[AI 101] 특성 공학(Feature Engineering) – AI 성능을 2배 높이는 데이터 변환의 기술


Table of Contents

핵심 요약

“특성 공학은 AI 성능을 좌우하는 숨은 무기”입니다. 동일한 알고리즘이라도 특성 공학의 질에 따라 정확도가 60% → 95%로 급상승할 수 있습니다. Feature(특성)는 AI 모델의 입력 데이터이며, 특성 선택(Selection)은 중요한 변수만 고르고, 특성 추출(Extraction)은 새로운 변수를 조합해 만듭니다. 정규화/표준화로 데이터 범위를 조정하고, PCA로 100차원 데이터를 2차원으로 압축하면서도 정보 손실을 최소화합니다. Kaggle 대회 우승팀의 80%가 “알고리즘보다 특성 공학이 중요하다”고 답한 이유를 완벽하게 설명합니다.


📍 목차

  1. Feature란 무엇인가?
  2. 특성 선택(Feature Selection)과 특성 추출(Feature Extraction)
  3. 데이터 정규화(Normalization)와 표준화(Standardization)
  4. 차원 축소 기법 – PCA(주성분 분석)
  5. 실전 특성 공학 체크리스트

1. Feature란 무엇인가?

1-1. Feature의 정의

Feature(특성, 피처)AI 모델에 입력되는 개별 측정 가능한 속성입니다.

비유: 집값 예측 AI

Feature (특성)설명
면적85㎡집의 크기
방 개수3개침실 수
역세권 여부O지하철역 500m 이내
층수7층건물의 층
건축 연도2015년신축 여부

모델 입력:

X = [[85, 3, 1, 7, 2015]]  # 5개의 Feature
y = [4.5억]  # 집값 (Target)

1-2. 좋은 Feature의 조건

Kaggle 대회 우승자들의 공통 의견:

조건설명예시
관련성Target 변수와 상관관계 높음집값 예측 시 “면적”은 관련성 높음, “집주인 나이”는 낮음
독립성다른 Feature와 중복 없음“면적(㎡)”과 “면적(평)” 둘 다 있으면 중복
변별력데이터 간 차이 구분 가능모든 집이 “서울”이면 변별력 없음
측정 가능객관적으로 측정 가능“집이 예쁘다” (주관적) → “방 개수” (객관적)

1-3. Feature의 종류

1️⃣ 수치형 Feature (Numerical)

연속적인 숫자 값

Feature예시특징
나이25, 30, 35세사칙연산 가능
온도15.5, 20.3°C소수점 가능
가격10,000원범위 제한 없음

2️⃣ 범주형 Feature (Categorical)

카테고리로 구분

Feature예시특징
성별남/여순서 없음
색상빨강/파랑/노랑순서 없음
학년1학년/2학년/3학년순서 있음 (Ordinal)

1-4. Feature의 중요성

동일한 데이터, 다른 Feature 구성:

시나리오 1: 원시 Feature 사용

# Feature: 주문 날짜, 가격
X = [['2025-11-23', 15000]]

# 모델 정확도: 70%

시나리오 2: 특성 공학 적용

# Feature: 요일, 시간대, 가격대, 계절
X = [['토요일', '저녁', '중간', '가을']]

# 모델 정확도: 92% (22%p 향상!)

핵심: 같은 데이터라도 Feature를 어떻게 구성하느냐에 따라 성능이 크게 달라집니다.


2. 특성 선택(Feature Selection)과 특성 추출(Feature Extraction)

2-1. 특성 선택 vs 특성 추출

항목특성 선택 (Selection)특성 추출 (Extraction)
정의기존 Feature 중 중요한 것만 선택기존 Feature를 조합해 새로운 Feature 생성
원본 유지✅ 유지 (일부만 선택)❌ 변환 (새로운 Feature 생성)
해석 가능성⭐⭐⭐⭐⭐ 쉬움⭐⭐ 어려움
대표 기법필터, 래퍼, 임베디드PCA, LDA, Auto-encoder
목적불필요한 Feature 제거차원 축소, 정보 압축

