▷ 오늘 학습 계획: 머신러닝 강의(15~17)
여러 개의 약한 분류기(성능은 떨어지지만 빠른)가 순차적으로 학습
앞에서 학습한 분류기가 예측이 틀린 데이터에 대해 다음 분류기가 가중치를 인가해서 학습을 이어가는 방식으로 예측 성능이 뛰어나서 앙상블 학습을 주도한다. (그래디언트 부스트, XGBoost(extra gradient boost), LightGBM(light gradient boost) 등
- Adaboost
DecisionTree기반의 알고리즘
순차적으로 가중치를 부여해서 최종 결과를 얻는다.- GBM(Gradient Boosting Machine): AdaBoost와 비슷하지만 가중치를 업데이트할 때 경사하강법(Gradient Descent)을 사용
- XGBoost(extra gradient boost): GBM에서 pc의 파워를 효율적으로 사용하기 위한 다양한 기법에 채택되어 빠른 속도와 효율
- LightGBM: XGBoost보다 빠른 속도
배깅과 부스팅의 차이
Bagging(Parallel): 한 번에 병렬적으로 결과를 얻음 → Bootstrap Agreegating
Boosting(Sequential): 순차적으로 진행
다양한 모델 한 번에 테스트
from sklearn.ensemble import AdaBoostClassifier, GradientBoostingClassifier, RandomForestClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.linear_model import LogisticRegression
models = [] models.append(('RandomForestClassifier', RandomForestClassifier())) models.append(('DecisionTreeClassifier', DecisionTreeClassifier())) models.append(('AdaBoostClassifier', AdaBoostClassifier())) models.append(('GradientBoostingClassifier', GradientBoostingClassifier())) models.append(('LogisticRegression', LogisticRegression()))
결과 저장
from sklearn.model_selection import KFold, cross_val_score results = [] names = [] for name, model in models: kfold = KFold(n_splits=5, random_state=13, shuffle=True) cv_results = cross_val_score(model, X_train, y_train, cv=kfold, scoring='accuracy') results.append(cv_results) names.append(name) print(name, cv_results.mean(), cv_results.std())
테스트 데이터로 평가
from sklearn.metrics import accuracy_score for name, model in models: model.fit(X_train, y_train) pred = model.predict(X_test) print(name, accuracy_score(y_test, pred))
k nearest neighbor: 새로운 데이터가 있을 때 기존 데이터의 그룹 중 어떤 그룹에 속하는지를 분류하는 문제(거리 계산: 유클리드 기하)
k: 몇 번째 가까운 데이터까지 볼 것인가를 결정하는 수치
k값에 따라 결과값이 바뀔 수 있고 단위에 따라 바뀔 수 있다.(표준화 필요)지도학습에 속한다.
실시간 예측을 위한 학습이 필요하지 않아서 속도가 빠르지만 고차원 데이터에는 적합하지 않다.from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier(n_neighbors=5) knn.fit(X_train, y_train) #절차상으로만 fit 과정이 있음(실제 학습 과정은 없다)
from sklearn.metrics import accuracy_score pred = knn.predict(X_test) print(accuracy_score(y_test, pred))
from sklearn.metrics import classification_report, confusion_matrix print(confusion_matrix(y_test, pred)) print(classification_report(y_test, pred))
Gradient Boosting Machine
from sklearn.ensemble import GradientBoostingClassifier from sklearn.metrics import accuracy_score import time import warnings warnings.filterwarnings('ignore')
start_time = time.time() gb_clf = GradientBoostingClassifier(random_state=13) gb_clf.fit(X_train, y_train) gb_pred = gb_clf.predict(X_test) print('ACC:', accuracy_score(y_test, gb_pred)) #ACC:0.9385816084153377 print('Fit time:', time.time()-start_time) #Fit time:1013.4244842529297
from sklearn.model_selection import GridSearchCV params = {'n_estimators':[100, 50], 'learning_rate':[0.05, 0.1]} start_time = time.time() grid = GridSearchCV(gb_clf, param_grid=params, cv=2, verbose=1, n_jobs=-1) grid.fit(X_train, y_train) print('Fit time:', time.time()-start_time) #Fit time:1709.350225687027
grid.best_score_ # 0.8990750816104461 grid.best_params_ # {'learning_rate': 0.05, 'n_estimators': 100} accuracy_score(y_test, grid.best_estimator_.predict(X_test)) # 0.9280624363759755
트리 기반의 앙상블 학습에서 가장 각광받는 알고리즘 중 하나
GBM 기반의 알고리즘으로 GBM의 느린 속도를 다양한 규제를 통해 해결(병렬 학습 가능)
반복 수행할 때마다 내부적으로 학습데이터와 검증데이터 교차검증을 수행
교차검증을 통해 최적화되면 반복을 중단한다(조기 중단 기능)
- 주요 파라미터
nthread: CPU의 실행 스레드 개수 조정(default: 전체 스레드 사용)
eta: GBM 학습률
num_boost_rounds: n_estimators와 같은 파라미터
max_depth
from xgboost import XGBClassifier from sklearn.preprocessing import LabelEncoder le = LabelEncoder() y_train = le.fit_transform(y_train)
import time start_time = time.time() xgb = XGBClassifier(n_estimators=400, learning_rate=0.1, max_depth=3) xgb.fit(X_train.values, y_train) print('Fit time: ', time.time() - start_time) # Fit time: 60.643099784851074
from sklearn.metrics import accuracy_score y_pred = xgb.predict(X_test.values) y_pred = le.inverse_transform(y_pred) accuracy_score(y_test, y_pred) #0.9494401085850017
조기 종료 조건, 검증데이터 지정 → 속도는 빨라지지만 성능은 비슷하다.
from xgboost import XGBClassifier evals = [(X_test.values, y_test)] start_time = time.time() xgb = XGBClassifier(n_estimators=400, learning_rate=0.1, max_depth=3) xgb.fit(X_train.values, y_train, early_stopping_rounds=10, eval_set=evals) print('Fit time: ', time.time() - start_time) accuracy_score(y_test, xgb.predict(X_test.values))
XGBoost와 함께 부스팅 계열에서 가장 각광받는 알고리즘
LGBM의 가장 큰 장점은 속도이지만 적은 수의 데이터에는 어울리지 않는다.(일반적으로 10,000건 이상의 데이터 필요)
GPU 버전도 존재한다.from lightgbm import LGBMClassifier evals = [(X_test.values, y_test)] start_time = time.time() lgbm = LGBMClassifier(n_estimators = 400) lgbm.fit(X_train.values, y_train, early_stopping_rounds=20, eval_set=evals)
print('Fit time: ', time.time()- start_time) # Fit time: 3.3771932125091553 accuracy_score(y_test, lgbm.predict(X_test.values)) # 0.9260264675941635
신용카드 사기 검출 분류 실습
'class' 컬럼이 사기 유무를 의미한다.(1이면 Fraud)
'class' 컬럼의 불균형이 심하다.(Fraud 비율이 전체 데이터의 0.172%)
일단 시도하기
- 분류기 성능 파악하기
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score def get_clf_eval(y_test, pred): acc = accuracy_score(y_test, pred) pre = precision_score(y_test, pred) re = recall_score(y_test, pred) f1 = f1_score(y_test, pred) auc = roc_auc_score(y_test, pred) return acc, pre, re, f1, auc
- 성능 출력 함수
from sklearn.metrics import confusion_matrix def print_clf_eval(y_test, pred): confusion = confusion_matrix(y_test, pred) acc, pre, re, f1, auc = get_clf_eval(y_test, pred) print('==> confusion matrix') print(confusion) print("=======================") print('Accuracy: {0:.4f}, Precision: {1:.4f}'.format(acc, pre)) print('Recall: {0:.4f}, F1: {1:.4f}, AUC:{2:.4f}'.format(re, f1, auc))
- 모델과 데이터를 주면 성능 출력
def get_result(model, X_train, y_train, X_test, y_test): model.fit(X_train, y_train) pred = model.predict(X_test) return get_clf_eval(y_test, pred)
- 모델의 성능을 정리해서 DataFrame으로 반환
def get_result_pd(models, model_names, X_train, y_train, X_test, y_test): col_names = ['accuracy', 'precision', 'recall', 'f1', 'roc_auc'] tmp = [] for model in models: tmp.append(get_result(model, X_train, y_train, X_test, y_test)) return pd.DataFrame(tmp, columns=col_names, index=model_names)
import time models = [lr_clf, dt_clf, rf_clf, lgbm_clf] model_names = ['LogisticReg', 'DecisionTree', 'RandomForest', 'LightGBM'] start_time = time.time() results=get_result_pd(models, model_names, X_train, y_train, X_test, y_test) print('Fit time: ', time.time() - start_time) results
데이터 정리하기
- Amount 컬럼에 StandardScaler 적용하기
- 모델별 ROC 커브 확인하기
from sklearn.metrics import roc_curve def draw_roc_curve(models, model_names, X_test, y_test): plt.figure(figsize=(10,10)) for model in range(len(models)): pred = models[model].predict_proba(X_test)[:, 1] fpr, tpr, thresholds = roc_curve(y_test, pred) plt.plot(fpr, tpr, label = model_names[model]) plt.plot([0,1], [0,1], 'k--', label='random guess') plt.title('ROC') plt.legend(); plt.grid(); plt.show()
- log scale(분포 변화)
outlier 정리
def get_outlier(df=None, column=None, weight=1.5): fraud = df[df['Class']==1][column] quantile_25 = np.percentile(fraud.values, 25) quantile_75 = np.percentile(fraud.values, 75) iqr = quantile_75 - quantile_25 iqr_weight = iqr * weight lowest_val = quantile_25 - iqr_weight highest_val = quantile_75 + iqr_weight outlier_index = fraud[(fraud < lowest_val) | (fraud>highest_val)].index return outlier_index
불균형한 두 클래스의 분포 맞추기
Undersampling, Oversampling: 데이터의 불균형이 극심할 때 불균형한 두 클래스의 분포를 강제로 맞춰보는 작업(train data에만 적용한다)
- Synthetic Minority Over-sampling Technique
적은 데이터 세트에 있는 개별 데이터를 k-최근접이웃 방법으로 찾아서 데이터의 분포 사이에 새로운 데이터를 만드는 방식(imbalanced-learn)from imblearn.over_sampling import SMOTE smote = SMOTE(random_state=13) X_train_over, y_train_over = smote.fit_resample(X_train, y_train)
▷ 내일 학습 계획: 머신러닝 강의(18~20)