본문 바로가기
AI 공부/머신러닝

(머신러닝) data leakage

by AI Sonny 2022. 9. 15.
728x90

Data leakage (중요!)

  • 데이터 유출
  • 예측할 때 사용할 수 없는 정보가 학습 데이터로 사용되는 것 (모델이 과대평가 된다.)

 

 

예시

 

tmp = pd.DataFrame(
    enc.fit_transform(train_churn[cols]).toarray(),
    columns = enc.get_feature_names_out() # 컬럼 이름 넣기
)

train = pd.concat([train,tmp],axis=1)
train.head()

=>
	gender	SeniorCitizen	Partner	Dependents	tenure	PhoneService	MultipleLines	OnlineSecurity	OnlineBackup	DeviceProtection	...	PaperlessBilling	MonthlyCharges	TotalCharges	InternetService_DSL	InternetService_Fiber optic	InternetService_No	PaymentMethod_Bank transfer (automatic)	PaymentMethod_Credit card (automatic)	PaymentMethod_Electronic check	PaymentMethod_Mailed check	0	0	0	1	1	0	0	0	0	0	...	0	25.30	25.30	1.0	0.0	0.0	0.0	0.0	1.0	0.0	1	0	0	0	7	1	0	0	0	1	...	0	75.15	525.00	0.0	1.0	0.0	0.0	0.0	1.0	0.0
	1	0	0	1	4	1	0	0	0	0	...	0	20.05	85.50	0.0	0.0	1.0	1.0	0.0	0.0	0.0
	1	0	0	0	29	1	1	0	0	0	...	0	76.00	2215.25	0.0	1.0	0.0	0.0	1.0	0.0	0.0
	1	0	0	0	3	1	1	0	0	0	...	0	75.10	270.70	0.0	1.0	0.0	0.0	1.0	0.0	0.0
5 rows × 24 columns

 

다음과 같이 학습데이터에서 범주형 데이터를 원핫 인코딩한 후 데이터프레임을 만들고,

 

fit_ tranform을 통해 정닶값을 제외한 train에 concat을 한다.

 

그 후 test 데이터도 동일하게 concat을 해야하는데 주의할 점이 있다.

 

tmp = pd.DataFrame(
    enc.transform(test_churn[cols]).toarray(),
    columns = enc.get_feature_names_out()
)

test = pd.concat([test,tmp],axis = 1)
test.head()

=>
gender	SeniorCitizen	Partner	Dependents	tenure	PhoneService	MultipleLines	OnlineSecurity	OnlineBackup	DeviceProtection	...	PaperlessBilling	MonthlyCharges	TotalCharges	InternetService_DSL	InternetService_Fiber optic	InternetService_No	PaymentMethod_Bank transfer (automatic)	PaymentMethod_Credit card (automatic)	PaymentMethod_Electronic check	PaymentMethod_Mailed check
0	1	0	1	0	1	0	0	0	0	0	...	0	24.80	24.80	1.0	0.0	0.0	0.0	0.0	1.0	0.0
1	0	0	0	0	41	1	1	0	0	0	...	0	25.25	996.45	0.0	0.0	1.0	1.0	0.0	0.0	0.0
2	1	0	1	1	52	1	0	0	0	0	...	1	19.35	1031.70	0.0	0.0	1.0	0.0	0.0	0.0	1.0
3	1	0	0	0	1	1	0	0	0	1	...	1	76.35	76.35	0.0	1.0	0.0	0.0	0.0	1.0	0.0
4	0	0	0	0	67	1	0	0	0	0	...	1	50.55	3260.10	1.0	0.0	0.0	1.0	0.0	0.0	0.0
5 rows × 24 columns

 

  • 테스트 데이터에 대해서는 transform 만 해야한다.
  • test 데이터는 절대 fit_transform 금지!
  • fit_transform을 하면 데이터 유출이 발생한다.

 


추가 피쳐 만들어 보기

 

- 가입기간별로 여성의 비율을 피쳐로 추가 하기

 

train_tmp = train_churn.groupby("tenure")["gender"].agg("mean").reset_index()
train_tmp = train_tmp.rename(columns  = {"gender":"gender_rate"})
train_tmp.head()

=>
tenure	gender_rate
0	0	0.375000
1	1	0.451327
2	2	0.530120
3	3	0.483660
4	4	0.518519

 