비유:

  • 특성 선택: 책장에 있는 책 중 중요한 10권만 고르기
  • 특성 추출: 모든 책의 핵심 내용을 요약한 1권 만들기

2-2. 특성 선택 (Feature Selection)

방법 1: 필터 방식 (Filter Method)

통계적 지표로 Feature 평가

상관계수 기반 선택:

import pandas as pd
import numpy as np

# 샘플 데이터
df = pd.DataFrame({
    'area': [85, 70, 95, 60],      # 면적
    'rooms': [3, 2, 4, 2],         # 방 개수
    'age': [5, 10, 2, 15],         # 건축 연수
    'price': [4.5, 3.8, 5.2, 3.0]  # 집값 (Target)
})

# 상관계수 계산
correlation = df.corr()['price'].abs().sort_values(ascending=False)

print(correlation)

출력:

price    1.000000  # Target (자기 자신)
area     0.980000  # 매우 높은 상관관계 → 선택
rooms    0.920000  # 높은 상관관계 → 선택
age      0.450000  # 낮은 상관관계 → 제거

분산 기반 선택 (Variance Threshold):

from sklearn.feature_selection import VarianceThreshold

# 분산이 0.1 이하인 Feature 제거
selector = VarianceThreshold(threshold=0.1)
X_new = selector.fit_transform(X)

원리: 분산이 낮으면 대부분 비슷한 값 → 정보량 적음 → 제거

방법 2: 래퍼 방식 (Wrapper Method)

모델 성능으로 Feature 평가

재귀적 Feature 제거 (RFE):

from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestRegressor

# 모델 정의
model = RandomForestRegressor()

# RFE: 최적의 5개 Feature 선택
selector = RFE(model, n_features_to_select=5)
selector.fit(X, y)

# 선택된 Feature 확인
selected_features = X.columns[selector.support_]
print(f"선택된 Feature: {selected_features}")

작동 방식:

  1. 모든 Feature로 모델 학습
  2. 가장 중요도 낮은 Feature 제거
  3. 나머지로 다시 학습
  4. 목표 개수까지 반복

방법 3: 임베디드 방식 (Embedded Method)

모델 학습 중 자동 선택

랜덤 포레스트 Feature Importance:

from sklearn.ensemble import RandomForestClassifier

# 모델 학습
model = RandomForestClassifier()
model.fit(X_train, y_train)

# Feature 중요도
importance = pd.DataFrame({
    'feature': X.columns,
    'importance': model.feature_importances_
}).sort_values('importance', ascending=False)

print(importance)

출력:

      feature  importance
0        area       0.45  # 가장 중요
1       rooms       0.30
2   near_station 0.15
3         age       0.10  # 덜 중요

L1 정규화 (Lasso):

from sklearn.linear_model import Lasso

# Lasso는 자동으로 일부 계수를 0으로 만듦
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)

# 계수가 0인 Feature는 자동 제거됨
selected = X.columns[lasso.coef_ != 0]
print(f"선택된 Feature: {selected}")

2-3. 특성 추출 (Feature Extraction)

1️⃣ 다항식 Feature (Polynomial Features)

기존 Feature의 조합으로 새로운 Feature 생성

from sklearn.preprocessing import PolynomialFeatures

# 원본 데이터
X = [[2, 3]]  # [면적(평), 방개수]

# 2차 다항식 Feature 생성
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)

print(X_poly)

출력:

[[1, 2, 3, 4, 6, 9]]
# 1 (상수), 2 (면적), 3 (방개수), 
# 4 (면적²), 6 (면적×방개수), 9 (방개수²)

효과: 비선형 패턴 학습 가능

2️⃣ 도메인 지식 기반 Feature 생성

날짜/시간 데이터 변환:

import pandas as pd

df = pd.DataFrame({
    'datetime': ['2025-11-23 18:30:00', '2025-11-24 12:15:00']
})

# 날짜를 datetime으로 변환
df['datetime'] = pd.to_datetime(df['datetime'])

