Feature Engineering (특성 추출, 선택, 변환)

topics 100-데이터분석 & AI 101 머신러닝 103 데이터 분석,처리
types 실습

딥러닝은 모델이 알아서 특성을 선택함
Therefore 딥러닝은 추출까지만 함

특성 추출

  • 추출 전 노이즈나 중복을 제거해야함
# <span id="xy-분할"></span>x,y 분할
X = df6.drop(target, axis=1) # axis 기본row 삭제
y = df6[target]

특성 선택

  • 중요도에 따라 데이터를 선택함
  • feature_importances_ 가 scikit-learn의 트리기반 모델에서 제공됨
    • 0-1 사이의 수로 정규화 되서 리턴
    • array형식으로 리턴 // [0.2,0.3,0.5] 이런식
방법 특징/설명 장점 단점
트리 기반 트리 분할 기준 불순도 감소 등으로 평가 빠르고 직관적 상관관계 있는 특성에 약함
Permutation
(순열 중요도)
특성 값을 섞어서 성능 저하 측정 모델 독립적, 직관적 계산량 많을 수 있음
SHAP Value 게임이론 기반, 개별 특성 기여도 정량화 일관성, 해석력 우수 계산 복잡, 느릴 수 있음
Drop-Column 특성 제거 후 성능 비교 명확한 영향력 평가 모든 특성마다 재학습 필요
통계적 방법 회귀계수, p-value 등 해석 쉬움 비선형 모델엔 부적합

트리기반 중요도 선택예시

from sklearn.ensemble import RandomForestClassifier
  
#데이터 분할 진행(train:val = 8:2 혹은 7:3 권장)
target = "is_dynamic"

dynamic_x_train = dynamic_train.drop(target, axis = 1)
dynamic_y_train = dynamic_train[target]
dynamic_x_test = dynamic_test.drop(target, axis = 1)
dynamic_y_test = dynamic_test[target]

#RandomForestClassifier로 모델링 진행
model_dynamic = RandomForestClassifier()
model_dynamic.fit(dynamic_x_train, dynamic_y_train)

# <span id="평가"></span>평가
dynamic_y_pred = model_dynamic.predict(dynamic_x_test)
print(classification_report(dynamic_y_test, dynamic_y_pred))

# <span id="is_dynamic-을-구분하는데-중요한-변수-상위-5를-분석"></span>is_dynamic 을 구분하는데 중요한 변수 상위 5를 분석!
dynamic_importance = model_dynamic.feature_importances_
names = dynamic_x_train.columns
dynamic_importance_result = plot_feature_importance(dynamic_importance, names, result_only = False, topn = 30)

# <span id="변수의-특성-중요도-계산하고-시각화하는-함수"></span>변수의 특성 중요도 계산하고 시각화하는 함수
def plot_feature_importance(importance, names, result_only = False, topn = 'all'):
    feature_importance = np.array(importance)
    feature_name = np.array(names)

    data={'feature_name':feature_name,'feature_importance':feature_importance}
    fi_temp = pd.DataFrame(data)

    #변수의 특성 중요도 순으로 정렬하기
    fi_temp.sort_values(by=['feature_importance'], ascending=False,inplace=True)
    fi_temp.reset_index(drop=True, inplace = True)

    if topn == 'all' :
        fi_df = fi_temp.copy()
    else :
        fi_df = fi_temp.iloc[:topn]

    #변수의 특성 중요도 그래프로 그리기
    if result_only == False :
        plt.figure(figsize=(10,20))
        sns.barplot(x='feature_importance', y='feature_name', data = fi_df)

        plt.xlabel('importance')
        plt.ylabel('feature name')
        plt.grid()

    return fi_df

관련 문서