Skip to main content

특성 선택 (Feature Selection)

특성 선택(Feature Selection)은 모델 성능에 기여하는 특성만 선별하고, 불필요한 특성을 제거하는 과정입니다. 차원의 저주를 방지하고 모델의 일반화 성능을 향상시킵니다.

학습 목표

  • Filter, Wrapper, Embedded 세 가지 접근법의 차이를 이해합니다.
  • scikit-learn의 특성 선택 도구를 사용할 수 있습니다.
  • RFE(Recursive Feature Elimination)를 적용할 수 있습니다.
  • 트리 기반 모델의 특성 중요도를 활용할 수 있습니다.

왜 중요한가

특성이 너무 많으면 과적합, 학습 시간 증가, 해석 어려움이 발생합니다. 반면 중요한 특성을 제거하면 모델 성능이 저하됩니다. 적절한 특성 선택은 성능과 효율의 균형을 맞추는 핵심 과정입니다.

핵심 개념

세 가지 접근법 비교

방법원리장점단점
Filter통계적 기준으로 독립 평가빠른 계산특성 간 상호작용 미반영
Wrapper모델 성능으로 부분집합 평가높은 정확도느린 계산
Embedded모델 학습 과정에서 선택효율적특정 모델에 종속

Filter 방법

from sklearn.feature_selection import SelectKBest, f_classif, mutual_info_classif
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)

# 방법 1: F-검정 기반 (분산 분석)
selector_f = SelectKBest(score_func=f_classif, k=2)
X_selected = selector_f.fit_transform(X, y)

# 각 특성의 점수 확인
scores = pd.DataFrame({
    "특성": load_iris().feature_names,
    "F-score": selector_f.scores_,
    "p-value": selector_f.pvalues_
}).sort_values("F-score", ascending=False)
print(scores)

# 방법 2: 상호 정보량 기반
selector_mi = SelectKBest(score_func=mutual_info_classif, k=2)
X_mi = selector_mi.fit_transform(X, y)
print(f"상호 정보량 점수: {selector_mi.scores_}")

Wrapper 방법: RFE

from sklearn.feature_selection import RFE, RFECV
from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier(n_estimators=100, random_state=42)

# RFE: 재귀적 특성 제거
rfe = RFE(estimator=model, n_features_to_select=2, step=1)
rfe.fit(X, y)

print(f"선택된 특성: {np.array(load_iris().feature_names)[rfe.support_]}")
print(f"특성 순위: {rfe.ranking_}")

# RFECV: 교차검증으로 최적 특성 수 자동 결정
rfecv = RFECV(estimator=model, step=1, cv=5, scoring="accuracy")
rfecv.fit(X, y)
print(f"최적 특성 수: {rfecv.n_features_}")

Embedded 방법: 모델 기반

from sklearn.feature_selection import SelectFromModel

# 트리 기반 특성 중요도
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X, y)

# 특성 중요도 시각화
importance = pd.DataFrame({
    "특성": load_iris().feature_names,
    "중요도": rf.feature_importances_
}).sort_values("중요도", ascending=False)
print(importance)

# 중요도 기반 자동 선택
selector = SelectFromModel(rf, threshold="mean")
X_important = selector.fit_transform(X, y)
print(f"선택된 특성 수: {X_important.shape[1]}")

# L1 정규화 (Lasso) 기반 선택
from sklearn.linear_model import LassoCV
lasso = LassoCV(cv=5, random_state=42)
lasso.fit(X, y)
print(f"Lasso 계수 (0이면 제거): {lasso.coef_}")

상관관계 기반 제거

# 높은 상관관계를 가진 특성 중 하나 제거 (다중공선성 방지)
def remove_correlated_features(df, threshold=0.9):
    """상관관계가 높은 특성 쌍에서 하나를 제거합니다."""
    corr_matrix = df.corr().abs()
    upper = corr_matrix.where(
        np.triu(np.ones(corr_matrix.shape), k=1).astype(bool)
    )
    to_drop = [col for col in upper.columns if any(upper[col] > threshold)]
    return to_drop

drop_cols = remove_correlated_features(pd.DataFrame(X))
print(f"제거 대상: {drop_cols}")

AI/ML에서의 활용

상황추천 방법관련 레퍼런스
빠른 스크리닝Filter (SelectKBest)모든 모델 적용 전
최적 부분집합 탐색Wrapper (RFECV)소규모 데이터셋
트리 모델 사용 시Embedded (feature_importances_)랜덤 포레스트
선형 모델 사용 시Embedded (Lasso 계수)Lasso
특성 선택은 원본 특성 중 일부를 선택하여 남깁니다 (해석 가능). 차원 축소(PCA 등)는 원본 특성을 변환하여 새로운 특성을 만듭니다 (해석이 어려울 수 있음).
네. 특성 선택도 전처리의 일부이므로, 학습 데이터로 선택 기준을 결정(fit)하고 테스트 데이터에는 동일한 기준을 적용(transform)해야 합니다.

체크리스트

  • Filter, Wrapper, Embedded 방법의 차이를 설명할 수 있다
  • SelectKBest로 통계 기반 특성 선택을 수행할 수 있다
  • RFE로 재귀적 특성 제거를 적용할 수 있다
  • 트리 기반 모델의 feature_importances_를 활용할 수 있다

다음 문서