04단계 · 2유형 — 예측과 제출
데이터 나누기 — 왜 나누나
`train_test_split` 으로 학습용과 검증용을 나누고, `stratify` 가 무엇을 맞추는지 본다.
먼저 알아볼게요
코드로 이동 ↓2유형은 라벨이 있는 학습 데이터로 모델을 만들고, 라벨이 없는 평가 데이터의 답을 예측해 제출하는 문제다. 평가 데이터의 정답은 우리에게 없다.
그래서 내 모델이 쓸 만한지 확인하려면, 학습 데이터를 다시 쪼개 일부를 "정답을 아는 가짜 시험지" 로 써야 한다. 이것을 검증(validation) 이라고 한다.
train_test_split(X, y, test_size=0.2, random_state=42) 는 20% 를 검증용으로 떼어 낸다. random_state 는 같은 방식으로 섞으라는 번호다. 이것을 고정해야 다시 돌렸을 때 같은 결과가 나온다.
결과는 순서가 정해져 있다: x_tr, x_va, y_tr, y_va. 순서를 바꿔 받으면 오류 없이 엉뚱한 학습이 된다.
stratify=y 를 주면 나눈 양쪽의 정답 비율을 원본에 맞춰 나눈다. 행 수가 딱 떨어지지 않으면 정확히 같아지지는 않고 가장 가깝게 맞춘다. 아래 과제에서는 random_state=7 로 그냥 나누면 학습 0.5547 · 검증 0.4375 로 어긋나는데, stratify=y 를 주면 이 데이터에서는 양쪽 다 원본과 같은 0.5312 가 된다.
import pandas as pd
from sklearn.model_selection import train_test_split
train = pd.read_csv("churn_train.csv")
X = train[["가입개월", "월요금"]]
y = train["이탈"]
a, b, c, d = train_test_split(X, y, test_size=0.5, random_state=0)
print(a.shape, b.shape)random_state 를 고정해야 결과가 재현된다. 받는 순서는 x_tr, x_va, y_tr, y_va 다.
churn_train.csv 에서 고객ID·이탈·성별·요금제 를 뺀 것을 X, 이탈 을 y 로 두고 ① random_state=42, test_size=0.2 로 나눈 두 X 의 shape ② 두 y 의 행 수 ③ 전체 y 의 평균(소수 4) ④ random_state=7 로 그냥 나눴을 때 두 y 의 평균 ⑤ 같은 random_state=7 에 stratify=y 를 더했을 때 두 y 의 평균을 출력하세요(모두 소수 4).
제공 파일 1개 · 내용 보기
파일은 준비되어 있어요. 코드에서 이름으로 불러오세요.
고객ID,성별,요금제,가입개월,월요금,부가서비스,이탈 C1001,남,standard,22,44300,3,1 C1002,여,premium,1,62000,1,1 C1003,남,premium,45,64000,0,1 C1004,남,basic,10,32200,1,1 C1005,남,premium,5,69500,0,1 C1006,여,basic,56,29500,0,0 C1007,여,premium,48,62800,2,0 C1008,여,standard,5,56700,1,1 C1009,여,basic,49,30600,3,0 C1010,여,premium,52,74800,2,1 C1011,여,basic,19,32800,2,1 C1012,여,standard,18,42200,3,0 C1013,남,standard,37,47900,1,0 C1014,남,basic,1,30500,4,1 C1015,여,standard,52,43200,0,0 C1016,남,premium,31,75300,3,1 C1017,여,basic,22,29100,1,1 C1018,남,standard,39,48400,1,1 C1019,남,premium,35,82500,0,0 C1020,남,standard,19,42600,3,0 C1021,남,basic,22,27300,4,1 C1022,여,basic,38,27800,1,1 C1023,남,standard,5,54200,0,1 C1024,여,premium,36,77200,3,0 C1025,여,standard,14,46500,1,1 C1026,남,premium,15,64500,2,1 C1027,남,basic,45,28100,4,0 C1028,남,standard,49,40600,1,1 C1029,남,standard,59,50800,4,0 C1030,여,basic,16,27800,3,1 C1031,남,basic,36,24900,0,1 C1032,남,basic,17,30200,4,0 C1033,여,basic,36,29900,3,1 C1034,남,basic,36,23800,2,0 C1035,여,standard,9,50200,1,1 C1036,여,premium,45,60800,2,0 C1037,여,standard,37,42900,3,0 C1038,여,basic,37,24800,2,0 C1039,남,standard,42,46300,0,0 C1040,여,basic,34,28400,2,1 C1041,남,premium,11,84200,3,1 C1042,남,standard,9,57000,4,1 C1043,여,standard,11,43500,3,1 C1044,여,basic,42,29200,2,1 C1045,여,premium,10,66800,4,1 C1046,남,premium,56,62700,2,0 C1047,남,standard,19,44100,3,1 C1048,여,basic,14,33700,2,0 C1049,여,basic,44,28800,0,1 C1050,여,premium,32,69800,0,1 C1051,남,basic,52,24100,3,0 C1052,남,standard,48,35900,1,0 C1053,여,basic,41,26300,0,0 C1054,여,basic,36,25500,1,1 C1055,여,basic,7,29000,3,0 C1056,여,basic,34,32700,3,1 C1057,남,standard,42,48900,4,1 C1058,여,basic,32,25800,1,1 C1059,남,standard,56,50100,3,0 C1060,여,standard,28,41500,1,0 C1061,여,premium,47,73900,0,0 C1062,남,premium,4,53900,3,1 C1063,여,premium,4,72600,0,1 C1064,여,basic,42,29100,4,1 C1065,남,basic,59,29800,4,0 C1066,남,premium,28,75100,1,0 C1067,남,basic,27,27200,0,0 C1068,남,basic,60,30100,2,1 C1069,여,premium,4,67400,1,1 C1070,여,basic,4,34100,0,1 C1071,남,standard,42,40800,4,0 C1072,여,premium,53,72900,4,0 C1073,남,standard,36,37500,1,0 C1074,남,standard,44,49800,0,0 C1075,남,basic,5,29700,3,1 C1076,남,premium,1,75600,3,1 C1077,남,standard,44,40600,1,1 C1078,여,basic,7,23800,1,0 C1079,여,premium,47,66100,4,1 C1080,남,standard,32,41500,1,0 C1081,남,premium,37,78500,4,1 C1082,남,premium,52,68500,1,0 C1083,남,premium,51,61900,3,1 C1084,남,basic,38,30000,2,1 C1085,남,basic,12,30900,0,0 C1086,남,premium,25,74900,1,1 C1087,여,standard,40,47300,1,0 C1088,남,standard,6,41600,1,1 C1089,남,premium,57,64200,4,0 C1090,여,basic,42,28700,0,1 C1091,여,standard,27,37300,0,1 C1092,남,basic,27,25900,2,1 C1093,여,basic,41,27900,0,0 C1094,남,standard,60,44200,0,0 C1095,남,premium,12,67100,2,1 C1096,남,standard,46,45700,1,0 C1097,여,standard,23,48800,1,1 C1098,남,premium,57,75300,4,0 C1099,남,premium,13,53900,0,0 C1100,여,premium,29,61600,3,1 C1101,남,standard,2,47300,3,1 C1102,남,standard,10,55900,1,1 C1103,남,premium,3,71800,1,1 C1104,남,premium,53,70000,1,0 C1105,남,premium,32,71300,2,1 C1106,남,premium,9,66000,0,1 C1107,여,premium,30,66100,2,1 C1108,남,standard,43,53500,3,0 C1109,남,basic,26,29400,4,0 C1110,여,standard,21,48500,4,0 C1111,남,standard,51,42400,0,1 C1112,남,premium,21,74100,4,0 C1113,남,premium,56,56600,0,0 C1114,남,standard,46,45300,4,0 C1115,여,standard,48,42300,4,0 C1116,여,basic,35,24700,4,1 C1117,여,premium,22,42700,1,0 C1118,남,standard,9,39900,4,1 C1119,남,premium,36,73100,1,0 C1120,여,premium,38,73800,0,1 C1121,여,standard,13,49300,4,0 C1122,남,basic,48,30300,0,0 C1123,남,standard,16,43800,0,1 C1124,남,premium,15,74000,2,1 C1125,남,basic,25,30200,0,1 C1126,남,basic,44,33000,2,1 C1127,남,basic,56,21800,3,0 C1128,남,standard,48,38600,1,0 C1129,여,premium,15,68200,0,1 C1130,여,basic,28,27400,3,0 C1131,남,standard,54,40800,4,0 C1132,남,basic,45,26900,3,0 C1133,여,premium,21,66200,0,1 C1134,여,premium,39,58900,0,0 C1135,남,basic,43,29000,3,0 C1136,남,standard,9,48600,4,1 C1137,남,basic,28,30300,1,0 C1138,남,premium,30,78600,4,0 C1139,남,basic,18,23900,3,0 C1140,남,standard,46,40900,2,1 C1141,남,premium,6,70300,0,1 C1142,남,basic,46,29100,1,0 C1143,남,standard,18,41600,3,0 C1144,여,basic,53,27800,3,1 C1145,여,basic,7,25400,0,1 C1146,남,basic,27,28800,0,1 C1147,여,premium,51,64300,4,0 C1148,남,premium,25,53100,2,0 C1149,남,standard,54,43800,1,1 C1150,남,premium,40,57700,0,1 C1151,여,standard,24,42900,3,1 C1152,남,premium,21,63300,1,1 C1153,여,standard,44,34800,3,0 C1154,여,basic,29,27400,2,1 C1155,여,premium,38,61500,1,0 C1156,여,premium,48,62600,4,0 C1157,남,basic,27,26900,1,1 C1158,남,standard,20,38000,4,0 C1159,여,premium,22,63700,2,1 C1160,여,standard,20,42800,1,0
들여쓰기: Tab · 편집기에서 나가기: Esc 다음 Tab
실행 결과
실행하면 코드가 출력한 내용이 여기에 나타나요.
막혔을 때
풀이와 비교하기
내 코드와 한 줄씩 비교해 보세요. 풀이를 보는 것만으로 완료되지는 않아요.
import pandas as pd
from sklearn.model_selection import train_test_split
train = pd.read_csv("churn_train.csv")
X = train.drop(columns=["고객ID", "이탈", "성별", "요금제"])
y = train["이탈"]
x_tr, x_va, y_tr, y_va = train_test_split(X, y, test_size=0.2, random_state=42)
print(x_tr.shape, x_va.shape)
print(y_tr.shape[0], y_va.shape[0])
print(round(y.mean(), 4))
a_tr, a_va, ay_tr, ay_va = train_test_split(X, y, test_size=0.2, random_state=7)
print(round(ay_tr.mean(), 4), round(ay_va.mean(), 4))
s_tr, s_va, sy_tr, sy_va = train_test_split(X, y, test_size=0.2, random_state=7, stratify=y)
print(round(sy_tr.mean(), 4), round(sy_va.mean(), 4))