04단계 · 2유형 — 예측과 제출
분류 모델 만들기 — predict 와 predict_proba
랜덤포레스트 분류기를 학습시키고, 라벨 예측과 확률 예측을 구분한다.
먼저 알아볼게요
코드로 이동 ↓랜덤포레스트는 결정나무 여러 개의 결과를 모아 판단한다. 스케일링 없이도 쓸 수 있고 기본값으로도 쓸 만해서 연습용으로 고르기 쉽다. 어떤 모델이 가장 좋은지는 데이터마다 다르다.
RandomForestClassifier(n_estimators=100, random_state=42) 로 만들고 .fit(X, y) 로 학습한다. random_state 를 안 주면 돌릴 때마다 결과가 조금씩 달라진다.
.predict(X) 는 0 또는 1 을 돌려준다. .predict_proba(X) 는 각 행이 0일 확률과 1일 확률을 두 열로 돌려준다.
predict_proba(X)[:, 1] 은 두 번째 열이다(: 은 모든 행, 1 은 두 번째 열). 그 열이 "1일 확률" 인 것은 model.classes_ 가 [0, 1] 일 때이고, 라벨이 다른 값이면 classes_ 를 먼저 찍어 어느 열이 내가 원하는 쪽인지 확인해야 한다.
.score(X, y) 는 정확도(맞힌 비율)다. 참고용으로는 좋지만, 제출 지표가 AUC 인 문제에서는 정확도가 높아도 점수가 낮을 수 있다(다음 수업).
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
train = pd.read_csv("churn_train.csv")
X = train[["가입개월", "월요금", "부가서비스"]]
y = train["이탈"]
m = RandomForestClassifier(n_estimators=30, random_state=0).fit(X, y)
print(m.predict(X)[:5].tolist())predict 는 라벨, predict_proba(X)[:, 1] 은 classes_[1] 일 확률. 어느 열인지 classes_ 로 확인하고 쓴다.
churn_train.csv 에서 고객ID·이탈 을 뺀 것을 X 로 두고 test_size=0.2, random_state=42, stratify=y 로 나누세요. 학습 쪽의 성별·요금제 에만 OrdinalEncoder 를 맞추고 검증 쪽에는 transform 을 적용한 뒤 RandomForestClassifier(n_estimators=100, random_state=42) 를 학습시키세요. ① model.classes_ 를 리스트로 ② 검증 앞 5개의 예측 라벨 ③ 앞 5개의 classes_[1] 일 확률(소수 4) ④ 검증 정확도(소수 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.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OrdinalEncoder
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, stratify=y)
enc = OrdinalEncoder(handle_unknown="use_encoded_value", unknown_value=-1)
x_tr[["성별", "요금제"]] = enc.fit_transform(x_tr[["성별", "요금제"]])
x_va[["성별", "요금제"]] = enc.transform(x_va[["성별", "요금제"]])
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(x_tr, y_tr)
print(model.classes_.tolist())
print(model.predict(x_va)[:5].tolist())
print([round(float(v), 4) for v in model.predict_proba(x_va)[:5, 1]])
print(round(model.score(x_va, y_va), 4))