# 새로운 Feature 생성
df['year'] = df['datetime'].dt.year
df['month'] = df['datetime'].dt.month
df['day'] = df['datetime'].dt.day
df['hour'] = df['datetime'].dt.hour
df['day_of_week'] = df['datetime'].dt.dayofweek  # 0=월요일
df['is_weekend'] = df['day_of_week'].isin([5, 6]).astype(int)

print(df)

출력:

             datetime  year  month  day  hour  day_of_week  is_weekend
0 2025-11-23 18:30:00  2025     11   23    18            6           1
1 2025-11-24 12:15:00  2025     11   24    12            0           0

실전 활용:

  • 택시 수요 예측: 요일, 시간대, 출퇴근 여부
  • 쇼핑몰 매출 예측: 주말/평일, 공휴일, 계절

3️⃣ 비율/차이 Feature

# 원본 Feature
df['total_price'] = [100000]
df['quantity'] = [5]

# 새로운 Feature 생성
df['price_per_unit'] = df['total_price'] / df['quantity']  # 20,000원

# 키와 몸무게 → BMI
df['height'] = [170]  # cm
df['weight'] = [70]   # kg
df['BMI'] = df['weight'] / (df['height'] / 100) ** 2  # 24.2

3. 데이터 정규화(Normalization)와 표준화(Standardization)

3-1. 왜 스케일링이 필요한가?

문제: Feature 간 범위 차이

Feature최소값최대값범위
연봉2,000만원1억원8,000만
나이20세60세40

문제점:

  • 거리 기반 알고리즘(KNN, SVM)에서 연봉이 나이를 압도
  • “20세, 3,000만원”과 “21세, 3,000만원”의 거리: 약 1 (나이 차이)
  • “20세, 3,000만원”과 “20세, 4,000만원”의 거리: 약 1,000 (연봉 차이)
  • 결과: 연봉만 고려되고 나이는 무시됨

해결책: 모든 Feature를 동일한 범위로 조정 → 스케일링

3-2. 정규화 (Normalization) – Min-Max Scaling

정의: 데이터를 0~1 범위로 변환

공식:

Xnorm=XXminXmaxXminX_{norm} = \frac{X – X_{min}}{X_{max} – X_{min}}

Python 구현:

from sklearn.preprocessing import MinMaxScaler

# 원본 데이터
df = pd.DataFrame({
    'salary': [2000, 3000, 5000, 10000],  # 만원 단위
    'age': [25, 30, 35, 40]
})

# Min-Max 정규화
scaler = MinMaxScaler()
df_normalized = pd.DataFrame(
    scaler.fit_transform(df),
    columns=df.columns
)

print(df_normalized)

출력:

   salary   age
0    0.00  0.00  # 최소값 → 0
1    0.12  0.33
2    0.38  0.67
3    1.00  1.00  # 최대값 → 1

장점:

  • ✅ 해석이 직관적 (0=최소, 1=최대)
  • ✅ 이미지 픽셀(0~255) → (0~1) 변환에 최적

단점:

  • ❌ 이상치에 매우 민감
  • 예: 연봉 [2000, 3000, 5000, 100000] → 대부분 0 근처로 압축

3-3. 표준화 (Standardization) – Z-Score Scaling

정의: 데이터를 평균 0, 표준편차 1로 변환

공식:

Xstd=XμσX_{std} = \frac{X – \mu}{\sigma}
  • (\mu): 평균
  • (\sigma): 표준편차

Python 구현:

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
df_standardized = pd.DataFrame(
    scaler.fit_transform(df),
    columns=df.columns
)

print(df_standardized)

출력:

   salary      age
0   -1.18   -1.34  # 평균 이하
1   -0.65   -0.45
2    0.00    0.45  # 평균
3    1.83    1.34  # 평균 이상

해석:

  • 0: 평균
  • +1: 평균보다 1 표준편차 위
  • -1: 평균보다 1 표준편차 아래

장점:

  • ✅ 이상치에 덜 민감
  • ✅ 많은 ML 알고리즘의 기본 가정

단점:

  • ❌ 범위가 고정되지 않음 (대부분 -3~+3)

3-4. 정규화 vs 표준화 선택 가이드

