Machine Learning_7

YJ·2023년 5월 22일
0

▷ 오늘 학습 계획: 머신러닝 강의(15~17)

📖 Chapter 07

1) Boosting Algorithm

여러 개의 약한 분류기(성능은 떨어지지만 빠른)가 순차적으로 학습
앞에서 학습한 분류기가 예측이 틀린 데이터에 대해 다음 분류기가 가중치를 인가해서 학습을 이어가는 방식으로 예측 성능이 뛰어나서 앙상블 학습을 주도한다. (그래디언트 부스트, 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))

2) kNN

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))

3-1) GBM

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

3-2) XGBoost

트리 기반의 앙상블 학습에서 가장 각광받는 알고리즘 중 하나
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))

3-3) LightGBM

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

4) credit card fraud detection

신용카드 사기 검출 분류 실습
'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)

[이 글은 제로베이스 데이터 취업 스쿨의 강의 자료 일부를 발췌하여 작성되었습니다.]

0개의 댓글