RyanNerd
라덕'Story
RyanNerd
  • 분류 전체보기 (72) N
    • Study Note (37) N
      • Python (3)
      • R (1)
      • Airflow (7)
      • 통계 (22) N
      • 머신러닝 (4) N
    • 빅데이터분석기사 (1)
      • 필기 (1)
    • Programmers (28)
      • Python (13)
      • SQL (15)
    • Project (3)
      • Django (3)
    • Mac (2)

블로그 메뉴

  • NaverBlog
  • 홈

최근 글

전체 방문자
오늘
어제
hELLO · Designed By 정상우.
RyanNerd

라덕'Story

Study Note/머신러닝

"모든 변수가 다 중요할까?" 피처 중요도(Feature Importance)로 모델 다이어트하기

2025. 12. 20. 20:47

데이터 분석을 하다 보면 "변수(Feature)가 많으면 무조건 좋을까?"라는 고민에 빠집니다. 정답은 NO입니다. 불필요한 변수는 모델의 학습 속도를 늦추고, 오히려 성능을 떨어뜨리는 노이즈가 될 수 있습니다.

오늘은 머신러닝의 기본 함수(fit, predict)를 확실히 정리하고, 여러 모델의 피처 중요도(Feature Importance)를 종합해 알짜배기 변수만 골라내는 방법을 실습해 보겠습니다.

 

1. 머신러닝의 문법: Scikit-learn 핵심 함수 4대장

본격적인 분석 전에, 우리가 숨 쉬듯이 사용하는 4가지 함수의 정확한 의미와 사용 시점을 짚고 넘어갑시다. (이것만 알면 코드가 보입니다!)

① fit(X_train, y_train): "공부해!"

  • 의미: 모델에게 문제($X$)와 정답($y$)을 주고 학습시키는 과정입니다.
  • 언제: 최적의 파라미터를 찾을 때 사용합니다.
  • 비유: 학생에게 교과서와 문제집을 주고 "수능 공부 해"라고 시키는 것.

② predict(X_test): "시험 봐!"

  • 의미: 학습된 모델에게 정답 없이 문제($X$)만 주고 예측값을 내놓으라고 하는 것입니다.
  • 언제: 실전 데이터의 결과를 예측할 때 사용합니다.
  • 비유: 수능 시험장에서 답안지를 작성하는 것.

③ score(X, y): "채점해!"

  • 의미: 모델이 예측한 결과가 실제 정답과 얼마나 일치하는지 점수(정확도 등)를 매깁니다.
  • 언제: 모델의 성능을 빠르게 확인하고 싶을 때 사용합니다.
  • 비유: 빨간 펜으로 채점해서 "85점"이라고 알려주는 것.

④ cross_val_score(): "모의고사 여러 번 봐!"

  • 의미: 데이터를 여러 조각으로 나누어 학습과 평가를 반복(교차 검증)합니다.
  • 언제: "이 모델이 운 좋게 점수가 잘 나온 건 아닐까?" 검증하고 신뢰도를 높일 때 사용합니다.
  • 비유: 3월, 6월, 9월 모의고사를 통해 학생의 진짜 실력을 평균 내는 것.

2. 왜 '피처 중요도'를 봐야 할까?

트리 기반 모델(Random Forest, XGBoost 등)은 학습 과정에서 "어떤 변수가 데이터를 분류하는 데 가장 큰 기여를 했는지"를 계산할 수 있습니다. 이를 feature_importances_라고 합니다.

전략: "집단 지성 이용하기"

하나의 모델만 믿는 것보다, 여러 모델(Decision Tree, Random Forest, XGBoost, LightGBM 등)이 공통적으로 중요하다고 지목한 변수를 찾는 것이 훨씬 신뢰도가 높습니다.

 

3. [실습] 타이타닉 생존자 예측: 중요 변수 추출하기

Step 1. 데이터 준비 & 전처리 (내장 데이터 활용)

import seaborn as sns
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder

# 1. 타이타닉 데이터 불러오기 (인터넷만 연결되어 있으면 OK)
df = sns.load_dataset('titanic')

# 2. 간단한 전처리 (결측치 제거 & 숫자로 변환)
df = df[['survived', 'pclass', 'sex', 'age', 'fare', 'embarked']].dropna()

# 문자열(sex, embarked)을 숫자(0, 1, 2...)로 변환 (Label Encoding)
encoder = LabelEncoder()
df['sex'] = encoder.fit_transform(df['sex'])
df['embarked'] = encoder.fit_transform(df['embarked'])

# 문제(X)와 정답(y) 분리
X = df.drop('survived', axis=1) # 생존 여부 제외한 나머지
y = df['survived']              # 생존 여부 (정답)

# 학습용 vs 테스트용 분리
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

print("준비 완료! 데이터 샘플:")
print(X_train.head())

 

Step 2. 모델 학습 (fit) 및 중요도 추출