상황추천 방법이유
이미지 데이터 (픽셀)Min-Max 정규화0~1 범위가 자연스러움
일반 수치 데이터Z-Score 표준화이상치에 강함
신경망 (딥러닝)Min-Max or Z-Score둘 다 가능, 실험 필요
거리 기반 (KNN, SVM)반드시 스케일링 필요범위 차이 문제 해결
트리 기반 (Decision Tree)스케일링 불필요분기 기준에 영향 없음

4. 차원 축소 기법 – PCA(주성분 분석)

4-1. 차원의 저주 (Curse of Dimensionality)

문제: Feature가 너무 많으면?

Feature 개수문제점
100개학습 시간 증가
1,000개과적합 위험 증가
10,000개데이터 희소성 → 모델 성능 저하

비유:

  • 2차원(평면)에서 점 10개 → 밀도 높음
  • 100차원 공간에서 점 10개 → 거의 비어있음

해결책: 차원 축소 (Dimensionality Reduction)

4-2. PCA (Principal Component Analysis)

정의: 데이터의 분산을 최대로 보존하면서 저차원으로 투영

핵심 아이디어:

100개 Feature → 2개 주성분 (Principal Component)
정보 손실: 5% → 정보 보존: 95%

시각적 이해:

3D 데이터 (X, Y, Z)
       ↓
     PCA 적용
       ↓
2D 데이터 (PC1, PC2)
  • PC1 (제1 주성분): 데이터의 분산이 가장 큰 방향
  • PC2 (제2 주성분): PC1과 직교하면서 분산이 두 번째로 큰 방향

4-3. PCA 작동 원리

단계별 설명:

1단계: 데이터 표준화

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

2단계: 공분산 행렬 계산

데이터의 Feature 간 관계 파악

3단계: 고유값/고유벡터 계산

  • 고유벡터: 주성분의 방향
  • 고유값: 해당 방향의 분산 크기

4단계: 주성분 선택

고유값이 큰 순서대로 k개 선택

5단계: 데이터 변환

원본 데이터를 새로운 주성분 축에 투영

4-4. PCA Python 구현

실전 예시: 붓꽃 데이터 (4차원 → 2차원)

from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

# 1. 데이터 로드
iris = load_iris()
X = iris.data  # 4개 Feature
y = iris.target

# 2. PCA: 4차원 → 2차원
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

# 3. 설명된 분산 비율
print(f"PC1 설명 분산: {pca.explained_variance_ratio_[0]:.2%}")
print(f"PC2 설명 분산: {pca.explained_variance_ratio_[1]:.2%}")
print(f"총 설명 분산: {sum(pca.explained_variance_ratio_):.2%}")

# 4. 시각화
plt.figure(figsize=(10, 6))
for i, target_name in enumerate(iris.target_names):
    plt.scatter(
        X_pca[y == i, 0], 
        X_pca[y == i, 1],
        label=target_name
    )
plt.xlabel('PC1')
plt.ylabel('PC2')
plt.legend()
plt.title('PCA: 4D → 2D')
plt.show()

출력:

PC1 설명 분산: 72.96%
PC2 설명 분산: 22.85%
총 설명 분산: 95.81%

해석:

  • 4개 Feature → 2개 주성분으로 정보의 95.81% 보존
  • 시각화 가능 + 학습 속도 2배 향상

4-5. 최적 주성분 개수 선택

방법 1: 누적 설명 분산 (Cumulative Explained Variance)

import numpy as np

# 모든 주성분 계산
pca = PCA()
pca.fit(X)

# 누적 설명 분산
cumsum = np.cumsum(pca.explained_variance_ratio_)

# 95% 이상 설명하는 최소 주성분 개수
n_components = np.argmax(cumsum >= 0.95) + 1
print(f"95% 설명에 필요한 주성분: {n_components}개")

방법 2: 스크리 플롯 (Scree Plot)

plt.figure(figsize=(10, 6))
plt.plot(range(1, len(pca.explained_variance_ratio_) + 1),
         pca.explained_variance_ratio_, 'bo-')
plt.xlabel('주성분 번호')
plt.ylabel('설명 분산 비율')
plt.title('Scree Plot')
plt.axhline(y=0.05, color='r', linestyle='--', label='5% 기준선')
plt.legend()
plt.show()

