AICE (에이스) 시험 노트개념 정리16 MIN
스케일링 세 가지와 fit·transform
AICE Associate 전처리에서 열마다 다른 크기를 맞추는 자리입니다. StandardScaler·MinMaxScaler·RobustScaler의 계산, fit_transform과 transform의 구별, 데이터 누수, 트리 모델과 스케일링을 연습 문제 7개로 짚습니다.
모든 열이 숫자가 됐어도 아직 고르지 않은 것이 있습니다. 나이는 20에서 70 사이에 있고 연 소득은 2,000만에서 1억 사이에 있습니다. 두 열을 그대로 넣으면 모델이 보는 차이는 나이 10살보다 소득 1원이 먼저입니다 — 숫자의 크기가 백만 배 넘게 다르기 때문입니다.
열마다 다른 크기를 한 잣대로 옮기는 일이 스케일링입니다. 사이킷런에는 스케일러가 여럿 있지만 AICE Associate가 다루는 것은 셋이고, 셋 모두 쓰는 틀이 같습니다. 시험은 「StandardScaler로 정규화하시오」처럼 클래스를 지정하거나, 변환 결과의 값을 묻거나, fit을 어디에 걸었는지를 따집니다.
스케일링과 모델
거리와 기울기
크기가 문제가 되는 모델은 숫자의 크기 자체를 계산에 쓰는 모델입니다. 가까운 이웃을 거리로 찾는 KNN은 소득 차이가 거리를 통째로 차지해 나이가 사실상 무시됩니다. 오차를 줄이는 쪽으로 가중치를 조금씩 옮기는 경사하강법을 쓰는 모델 — 로지스틱 회귀와 신경망 — 은 열마다 크기가 다르면 한쪽 가중치만 크게 흔들려 학습이 느리거나 불안정해집니다.
서포트 벡터 머신(SVM)도 거리로 경계를 정하므로 같은 무리에 듭니다.
트리 모델
결정트리는 「소득이 5,000만보다 큰가」처럼 한 열의 값을 기준값과 비교해 둘로 가르는 일을 되풀이합니다. 비교에 쓰는 것은 값의 차례뿐이라, 열 전체를 같은 식으로 늘이거나 줄여도 어느 행이 어느 쪽으로 가는지는 바뀌지 않습니다. 그래서 결정트리와 그것을 여럿 묶은 랜덤포레스트·XGBoost·LightGBM에는 스케일링이 필요 없습니다.
걸어도 해가 되지는 않으므로, 여러 모델을 한 번에 비교하는 문항에서는 공통으로 걸어 두기도 합니다. 다만 「트리 모델을 쓸 때 반드시 해야 하는 전처리」를 고르라는 보기에 스케일링이 있으면 그것은 오답입니다.
| 모델 | 크기를 쓰는 방식 | 스케일링 |
|---|---|---|
| KNN, SVM | 거리 | 필요 |
| 로지스틱 회귀, 신경망 | 경사하강법 | 필요 |
| 결정트리, 랜덤포레스트, XGBoost | 기준값과 비교 | 필요 없음 |
스케일러 셋
StandardScaler
표준화는 열의 평균을 빼고 표준편차로 나눕니다. 평균은 0, 표준편차는 1이 되고, 값은 「평균에서 표준편차 몇 개만큼 떨어졌나」로 바뀝니다.
여기서 는 평균, 는 표준편차입니다. 결과에는 상한·하한이 없어 극단값은 3이나 4를 넘기도 합니다. 사이킷런은 표준편차를 나눌 때 으로 나누는 모표준편차를 씁니다. 판다스의 std()는 기본이 이라 손으로 계산한 값과 소수점 아래가 조금 다를 수 있습니다.
MinMaxScaler
정규화는 최솟값을 0, 최댓값을 1로 옮기고 그 사이를 같은 비율로 채웁니다.
결과가 0에서 1 사이로 딱 떨어져 읽기 쉽지만, 최댓값 하나가 크게 튀면 나머지가 전부 0 근처로 눌립니다. 이미지의 픽셀 값(0~255)처럼 끝이 정해진 값에 잘 맞습니다.
RobustScaler
로버스트 스케일링은 평균 대신 중앙값을 빼고, 표준편차 대신 IQR()로 나눕니다.
중앙값과 사분위수는 극단값 몇 개가 커져도 거의 안 움직이므로, 이상치를 남겨 둔 열에 씁니다. 「이상치의 영향을 덜 받는 스케일러」를 고르라면 이것입니다.
세 스케일러 비교
값이 10, 20, 30, 40, 100인 열에 셋을 걸어 보면 차이가 보입니다. 평균은 40, 모표준편차는 약 31.6, 중앙값은 30, 과 는 20과 40입니다.
| 원래 값 | Standard | MinMax | Robust |
|---|---|---|---|
| 10 | -0.949 | 0.000 | -1.0 |
| 30 | -0.316 | 0.222 | 0.0 |
| 40 | 0.000 | 0.333 | 0.5 |
| 100 | 1.897 | 1.000 | 3.5 |
MinMax에서는 100 하나 때문에 나머지 넷이 0에서 0.333 사이에 몰렸습니다. Robust에서는 보통 값들이 -1에서 0.5 사이에 고르게 퍼지고 100만 3.5로 멀리 떨어져, 이상치가 이상치로 남습니다.
fit과 transform
배우기와 바꾸기
세 스케일러는 모두 두 걸음으로 움직입니다. fit이 데이터에서 변환에 쓸 값을 배우고 — 표준화면 평균과 표준편차, 정규화면 최솟값과 최댓값 — transform이 그 값으로 실제 숫자를 바꿉니다. 배운 값은 객체 안에 남아 scaler.mean_, scaler.data_min_처럼 꺼내 볼 수 있습니다.
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
fit_transform은 fit 뒤에 transform을 한 번에 부르는 줄임입니다. 결과는 판다스 표가 아니라 넘파이 배열로 나오므로, 열 이름이 필요하면 pd.DataFrame(X_train_scaled, columns=X_train.columns)로 다시 감쌉니다.
평가용 transform
평가용에 transform만 거는 것은 학습용에서 배운 잣대를 그대로 쓰겠다는 뜻입니다. 그래서 평가용의 정규화 결과는 0에서 1을 벗어날 수 있습니다. 학습용의 최댓값이 70이었는데 평가용에 80이 있으면 1보다 큰 값이 나옵니다. 오류가 아니라 정상입니다 — 실제 서비스에서 들어올 새 데이터도 학습 때 본 범위를 넘을 수 있습니다.
평가용에도 fit_transform을 걸면 두 데이터가 서로 다른 잣대로 바뀝니다. 학습용에서 0.5였던 나이와 평가용에서 0.5인 나이가 다른 나이가 되는 것이라, 모델이 배운 관계가 평가용에서는 맞지 않습니다.
데이터 누수
누수 경로
모델을 평가하는 목적은 처음 보는 데이터에서 얼마나 맞히는지를 재는 것입니다. 그런데 평가용의 정보가 학습 과정 어딘가에 섞이면 모델은 시험지를 미리 본 셈이 됩니다. 이렇게 알면 안 되는 정보가 학습에 흘러드는 것이 데이터 누수입니다.
스케일링에서 새는 길은 둘입니다. 하나는 평가용에 fit을 거는 것이고, 다른 하나는 나누기 전의 전체 데이터에 fit을 거는 것입니다. 뒤의 것이 더 눈에 안 띕니다. 전체의 평균에는 평가용 행이 들어 있으므로, 그 평균으로 바꾼 학습용은 평가용을 조금 엿본 상태가 됩니다.
순서
막는 방법은 순서 하나입니다 — 나누고 나서, 학습용에만 fit한다.
train_test_split으로 학습용과 평가용을 나눈다- 스케일러를 학습용에
fit_transform한다 - 같은 스케일러로 평가용에
transform한다 - 새로 들어오는 데이터에도 같은 스케일러로
transform한다
누수가 있으면 점수가 실제보다 좋게 나옵니다. 행이 많고 분포가 고르면 차이가 작아 티가 안 나지만, 행이 적거나 이상치가 있으면 눈에 띌 만큼 벌어집니다. 시험에서는 코드 넉 줄을 주고 「누수가 생기는 줄」을 고르게 하는 문항이 자주 나옵니다.
인코딩과의 차이
원핫 인코딩은 나누기 전에 걸어도 된다고 했는데 스케일링은 안 되는 까닭은 배우는 것이 다르기 때문입니다. 인코딩이 배우는 것은 범주의 이름 목록뿐이라 평가용의 값 크기를 알지 못합니다. 스케일링은 평균·최댓값·사분위수처럼 값에서 계산한 수를 배웁니다. 결측치를 평균이나 중앙값으로 채우는 일도 같은 이유로 나눈 뒤에 해야 엄밀합니다.
적용 범위
숫자 열 선택
원핫 열까지 스케일링할 필요는 없습니다. 0과 1뿐인 열을 표준화하면 0.3·-1.2 같은 값이 되어 읽기만 어려워집니다. 연속값 열만 골라 겁니다.
num_cols = ['Age', 'Income', 'Usage']
scaler = MinMaxScaler()
X_train[num_cols] = scaler.fit_transform(X_train[num_cols])
X_test[num_cols] = scaler.transform(X_test[num_cols])
좌변에 열 목록을 그대로 적어 받으면 결과가 원래 표의 그 자리로 들어가 열 이름이 유지됩니다.
타깃 열
회귀의 타깃 y는 보통 스케일링하지 않습니다. 걸면 예측값도 바뀐 잣대로 나오므로 inverse_transform으로 되돌려야 원래 단위의 오차를 잴 수 있습니다. 분류의 타깃은 갈래 번호라 스케일링할 대상이 아닙니다.
출제 형태는 셋입니다. 원래 값과 통계량을 주고 변환 결과를 계산하게 하거나, 누수가 생기는 줄을 고르게 하거나, 스케일링이 필요 없는 모델을 고르게 합니다.
연습 문제
어떤 열의 평균이 50, 표준편차가 10이다.
StandardScaler를 거치면 값 65는 얼마가 되는가?입니다. 평균보다 표준편차 1.5개만큼 크다는 뜻입니다.학습용
Age의 최솟값이 20, 최댓값이 70이다. 이 데이터로fit한MinMaxScaler로 평가용의 45, 80, 10을transform하면 각각 얼마인가?분모는 입니다. 45는 , 80은 , 10은 입니다. 평가용 값이 학습용 범위 밖에 있으면 0~1을 벗어나는 것이 정상입니다.어떤 열의 중앙값이 30, 이 22, 가 46이다.
RobustScaler를 거치면 값 90은 얼마가 되는가?IQR은 이고 입니다.다음 코드에서 데이터 누수가 생기는 줄은?
①X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
②scaler = StandardScaler()
③X_train_s = scaler.fit_transform(X_train)
④X_test_s = scaler.fit_transform(X_test)④. 평가용에fit을 다시 걸어 평가용의 평균과 표준편차로 바뀌었습니다.scaler.transform(X_test)로 고쳐야 학습용의 잣대가 그대로 쓰입니다.다음 중 스케일링을 하지 않아도 결과가 달라지지 않는 모델은?
① KNN
② 로지스틱 회귀
③ 랜덤포레스트
④ 신경망③. 랜덤포레스트를 이루는 결정트리는 값의 차례로만 가르므로 열을 늘이거나 줄여도 갈리는 결과가 같습니다. KNN은 거리, 로지스틱 회귀와 신경망은 경사하강법에서 크기를 씁니다.이상치를 지우지 않고 남겨 둔
Income열을 스케일링하려 한다. 세 스케일러 중 무엇이 알맞고,MinMaxScaler를 쓰면 어떤 일이 생기는가?RobustScaler가 알맞습니다. 중앙값과 IQR은 극단값에 거의 안 움직입니다.MinMaxScaler를 쓰면 최댓값인 이상치가 1을 차지해 나머지 값들이 0 근처의 좁은 구간으로 몰립니다.숫자 열
['Age', 'Income']만StandardScaler로 바꾸되, 바꾼 값이 학습용 표의 원래 열 자리에 들어가도록 학습용·평가용 코드를 쓰시오.열 목록으로 골라 넣고, 평가용에는transform만 겁니다.cols = ['Age', 'Income'] scaler = StandardScaler() X_train[cols] = scaler.fit_transform(X_train[cols]) X_test[cols] = scaler.transform(X_test[cols])
여기서 손이 굳어야 하는 것은 두 줄의 짝입니다 — 학습용에 fit_transform, 평가용에 transform입니다. 그 짝이 성립하려면 학습용과 평가용이 먼저 나뉘어 있어야 하고, 다음이 그 나누기입니다.