merge 하기

 

train = train.merge(train_tmp,how="left",on="tenure")

 

테스트 데이터에 대해서 학습데이터에 추가한 동일한 피쳐 추가 시 데이터 유출 사례

  • 실제 서비스에서 예측해야 하는 데이터를 하나의 샘플만 예측 해야할 때도 있고 여러개의 샘플을 예측해야할때가 있다.
  • 다음과 같이 피쳐를 추가 할 경우 하나의 샘플만 예측해야하는경우 피쳐를 만들 수 없다.
test_tmp = test_churn.groupby("tenure")["gender"].agg("mean").reset_index()
test_tmp = test_tmp.rename(columns  = {"gender":"gender_rate"})
test.merge(test_tmp,how="left",on="tenure")

=> 
gender	SeniorCitizen	Partner	Dependents	tenure	PhoneService	MultipleLines	OnlineSecurity	OnlineBackup	DeviceProtection	...	MonthlyCharges	TotalCharges	InternetService_DSL	InternetService_Fiber optic	InternetService_No	PaymentMethod_Bank transfer (automatic)	PaymentMethod_Credit card (automatic)	PaymentMethod_Electronic check	PaymentMethod_Mailed check	gender_rate
0	1	0	1	0	1	0	0	0	0	0	...	24.80	24.80	1.0	0.0	0.0	0.0	0.0	1.0	0.0	0.496894
1	0	0	0	0	41	1	1	0	0	0	...	25.25	996.45	0.0	0.0	1.0	1.0	0.0	0.0	0.0	0.562500
2	1	0	1	1	52	1	0	0	0	0	...	19.35	1031.70	0.0	0.0	1.0	0.0	0.0	0.0	1.0	0.413793
3	1	0	0	0	1	1	0	0	0	1	...	76.35	76.35	0.0	1.0	0.0	0.0	0.0	1.0	0.0	0.496894
4	0	0	0	0	67	1	0	0	0	0	...	50.55	3260.10	1.0	0.0	0.0	1.0	0.0	0.0	0.0	0.454545
...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...	...
1756	1	0	0	0	3	1	1	0	0	0	...	75.80	246.30	0.0	1.0	0.0	0.0	0.0	1.0	0.0	0.574468
1757	1	0	1	0	8	1	1	0	0	0	...	90.25	743.75	0.0	1.0	0.0	0.0	0.0	1.0	0.0	0.541667
1758	0	0	0	0	29	1	1	0	1	1	...	70.90	1964.60	1.0	0.0	0.0	0.0	1.0	0.0	0.0	0.388889
1759	1	0	0	0	2	0	0	0	0	0	...	34.70	62.25	1.0	0.0	0.0	0.0	0.0	1.0	0.0	0.583333
1760	1	1	0	0	53	1	0	0	1	0	...	73.80	4003.85	0.0	1.0	0.0	0.0	1.0	0.0	0.0	0.600000
1761 rows × 25 columns

 

위 코드에서 다음과 같이 학습데이터에서 추출한 피쳐를 적용해야 데이터 유출을 방지 할 수 있다.

 

test_tmp = train_tmp.rename(columns  = {"gender":"gender_rate"})

 

 

merge 하기

 

test = test.merge(train_tmp,how="left",on="tenure")

 

즉, 정답데이터에 피쳐를 추가하거나 통계치를 뽑는 것은 말도 안된다.  -> train으로 merge해라!
 

만약에 결측치가 생기면 trian에서 나온 통계치로 채워 넣어라!

 


오늘은 개인전으로 각자 앙상블을 하든 피처 추가를 하든 roc를 올리는 것에 대해 하였다.

 

처음에 1등해서 기분이 좋았는데 나중에 역전당해서 속상했다...

 

잘하는 분들이 많다.

728x90

'AI 공부 > 머신러닝' 카테고리의 다른 글

(머신러닝) XAI와 SHAP  (1) 2022.09.15
(머신러닝) 비지도 학습 - 차원축소  (1) 2022.09.14
(머신러닝) 모델튜닝  (1) 2022.09.13
(머신러닝) 앙상블  (0) 2022.09.13
(머신러닝) 머신러닝 모델  (2) 2022.09.13

댓글