해석:

  • 그래프가 급격히 꺾이는 지점 = Elbow Point → 최적 개수

4-6. PCA의 장단점

장점:

  • ✅ 차원 축소로 학습 속도 향상
  • ✅ 시각화 가능 (2D, 3D)
  • ✅ 다중공선성 제거 (Feature 간 상관관계 해소)
  • ✅ 노이즈 제거

단점:

  • 해석 불가능: PC1이 “무엇”인지 설명 어려움
  • 예: PC1 = 0.5×키 + 0.3×몸무게 – 0.2×나이 (의미 모호)
  • ❌ 정보 손실 (5~20%)
  • ❌ 선형 변환만 가능 (비선형 패턴 포착 못함)

대안:

  • t-SNE: 비선형 차원 축소 (시각화 특화)
  • UMAP: t-SNE 개선 (속도 빠름)
  • Auto-encoder: 딥러닝 기반 차원 축소

5. 실전 특성 공학 체크리스트

5-1. 데이터 탐색 단계

  • [ ] EDA (탐색적 데이터 분석) 수행
  • [ ] 각 Feature의 분포 확인 (히스토그램)
  • [ ] Target과의 상관관계 분석
  • [ ] Feature 간 상관관계 (다중공선성 확인)
  • [ ] 결측치 패턴 확인
  • [ ] 랜덤 결측 vs 체계적 결측
  • [ ] 이상치 탐지
  • [ ] 박스플롯, Z-Score

5-2. Feature 생성 단계

  • [ ] 도메인 지식 활용
  • [ ] 날짜 → 요일, 시간대, 계절
  • [ ] 텍스트 → 길이, 단어 수, 감정
  • [ ] Feature 조합
  • [ ] 비율: A/B
  • [ ] 차이: A-B
  • [ ] 곱: A×B
  • [ ] 다항식: A², A³
  • [ ] 범주형 Feature 처리
  • [ ] One-Hot Encoding
  • [ ] Label Encoding
  • [ ] Target Encoding

5-3. Feature 선택 단계

  • [ ] 중복 Feature 제거
  • [ ] 상관계수 > 0.9인 쌍 제거
  • [ ] 저분산 Feature 제거
  • [ ] Variance Threshold
  • [ ] Feature Importance
  • [ ] RandomForest로 중요도 측정
  • [ ] 하위 20% Feature 제거

5-4. 스케일링 단계

  • [ ] 알고리즘별 스케일링 필요 여부 확인
  • [ ] 필요: KNN, SVM, 신경망
  • [ ] 불필요: Decision Tree, Random Forest
  • [ ] 스케일링 방법 선택
  • [ ] 이미지 → Min-Max
  • [ ] 일반 데이터 → StandardScaler
  • [ ] Train/Test 별도 스케일링
  • [ ] Train으로 fit → Test는 transform만
# ❌ 잘못된 방법: 전체 데이터로 스케일링
scaler.fit(X)  # Train + Test 모두 사용

# ✅ 올바른 방법: Train만으로 학습
scaler.fit(X_train)  # Train만 사용
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)

5-5. 차원 축소 단계

  • [ ] 차원 축소 필요성 판단
  • [ ] Feature > 50개: 고려
  • [ ] Feature > 100개: 강력 추천
  • [ ] PCA 적용
  • [ ] 95% 분산 보존 목표
  • [ ] Scree Plot으로 최적 개수 선택
  • [ ] 성능 비교
  • [ ] PCA 전 vs 후 모델 성능 비교

6. 실전 예제: Kaggle Titanic 데이터

6-1. 원시 데이터

import pandas as pd

df = pd.read_csv('titanic.csv')
print(df.head())

출력:

   PassengerId  Survived  Pclass  Name                 Sex   Age  SibSp  Parch  Fare
0            1         0       3  Braund, Mr. Owen     male  22.0      1      0   7.25
1            2         1       1  Cumings, Mrs. John   female 38.0     1      0  71.28

6-2. 특성 공학 적용

1단계: 새로운 Feature 생성

