변수 변환
IT 위키
더 많은 작업
- Variable Transformation; 변수 변환
- 변수의 척도·분포·형태를 분석 모형에 맞게 바꾸는 전처리 기법
변수마다 단위가 다르면 거리 기반 모형(K-NN, K-평균, SVM)이 큰 값을 가진 변수에 끌려가고, 한쪽으로 치우친 분포는 선형 모형의 가정을 깨뜨린다. 변수 변환은 이런 문제를 줄인다.
| 기법 | 공식 | 결과 | 특징 |
|---|---|---|---|
| 표준화(Z-score) | 평균 0, 표준편차 1 | 이상값의 영향을 받는다 | |
| 최소-최대 정규화 | 0~1 범위 | 이상값 하나가 범위를 크게 바꾼다 | |
| 로버스트 스케일링 | 중앙값 0 | 중앙값과 IQR을 써서 이상값에 강하다 |
오른쪽 꼬리가 긴(양의 왜도) 분포를 정규분포에 가깝게 만든다.
- 로그 변환 : . 0이 있으면 을 쓴다. 소득, 거래 금액처럼 크기 차이가 큰 변수에 쓴다
- 제곱근 변환 : . 로그보다 약하게 작용하며 개수(count) 데이터에 쓴다
- Box-Cox 변환 : 모수 를 데이터로 추정하는 거듭제곱 변환. 양수 데이터에만 쓸 수 있다
- Yeo-Johnson 변환 : Box-Cox를 0과 음수까지 쓸 수 있게 확장한 변환
연속형 변수를 몇 개의 구간(범주)으로 나눈다(binning, 이산화).
- 등간격 구간화 : 구간 폭을 같게 나눈다. pandas
cut - 등빈도 구간화 : 구간마다 관측 수를 같게 나눈다. pandas
qcut - 잡음을 줄이는 평활화 효과가 있지만, 정보 손실이 생긴다
| 상황 | 변환 | 효과 |
|---|---|---|
| 오른쪽 꼬리가 긴 분포(양의 왜도) | 로그, 제곱근 | 큰 값을 작게 눌러 꼬리를 줄인다 |
| 왼쪽 꼬리가 긴 분포(음의 왜도) | 제곱, 지수(exp) | 작은 값을 크게 벌려 꼬리를 줄인다 |
| 단위·범위가 서로 다름 | 최소-최대 정규화 | 값을 0~1 범위로 옮긴다 |
- 구간을 많이 나눌수록 원래 값의 정보가 많이 남아 정확도는 높아질 수 있지만, 범주가 늘어 계산이 느려진다.
- 구간을 적게 나눌수록 처리는 빨라지지만 정보 손실이 커져 정확도가 떨어진다.
- "구간 수가 줄면 정확도는 높아지고 속도는 느려진다" 는 두 방향이 모두 거꾸로라 틀리다.
| 기법 | 방법 | 쓰는 곳 |
|---|---|---|
| 원-핫 인코딩 | 범주마다 0/1 더미 변수를 만든다 | 순서 없는 명목형 변수. 범주가 많으면 차원이 커진다. 원 핫 인코딩 참고 |
| 레이블 인코딩 | 범주에 정수 0, 1, 2…를 붙인다 | 트리 모형, 순서형 변수. 선형 모형에서는 가짜 순서가 생긴다 |
- 텍스트 : 토큰화 후 Bag of Words, TF-IDF, 워드 임베딩 등으로 수치 벡터로 바꾼다
- 이미지 : 픽셀 값을 0~1로 스케일링하거나 크기를 맞춘 뒤 텐서로 바꾼다
import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler, PowerTransformer
df = pd.DataFrame({"income": [200, 250, 300, 320, 5000],
"city": ["서울", "부산", "서울", "대구", "부산"]})
df["income_std"] = StandardScaler().fit_transform(df[["income"]]).ravel()
df["income_mm"] = MinMaxScaler().fit_transform(df[["income"]]).ravel()
df["income_rb"] = RobustScaler().fit_transform(df[["income"]]).ravel()
df["income_log"] = np.log1p(df["income"])
df["income_bc"] = PowerTransformer(method="box-cox").fit_transform(df[["income"]]).ravel()
df["income_bin"] = pd.qcut(df["income"], q=2, labels=["하", "상"])
df = pd.get_dummies(df, columns=["city"]) # 원-핫 인코딩
스케일러는 학습 데이터로만 fit하고, 같은 객체로 평가 데이터를 transform해야 한다. 평가 데이터까지 합쳐 fit하면 정보가 새어 나간다.
- 표준화·최소-최대 정규화 값 계산, 이상값에 강한 기법(로버스트 스케일링) 고르기
- Box-Cox는 양수만 가능하다는 점, 로그 변환이 왜도를 줄인다는 점
- 원-핫과 레이블 인코딩의 차이, 실기 작업형 2유형에서 인코딩·스케일링 적용