Python/[코칭스터디 10기] Beyond AI Basic

[쇼핑데이터를 활용한 머신러닝] 9. 피처 엔지니어링 (1)

김초송 2023. 5. 10. 18:11

https://www.boostcourse.org/ai224/joinLectures/361819?isDesc=false 

 

쇼핑데이터를 활용한 머신러닝

부스트코스 무료 강의

www.boostcourse.org

1. 피처 엔지니어링

  • 원본 데이터로부터 도메인 지식 등을 바탕으로 문제를 해결하는데 도움이 되는 Feature 를 생성 / 변환하고 이를 머신러닝 모델에 적합한 형식으로 변환하는 작업
  • 딥러닝이 아닌 머신러닝에서 모델의 성능을 높이는 가장 핵심적인 단계
  • 양질의 데이터라면 성능의 80 - 90% 는 피처 엔지니어링에 의해 결정됨
    나머지는 하이퍼 파라미터 튜닝 등
  • 딥러닝 : end-to-end learning, 딥러닝 모델의 구조를 통해 데이터의 feature 를 모델이 알아서 찾아냄
  • 머신러닝 : 사람이 직접 데이터에 대해 이해해서 feature 를 만들어 줘야함

1) Pandas Group By Aggregation 을 이용한 Feature Engineering

  • 구매데이터를 바탕으로 고객의 구매액이 300 이상 여부 예측?
    -> 원본 데이터에서 주어진 Feature 에 고객 ID 기반으로 Aggregation 함수 적용
    -> 새로운 Feature 생성
agg_func = ['mean','max','min','sum','count','std','skew']
  • std: 표준편차(standard deviation), 클수록 데이터와 떨어진 정도가 큼
  • skew: 데이터의 비대칭도, 데이터가 어느쪽으로 쏠려있는지 나타냄
    positive - 왼쪽, negative - 오른쪽

- total-sum Feature

  • 과거 고객 구매액의 총 합
  • 예측을 위해 가장 중요한 feature
  • 머신러닝 모델은 데이터에서 타겟을 구분할 수 있는 패턴을 인식하는 것
    -> 어떤 피처가 타겟 레이블별로 분포가 다르면 모델에서 패턴을 쉽게 인식
    -> 분포 차이가 명확할수록 좋은 피처

좋은 피처, 나쁜 피처

- quantity-sum Feature

  • 과거 고객이 구매한 상품 개수의 합
  • 합이 클수록 타겟 레이블이 1이 될 확률이 높음
  • 레이블이 1이면 구매액이 높을 확률이 높음

 

2) Cross Validation 을 이용한 Out of Fold 예측

  • training 시 cross validation 을 적용해서 out of fold validation 성능 측정 및 테스트 데이터 예측을 통해 성능 향상

- Out of Fold 예측

  • Fold 마다 훈련한 모델로 테스트 데이터 예측
    -> Fold 수 만큼 예측 결과
    -> average ensemble 해서 최종 테스트 예측값으로 사용하는 방법
  • 캐글에서 대부분 사용하는 예측 기법

cross validation out of fold

folds = 10
model_params = ... # hyper parameter
x_train = ...
x_test = ...
y = ...

# Out Of Fold Validation 예측 데이터를 저장할 변수
y_oof = np.zeros(x_train.shape[0])
# 테스트 데이터 예측값을 저장할 변수
y_preds = np.zeros(x_test.shape[0])

# Stratified K Fold 선언
skf = StratifiedKFold(n_splits=folds, shuffle=True, random_state=42)

# stratified k fold split 함수로 train index, validation index 를 가져옴 
for fold, (tr_idx, val_idx) in enumerate(skf.split(x_train, y)):
    # train index, validation index로 train 데이터를 나눔
    x_tr, x_val = x_train.loc[tr_idx], x_train.loc[val_idx]
    y_tr, y_val = y[tr_idx], y[val_idx]
    # LightGBM 데이터셋 선언
    dtrain = lgb.Dataset(x_tr, label=y_tr)
    dvalid = lgb.Dataset(x_val, label=y_val)
    
    # LightGBM 모델 훈련
    clf = lgb.train(
        model_params,
        dtrain,
        valid_sets=[dtrain, dvalid] # Validation 성능을 측정할 수 있도록 설정
    )

    # Validation 데이터 예측
    y_oof[val_idx] = clf.predict(x_val)

    # train 된 모델로 test data 예측
    y_preds += clf.predict(x_test) / folds


# out of fold validation 성능 측정
print(f"OOF AUC = {roc_auc_score(y, y_oof)}")

 

3) LightGBM Early Stopping 적용

- Early Stopping

  • iteration 을 통해 반복학습이 가능한 머신러닝 모델에서 validation 성능 측정을 통해 성능이 가장 좋은 하이퍼 파라미터에서 학습을 조기종료하는 regularization 방법
  • ex) boosting 트리모델 트리 갯수, 딥러닝 epoch 수

- LightGBM Early Stopping

  • n_estimators : 트리 개수 하이퍼 파라미터
  • validation 데이터가 있으면 n_estimators 는 충분히 크게 설정,
    early_stopping_rounds 를 적절한 값으로 설정
  • 트리를 추가할 때마다 validation 성능 측정
    -> 성능이 early_stopping_rounds 값 이상 연속으로 성능이 좋아지지 않으면
    -> 트리 추가 stop, 가장 성능이 좋은 트리 개수를 최종 트리 개수로 사용
folds = 10
model_params = {'n_estimators':10000, ...} # hyper parameter : 10000 개로 충분히 크게 잡음
x_train = ... # train data
x_test = ... # test data
y = ... # train label

# Out Of Fold Validation 예측 데이터를 저장할 변수
y_oof = np.zeros(x_train.shape[0])
# 테스트 데이터 예측값을 저장할 변수
y_preds = np.zeros(x_test.shape[0])

# Stratified K Fold 선언
skf = StratifiedKFold(n_splits=folds, shuffle=True, random_state=42)

# stratified k fold split 함수로 train index, validation index 를 가져옴 
for fold, (tr_idx, val_idx) in enumerate(skf.split(x_train, y)):
    # train index, validation index로 train 데이터를 나눔
    x_tr, x_val = x_train.loc[tr_idx], x_train.loc[val_idx]
    y_tr, y_val = y[tr_idx], y[val_idx]
    # LightGBM 데이터셋 선언
    dtrain = lgb.Dataset(x_tr, label=y_tr)
    dvalid = lgb.Dataset(x_val, label=y_val)
    
    # LightGBM 모델 훈련 + early stopping 추가
    clf = lgb.train(
        model_params,
        dtrain,
        valid_sets=[dtrain, dvalid], # Validation 성능을 측정할 수 있도록 설정
        early_stopping_rounds=100
    )

    # Validation 데이터 예측
    y_oof[val_idx] = clf.predict(x_val)

    # train 된 모델로 test data 예측
    y_preds += clf.predict(x_test) / folds


# out of fold validation 성능 측정
print(f"OOF AUC = {roc_auc_score(y, y_oof)}")