기여도 분석 툴 제작

3 minute read

지금 업무에 필요한 개발들이 많지만 그 중에서 지금 제일 유용할 것으로 보이는 것은

평가에 대한 기여도 분석이라고 생각해서 아래와 같은 코드를 작성 해보았다.

핸즈온 머신러닝에 있는 분석을 실제 평가 결과에 적용해보면 결과가 실제의 결과와 살짝 동떨어져있는 경우가 있다.

대량의 데이터가 균일하게 되어있는 것이 아닌 정말 몇조건의 Recipe만 해당 평가에 필요하고 나머지들은 오히려 노이즈로 작용하여 모델이 부적합하게 만들어져서

결과를 해석하기 힘들게 만든다.

생각해보면 데이터가 많고 균일하다면 그냥 해도 될거같기도하고…

미니탭에서 주성분분석을 해보면 평가항목에 대한 plot은 당연히 적당한데 Ref 조건이 다른 평가항목들의 분산이 섞여 들어서 왜곡이 되있다.

그래서 일단 data의 filtering이 필요할 것으로 보인다.

또한 이상하게 p-value가 0이 절대 아닌데 0으로 되어버리는 것도 있다.

이러저러한 이유로 개별 기여도 분석 툴 제작이 시급하여 지금 중국 기숙사 단칸방에서 이렇게 만들고 있다.

개발을 하다보면 검색을 통해 필요한 라이브러리의 기능들을 확인하곤 하는데 이것들이 반복적인 경우가 많아 이렇게 포스트에 기록하여

내머리속에 기억나는 것들은 여기서 간단하게 찾아 쓰려고 한다.

그럼 지금 부터 시작..

──────────────────────────────────────────────────────────────────────────────────────────────────────────

제일 처음 만들 것은 각 recipe 별로 df를 만들어 주는 일. (왜냐면 잡스런 다른 평가들이 노이즈를 만들기 때문에 딱 해당 평가에 맞는 결과들만 갖고 오기 위해서..)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# 평가 Recipe 별로 묶어놓은 df을 만들어주는 함수.
# dict 형태에 key:평가 layer, value:df 로 값 반환.
def make_evaluate_df(df, ref_row):
    '''
    Input
    1. df : df_recipe, 조건만 있는 DataFrame Input
    2. ref_row : Reference 조건이 있는 row. 여러개의 Ref가 있을 경우를 위함.
    * 추후 추가필요사항
    -단순 Cavity Split 시 보상을 위해 일부 layer 두꼐 변경하는 경우가 있는데
    이 부분을 split이 아닌 그냥 포함 시킬 수 있는 예외 항을 기록 해줘야 할 듯.
    '''
    df_cols = df.columns
    df_dict_list = {}
    for col in df_cols:
        df_X_temp = df_X.drop(col, axis=1)
        df_X_temp_boolean = df_X_temp.eq(df_X_temp.iloc[ref_row,:],axis=1)
        df_same_col = df_X.loc[df_X_temp_boolean.all(axis=1)==True]
        df_dict_list[col] = df_same_col

    return df_dict_list

위와 같이 간단하게 만들었다. 각 df의 columns을 만들고 결과를 저장할 빈 dict를 만들었다.

중요한 것은 그 다음인데 아래와 코드를 잘 살펴보자.

df_X_temp_boolean = df_X_temp.eq(df_X_temp.iloc[ref_row,:],axis=1)

pd.DataFrame.eq()라고 하는 함수는 같으면 True 다르면 False를 반환하는데 비교대상은 한개의 값, 혹은 Series로 넣을 수 있어 현재 내가 하고자 하는 Ref와 비교하여 각 Column 별로 동일한지 여부를 확인 할 수 있는 함수이다. 참고 : https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.eq.html?highlight=dataframe%20eq#pandas.DataFrame.eq

이 항목은 모든 column이 ref와 동일하여 True를 반환한 row만 추리기 위한 코드.

df_same_col = df_X.loc[df_X_temp_boolean.all(axis=1)==True]

df.all()을 사용하면 전부 True일떄 True를 반환해준다. 그것을 df.loc을 이용해 index를 가져오고 그것을 df_X에서 Filtering 해준다. 단 index가 동일해야 이것의 사용이 가능할 것이다.

patsy의 dmatrices를 이용한 효과적인 DataFrame 나누기

from patsy import dmatrices
a = ''
for col in df_cols:
    a = a + col + ' + ' 
formula_cols = 'Eff ~ ' + a[:-3]
formula_cols

이렇게 하면 Eff부분을 y로 그리고 + 이후 부분을 1을 추가한 X로 만들어줌. y, X 를 표현하는 formula는 patsy 문서를 참고하자. https://patsy.readthedocs.io/en/latest/formulas.html#formulas https://patsy.readthedocs.io/en/v0.1.0/API-reference.html

mod = sm.OLS(y, X)
result = mod.fit()
print(result.summary())
                        OLS Regression Results                             ============================================================================== Dep. Variable:                    Eff   R-squared:                       0.956 Model:                            OLS   Adj. R-squared:                  0.945 Method:                 Least Squares   F-statistic:                     87.70 Date:                Wed, 13 Nov 2019   Prob (F-statistic):           0.000724 Time:                        16:54:42   Log-Likelihood:                 1.0406 No. Observations:                   6   AIC:                             1.919 Df Residuals:                       4   BIC:                             1.502 Df Model:                           1                                          Covariance Type:            nonrobust                                          ==============================================================================
             coef    std err          t      P>|t|      [0.025      0.975] ------------------------------------------------------------------------------ Intercept    3.01e-06   2.87e-06      1.051      0.353   -4.95e-06     1.1e-05 HIL_T          0.0002      0.000      1.051      0.353      -0.000       0.001 HIL_R       1.505e-06   1.43e-06      1.051      0.353   -2.47e-06    5.48e-06 HTL_T          0.0330      0.004      9.365      0.001       0.023       0.043 HTL_R       2.709e-06   2.58e-06      1.051      0.353   -4.45e-06    9.87e-06 EML_T          0.0006      0.001      1.051      0.353      -0.001       0.002 EML_R       1.505e-06   1.43e-06      1.051      0.353   -2.47e-06    5.48e-06 EML_D        6.02e-07   5.73e-07      1.051      0.353   -9.89e-07    2.19e-06 ETL_T          0.0008      0.001      1.051      0.353      -0.001       0.003 ETL_R       1.505e-06   1.43e-06      1.051      0.353   -2.47e-06    5.48e-06 Cathode_T      0.0030      0.003      1.051      0.353      -0.005       0.011 ============================================================================== Omnibus:                          nan   Durbin-Watson:                   2.899 Prob(Omnibus):                    nan   Jarque-Bera (JB):                0.811 Skew:                           0.776   Prob(JB):                        0.666 Kurtosis:                       2.084   Cond. No.                     5.58e+48 ==============================================================================

Warnings: [1] Standard Errors assume that the covariance matrix of the errors is correctly specified. [2] The input rank is higher than the number of observations. [3] The smallest eigenvalue is 3.7e-91. This might indicate that there are strong multicollinearity problems or that the design matrix is singular. C:\Anaconda3\lib\site-packages\statsmodels\stats\stattools.py:72: ValueWarning: omni_normtest is not valid with less than 8 observations; 6 samples were given. “samples were given.” % int(n), ValueWarning)

summary를 하면 위와 같이 나옴. 개별 항목을 확인하기 위해선 아래와 dir()함수로 확인 ```python dir(

Categories:

Updated: