반응형
머신러닝 개인 과제
선택과제
1) balance 음수값 보정
2) np.log() 대신 np.log1p 사용 이유
3) 더 나은 인코딩
4) 결측치 처리
3, 4를 한꺼번에 코드에서 다뤘다.
(1) 결측치 처리.
## 결측치 확인 df = pd.read_csv('./bank_marketing.csv') df.isnull().sum() ## job, eduaction, contact 까지는 대치할만한데 ## poutcome은 버리는 게 좋을 거 같다 ## 결측치 처리를 위한 모듈 불러오기 from sklearn.impute import SimpleImputer ## 대치는 최빈값으로 imputer = SimpleImputer(missing_values=np.nan, strategy='most_frequent') ## 결측치가 있는 컬럼을 명확하게 알기 때문에 df2 통으로 집어넣는다 df = pd.DataFrame(imputer.fit_transform(df), columns=df.columns, index=df.index) ## 결측치가 너무 많았던 poutcome은 일단 컬럼을 아예 없애본다 ## 없앴다가 점수가 더 낮게 나와서 다시 추가 ## 확인 df.isnull().sum()
(2) 더 나은 인코딩.
기존의 인코딩 함수를 두번째 블럭의 get_category_modified로 만들었다.
label 리스트에 있는 것들은 LabelEncoder를 돌리려다가 순서가 의미 없는 범주임을 깨닫고
철회했는데 리스트를 없애지 못했다.
## 인코딩 개선 ## get_dummies() output 중에서 컬럼 하나 제거하기 ## 다중 공선성을 일으키는 컬럼 색출하기 ## result 값 ## 범주형 컬럼, 상관계수 최대조합 리스트 ## 상관계수 최대조합 리스트 = [카테고리1, 카테고리2, 상관계수(절댓값)] ## 결과를 보면 ## marital, education, default, housing, loan ## 위 컬럼들에서 get_dummies를 할 때 ## output에서 컬럼을 하나씩 제거할 수 있다 df = pd.read_csv('./bank_marketing.csv') category_col = ['job','marital','education','default','housing','loan','contact','month', 'poutcome'] corrs = [['default', 'default', 0] for i in range(len(category_col))] for i, col in enumerate(category_col): df_dum = pd.get_dummies(df[col]) corr = df_dum.corr(method='pearson') for category in corr.columns: max_index = corr[category].abs().sort_values(ascending=False)[1:].index[0] max_corr_abs = corr[category].abs().sort_values(ascending=False)[1:][0].round(3) max_combis = [category, max_index, max_corr_abs] if max_combis[2] > corrs[i][2]: corrs[i] = max_combis else: continue for i, list in enumerate(corrs): print(category_col[i], list)
def get_category_modified(X_train:pd.DataFrame, X_test:pd.DataFrame): #범주형변수 # 'job','marital','education','default','housing','loan','contact','month','poutcome' # 모델 불러오기 from sklearn.preprocessing import LabelEncoder # modified modified = ['marital', 'education', 'default', 'housing', 'loan'] label = ['job', 'month'] #범주형 컬럼 더미화 하기 X_train_dummies_total = pd.DataFrame() X_test_dummies_total = pd.DataFrame() for col in category_col: X_train_temp = X_train[col] X_test_temp = X_test[col] X_train_dummies = pd.get_dummies(X_train_temp) X_test_dummies = pd.get_dummies(X_test_temp) if col in modified: X_train_dummies = X_train_dummies.iloc[:, 1:] X_test_dummies = X_test_dummies.iloc[:, 1:] X_train_dummies_total = pd.concat([X_train_dummies_total, X_train_dummies], axis = 1) X_test_dummies_total = pd.concat([X_test_dummies_total, X_test_dummies], axis = 1) # 더미화한 변수를 기존 데이터셋에 합치기 X_train = pd.concat([X_train, X_train_dummies_total], axis = 1) X_test = pd.concat([X_test, X_test_dummies_total], axis = 1) return X_train, X_test, X_train_dummies_total.columns.to_list()
5) 하이퍼 파라미터 최적화 하기.
최적화된 하이퍼 파라미터를 찾는 함수를 만들어
기존에 모델 성능을 채점하는 함수에서
함수를 통해 찾아낸 하이퍼 파라미터를 적용하는
get_score_modified 함수로 수정한다.
def grid_search(X_train, y_train, x_var_list): # 모듈 불러오기 from sklearn.linear_model import LogisticRegression from sklearn.model_selection import GridSearchCV # 일부 컬럼만 가져오기 X_train = X_train[x_var_list] # 모델 생성 logit = LogisticRegression() params = {'solver' : ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'], 'max_iter' : [100, 200, 300] } gs = GridSearchCV(logit, param_grid=params, cv=5) gs.fit(X_train, y_train) return gs.best_params_ best_params = grid_search(X_train, y_train, col_dummies + numeric_col) best_params
def get_score_modified(train:pd.DataFrame, test:pd.DataFrame, x_var_list:list, best_params:dict): """ train과 test 데이터와 X변수 컬럼을 받아 평가지표를 내는 함수입니다. Args: train (pd.DataFrame): train 데이터프레임 test (pd.DataFrame): test 데이터프레임 x_var_list (list): 모델링에 사용할 변수 리스트 """ #외부 전달인자를 내부변수에 할당 X_train = train X_test = test #일부 컬럼만 가져오기 X_train = X_train[x_var_list] X_test = X_test[x_var_list] '''문제 시작''' #모듈불러오기 from sklearn.linear_model import LogisticRegression from sklearn.metrics import f1_score, accuracy_score #모델가져오기 & 학습하기 logit = LogisticRegression(solver=best_params['solver'], max_iter=best_params['max_iter']) logit.fit(X_train, y_train) # 학습하여 결과 저장 y_pred_train = logit.predict(X_train) y_pred_test = logit.predict(X_test) '''문제 끝''' #평가표 생성 result = pd.DataFrame({'acc' : [accuracy_score(y_train, y_pred_train), accuracy_score(y_test, y_pred_test)], 'f1_score' : [f1_score(y_train, y_pred_train), f1_score(y_test, y_pred_test)]}, index = ['train','test']) display(result.round(2))
1. 결측치 처리 & 인코딩 개선.
2. 하이퍼 파라미터 최적화.
1, 2번 모두 원래 데이터와
오버샘플링한 데이터에서
모두 모델을 돌려봤고,
과제에 원래 제시되어 있던
모델과 성능도 비교해보았다.
결론은
원형 데이터 = 성능 소폭 상승.
오버샘플링 데이터 = 성능 소폭 하락.
원형 데이터는 애초에
데이터 불균형으로 인해
성능이 안 나왔던 것을 생각했을 때,
소폭 상승은 거의 의미가 없다.
오버샘플링 데이터에서의 하락은
1. 그냥 진짜 하락
2. 과적합 소폭 해소
라고 생각할 수 있겠는데
아마 1이겠지..
팀 프로젝트가 임박했다.
주제 몇개를 제시하고
그 중에 선택하는 방식을 차용하신다고 하는데
주제에 매몰되는 시간이 짧아지는 만큼
분석의 질이 높아질 수 있기 때문에
좋은 방향인 듯 하다.
반응형
'TIL' 카테고리의 다른 글
내배캠 TIL 36일차 (1) | 2024.02.07 |
---|---|
내배캠 TIL 35일차 (0) | 2024.02.06 |
내배캠 TIL 33일차 (0) | 2024.02.02 |
내배캠 TIL 32일차 (0) | 2024.02.01 |
내배캠 TIL 31일차 (0) | 2024.01.31 |