# 가족 크기
df['FamilySize'] = df['SibSp'] + df['Parch'] + 1

# 혼자 탑승 여부
df['IsAlone'] = (df['FamilySize'] == 1).astype(int)

# 이름에서 호칭 추출
df['Title'] = df['Name'].str.extract(' ([A-Za-z]+)\.', expand=False)

# 나이 범주화
df['AgeGroup'] = pd.cut(df['Age'], bins=[0, 12, 18, 60, 100],
                        labels=['Child', 'Teen', 'Adult', 'Senior'])

# Fare 로그 변환 (왜도 제거)
df['Fare_log'] = np.log1p(df['Fare'])

2단계: 범주형 Feature 인코딩

# One-Hot Encoding
df = pd.get_dummies(df, columns=['Sex', 'Embarked', 'Title'])

# Label Encoding (순서 있음)
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df['AgeGroup_encoded'] = le.fit_transform(df['AgeGroup'].astype(str))

3단계: Feature 선택

from sklearn.ensemble import RandomForestClassifier

# 중요도 계산
model = RandomForestClassifier()
model.fit(X_train, y_train)

importance = pd.DataFrame({
    'feature': X.columns,
    'importance': model.feature_importances_
}).sort_values('importance', ascending=False)

# 상위 10개 Feature 선택
top_features = importance.head(10)['feature'].tolist()
X_selected = X[top_features]

4단계: 스케일링

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

결과:

  • 원본 Feature: 12개 → 정확도 78%
  • 특성 공학 후: 25개 → 정확도 83% (5%p 향상!)

FAQ: 초보자가 자주 묻는 질문

Q1. Feature가 많으면 무조건 좋은가요?

A. 아니요! “더 많은 Feature = 더 좋은 성능”은 아닙니다. 불필요한 Feature는 (1) 과적합 유발, (2) 학습 시간 증가, (3) 노이즈 증가. Feature는 “양”보다 “질”이 중요합니다.

Q2. 정규화와 표준화 중 어느 것을 써야 하나요?

A. 일반 원칙: (1) 이미지 데이터: Min-Max 정규화, (2) 일반 수치: StandardScaler 표준화, (3) 이상치 많음: RobustScaler. 정답은 없으니 둘 다 실험하세요.

Q3. PCA를 하면 성능이 항상 좋아지나요?

A. 아니요. PCA는 차원 축소가 목적이지 성능 향상이 목적이 아닙니다. 오히려 정보 손실로 성능이 떨어질 수 있습니다. PCA는 (1) 시각화, (2) 학습 속도 향상, (3) 과적합 방지가 주 목적입니다.

Q4. Feature Engineering은 딥러닝에도 필요한가요?

A. 전통 ML: 필수 (80% 시간 소요). 딥러닝: 선택 (딥러닝이 자동으로 Feature 학습). 하지만 도메인 지식 기반 Feature는 딥러닝에서도 효과적입니다. 예: “요일”, “시간대” 같은 명확한 패턴.

Q5. Kaggle에서 특성 공학을 배우려면?

A. (1) Titanic: 가장 기초적인 특성 공학, (2) House Prices: 다양한 Feature 변환, (3) Santander: 대규모 Feature 선택. Kaggle 노트북의 “Feature Engineering” 태그 검색하세요.


외부 참고 자료

특성 공학을 더 깊게 배우고 싶다면:


정리: 이 글에서 배운 것

Feature: AI 모델의 입력 변수, 성능의 80% 결정
특성 선택: 중요한 Feature만 고르기 (필터, 래퍼, 임베디드)
특성 추출: 새로운 Feature 조합 생성 (PCA, 다항식)
정규화/표준화: Feature 범위 조정 (0~1 또는 평균 0)
PCA: 100차원 → 2차원, 정보 95% 보존
핵심: “좋은 Feature = 좋은 AI”, 알고리즘보다 중요

다음 편에서는 신경망의 시작 – 퍼셉트론에서 딥러닝까지에 대해 자세히 알아봅니다. 특히 단층 퍼셉트론, 다층 신경망, 역전파 알고리즘을 수식과 코드로 완벽 설명하겠습니다.


같이 보기

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다