이번에는 가장 많이 쓰이는 Random Forest와 XGBoost 두 가지 모델을 써보겠습니다.

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
import matplotlib.pyplot as plt
import numpy as np
from functools import reduce  # 핵심 함수: 여러 개의 DF를 한 번에 병합

models = [
    RandomForestClassifier(n_estimators=100, random_state=42),
    GradientBoostingClassifier(n_estimators=100, random_state=42),
    XGBClassifier(n_estimators=100, eval_metric='logloss', random_state=42)
]

print("모델 학습 중...", end=" ")
for model in models:
    model.fit(X_train, y_train)
print("완료!")

# ---피처 중요도 추출 및 병합 ---
data_frames = []
for model in models:
    # 각 모델의 중요도 추출
    importance = pd.DataFrame({
        'Feature': X_train.columns, 
        model.__class__.__name__: model.feature_importances_
    })
    data_frames.append(importance)

# reduce를 사용하여 리스트에 있는 모든 데이터프레임을 'Feature' 기준으로 한 번에 병합
importances = reduce(lambda left, right: pd.merge(left, right, on='Feature'), data_frames)

# 수치형 컬럼(각 모델의 중요도)들의 평균(avg) 계산
importances['avg'] = importances.select_dtypes(include=[np.number]).mean(axis=1)

# 평균 중요도가 높은 순서대로 정렬
importances = importances.sort_values(by='avg', ascending=False)

print("\n=== 모델 통합 변수 중요도 순위 ===")
print(importances)

 

 

Step 3. 결과 시각화

# 막대 그래프로 그리기
plt.figure(figsize=(10, 6))
sns.barplot(x='Average', y='Feature', data=importance_df, palette='viridis')
plt.title('Feature Importance (RF & XGB Average)')
plt.xlabel('Importance Score')
plt.show()

 

 

위 코드를 실행하면 성별(sex), 요금(fare), 나이(age) 순으로 중요도가 높게 나옵니다.

  1. 성별(Sex)의 압도적 중요성:
    • "여성과 아이 먼저"라는 구조 원칙 때문에 성별은 생존을 가르는 가장 결정적인 변수입니다. 모델도 이를 정확히 파악했습니다.
  2. 요금(Fare)과 등급(Pclass):
    • 비싼 요금을 낸 승객(1등석)이 구조될 확률이 높았음을 모델이 반영하고 있습니다.
  3. 의료 데이터 적용:
    • 만약 이것이 '당뇨병 예측'이었다면?
    • feature_importances_를 통해 "혈당(Glucose)과 BMI가 가장 중요합니다"라는 결과를 얻었을 것이고, 이를 바탕으로 환자에게 "다른 건 몰라도 체중 관리는 꼭 하셔야 합니다"라고 근거 있는 조언을 할 수 있습니다.

'알짜배기' 변수로 재학습

상위 50개(혹은 상위 N%)의 변수만 남기고 나머지 불필요한 변수는 버립니다. 그 후 모델을 다시 학습시키면 어떤 일이 일어날까요?

  • 정확도: 유지되거나 오히려 소폭 상승할 수 있습니다. (노이즈 제거 효과)
  • 속도: 학습해야 할 데이터 양이 줄어들어 훨씬 빨라집니다.

의료 데이터 분석 Insight

이 방법론은 의료 데이터 분석에서 매우 유용합니다.

  1. 비용 절감: 피처 중요도 분석 결과, 비싼 MRI 검사보다 간단한 혈액 검사 수치가 더 중요하다고 나왔다면? $\rightarrow$ 환자의 비용 부담을 줄이는 근거가 됩니다.
  2. 설명 가능성: 의사 선생님께 "이 AI 모델은 환자의 나이와 BMI를 가장 중요하게 보고 당뇨병을 예측했습니다"라고 구체적인 근거를 제시할 수 있습니다.

결론: 무조건 데이터를 많이 넣는 게 능사가 아닙니다. feature_importances_를 통해 데이터의 '옥석'을 가려내는 것이 고수 분석가로 가는 지름길입니다!

'Study Note > 머신러닝' 카테고리의 다른 글

내 모델 믿어도 될까? 교차 검증(Cross Validation) 완벽 가이드  (0) 2025.12.20
머신러닝의 꽃, 앙상블과 부스팅 (XGBoost, LightGBM) 완전 정복  (1) 2025.12.19
[ML 기초] 통계가 머신러닝이 되는 순간: 나이브 베이즈와 ML 프로세스  (0) 2025.12.19
    'Study Note/머신러닝' 카테고리의 다른 글
    • 내 모델 믿어도 될까? 교차 검증(Cross Validation) 완벽 가이드
    • 머신러닝의 꽃, 앙상블과 부스팅 (XGBoost, LightGBM) 완전 정복
    • [ML 기초] 통계가 머신러닝이 되는 순간: 나이브 베이즈와 ML 프로세스
    RyanNerd
    RyanNerd
    라이언 덕후의 일상 스토리~

    티스토리툴바