데이터 정규화 (스케일링, 인코딩)
| topics | 100-데이터분석 & AI 103 데이터 분석,처리 |
| types | 이론 실습 레퍼런스 |
| tags |
스케일링, 인코딩
왜 필요한가
스케일링
서로 다른 범위를 가진 특성들을 같은 스케일로 맞춰야 모델이 제대로 학습한다. 예를 들어 나이(0100)와 연봉(1000만1억)을 그대로 쓰면 연봉이 모델에 과도한 영향을 준다.
인코딩
머신러닝 모델은 숫자만 이해한다. "서울", "부산" 같은 범주형 데이터는 숫자로 변환해야 한다.
스케일링
수치형 데이터의 범위나 비율을 일정히 하기 위해 스케일링을 진행한다
스케일링에는 정규화와 표준화가 있다.
언제 스케일링을 안 해도 될까?
트리 계열(Decision Tree, Random Forest, XGBoost) 이나 나이브 베이즈 등에는 굳이 필요 없다. 이 모델들은 값의 범위보다 분포나 순서를 본다.
정규화
$
X_{norm} = \frac{x - x_{min}}{x_{max} - x_{min}}
$
- 변수의 값이 0~1사이
- sklearn func: MinMaxScaler, normalize(각데이터 벡터 크기를1로 조정,L2 기준)
- normalize는 특징을 뽑을때 즉 방향만 필요할때 주로 사용
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
df_normalized = scaler.fit_transform(df)
표준화(정규분포화)
$
X_z = \frac{x - x_{mean}}{x_{std}}
$
- 평균이 0, 표준편차가 1
- sklearn func: StandardScaler
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train) # 평균0 표편 1
# <span id="fit하지않음"></span>fit하지않음
X_test = scaler.transform(X_test) # 이건 X_train에서 계산 한 평균,표편을 사용해서 표준화
함수 정리
| 이름 | 동작 방식 | 적용 대상 | 특징/범위 | 이상치 영향 |
|---|---|---|---|---|
| StandardScaler | 각 컬럼에서 평균을 빼고 표준편차로 나눔 (z-score) | 컬럼(특성) | 평균 0, 분산 1 | 영향 있음 |
| MinMaxScaler | 각 컬럼을 최소 |
컬럼(특성) | 0~1(기본), 범위 변경 가능 | 영향 큼 |
| normalize | 각 행(샘플)을 벡터의 크기(노름)가 1이 되도록 맞춤(합이 1) | 행(샘플) | 벡터 크기 1 | 영향 적음 |
인코딩
범주형 혹은 문자열 데이터를 수치형 데이터로 변환한다
라벨 인코딩
- value가 a,b,c,d 이러면 이걸 그냥 숫자로 단순 변환 (a=0, b=1, c=2, d=3)
- 간단하지만 순서가 없는 범주에 순서를 부여하는 문제 발생 가능
원핫 인코딩
- value가 a,b,c,d 이러면 컬럼_a 이렇게 새로 컬럼을 만든다
- 원핫은 값이 0 아니면 1이다
- 순서/크기 왜곡이 없지만 컬럼 수가 많이 증가한다
| 구분 | 라벨 인코딩 | 원핫 인코딩 |
|---|---|---|
| 변환 방식 | 각 범주를 정수로 매핑 | 각 범주를 별도 열로 만들고 0/1로 표시 |
| 사용 상황 | 순서 없는 범주, 트리 계열 모델, 목표변수 | 순서 없는 범주, 대부분의 모델, 입력 변수 |
| 장점 | 간단, 변수 수 증가 없음 | 순서/크기 정보 왜곡 없음, 대부분 모델에 안전 |
| 단점 | 숫자 간 순서 오해 가능 | 변수(열) 수 증가, 희소 행렬 |
# <span id="라벨-인코딩"></span>라벨 인코딩
from sklearn.processing import LabelEncoder
le = LabelEncoder()
df5['cust_clas_itg_cd'] = le.fit_transform(df5['cust_clas_itg_cd'])
# <span id="원핫인코딩-판다스의-함수임"></span>원핫인코딩, 판다스의 함수임
df6 = pd.get_dummies(df5, columns=cat_cols.drop('cust_clas_itg_cd'))