Allen's 데이터 맛집
[머신러닝] 분류 : 전자상거래 배송 데이터 예측 본문
전자상거래 배송 데이터
이번 포스팅에선 빅데이터 분석기사의 예제문제인 분류 문제를 가지고 분류예측모델을 만들어보겠습니다.
제품 배송 시간에 맞춰 배송되었는지 예측모델 만들기
학습용 데이터 (X_train, y_train)을 이용하여 배송 예측 모형을 만든 후, 이를 평가용 데이터(X_test)에 적용하여 얻은 예측 확률값을 다음과 같은 형식의 CSV파일로 생성하시오(제출한 모델의 성능은 ROC-AUC 평가지표에 따라 채점)
ID, Reached.on.Time_Y.N
4733,0.6
2040,0.8
5114,0.45
2361,0.23
5996,0.43
[시험용 데이터셋 만들기] 코드는 예시문제와 동일한 형태의 X_train, y_train, X_test 데이터를 만들기 위함임
(유의사항)
- 성능이 우수한 예측모형을 구축하기 위해서는 적절한 데이터 전처리, 피처엔지니어링, 분류알고리즘, 하이퍼파라미터 튜닝, 모형 앙상블 등이 수반되어야 한다.
- 수험번호.csv파일이 만들어지도록 코드를 제출한다.
- 제출한 모델의 성능은 ROC-AUC형태로 읽어드린다.
[참고] 작업형 2 문구
- 출력을 원하실 경우 print() 함수 활용
- 예시) print(df.head())
- getcwd(), chdir() 등 작업 폴더 설정 불필요
- 파일 경로 상 내부 드라이브 경로(C: 등) 접근 불가
데이터 파일 읽기 예제
- import pandas as pd
- X_test = pd.read_csv("data/X_test.csv")
- X_train = pd.read_csv("data/X_train.csv")
- y_train = pd.read_csv("data/y_train.csv")
사용자 코딩
답안 제출 참고
- 아래 코드 예측변수와 수험번호를 개인별로 변경하여 활용
- pd.DataFrame({'cust_id': X_test.cust_id, 'gender': pred}).to_csv('003000000.csv', index=False)
데이터 세팅
# 시험환경 세팅 (코드 변경 X)
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
def exam_data_load(df, target, id_name="", null_name=""):
if id_name == "":
df = df.reset_index().rename(columns={"index": "id"})
id_name = 'id'
else:
id_name = id_name
if null_name != "":
df[df == null_name] = np.nan
X_train, X_test = train_test_split(df, test_size=0.2, random_state=2021)
y_train = X_train[[id_name, target]]
X_train = X_train.drop(columns=[target])
y_test = X_test[[id_name, target]]
X_test = X_test.drop(columns=[target])
return X_train, X_test, y_train, y_test
df = pd.read_csv("../input/customer-analytics/Train.csv")
X_train, X_test, y_train, y_test = exam_data_load(df, target='Reached.on.Time_Y.N', id_name='ID')
X_train.shape, X_test.shape, y_train.shape, y_test.shape
>>> ((8799, 11), (2200, 11), (8799, 2), (2200, 2))
X, Y, 제출 데이터를 변수에 담고 X데이터와 X제출 데이터를 동일한 데이터 전처리 작업을 위해 dfX데이터로 concat함수를 사용하여 합칩니다.
from sklearn.metrics import roc_auc_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
# 제공된 3개 데이터 (y_test데이터 활용X)
X = X_train
Y = y_train
X_submission = X_test
dfX = pd.concat([X, X_submission], ignore_index = True)
dfX.head(3)
EDA
EDA가 힘든 Object 타입인 'Warehouse_block', 'Mode_of_Shipment', 'Product_importance', 'Gender' 칼럼들을 수치형으로 변환해 줍니다.
#dfX.info()
feature = ['Warehouse_block','Mode_of_Shipment','Product_importance','Gender']
dfX[feature].nunique()
for x in feature:
dfX[x] = dfX[x].astype('category').cat.codes
dfX.info()
전처리가 끝난 후 다시 X데이터와 X제출 데이터를 나눠줍니다.
size = X.shape[0]
X1 = dfX[:size]
X1_submission = dfX[size:]
print(X1.shape, X1_submission.shape)
>>> (8799, 11) (2200, 11)
값의 비율을 normalize를 통해 확인해 줍니다.
Y['Reached.on.Time_Y.N'].value_counts(normalize = True).sort_index()
>>> 0 0.403228
>>> 1 0.596772
>>> Name: Reached.on.Time_Y.N, dtype: float64
모델 및 평가
LogisticRegression 모델을 사용하여 r2 score와 roc_auc_score를 계산합니다.
Y1 = Y['Reached.on.Time_Y.N']
xtrain1, xtest1, ytrain1, ytest1 = train_test_split(X1, Y1,
test_size = 0.25, stratify = Y1, random_state = 0)
model1 = LogisticRegression().fit(xtrain1, ytrain1)
a = model1.score(xtrain1,ytrain1)
b = model1.score(xtest1, ytest1)
ypred = model1.predict_proba(xtest1)[:,1]
c = roc_auc_score(ytest1, ypred)
print(f'{a:.4f} {b:.4f} {abs(a-b):.4f} {c:.4f}')
>>> 0.6601 0.6673 0.0072 0.7499
위와 같이 이번엔 RandomForestCalssifier모델을 사용하여 r2 score와 roc_auc_score를 계산합니다.
for x in range(3,9):
model2 = RandomForestClassifier(max_depth=x).fit(xtrain1, ytrain1)
a = model2.score(xtrain1,ytrain1)
b = model2.score(xtest1, ytest1)
ypred = model2.predict_proba(xtest1)[:,1]
c = roc_auc_score(ytest1, ypred)
print(f'{x} {a:.4f} {b:.4f} {abs(a-b):.4f} {c:.4f}')
>>> 3 0.6925 0.6991 0.0066 0.7457
>>> 4 0.6928 0.6973 0.0044 0.7483
>>> 5 0.7009 0.6977 0.0031 0.7538
>>> 6 0.7025 0.6941 0.0084 0.7501
>>> 7 0.7272 0.6955 0.0318 0.7498
>>> 8 0.7553 0.6850 0.0703 0.7435
모델 선택 및 결과 출력
이중 제일 점수가 좋았던 RandomForestCalssifier모델을 사용합니다.
model = RandomForestClassifier(max_depth=5).fit(xtrain1, ytrain1)
ypred = model.predict_proba(X1_submission)[:,1]
ypred
>>> array([0.4278662 , 0.99932841, 0.43842147, ..., 0.40471845, 0.42668574,
0.43136677])
제출할 양식에 맞게 csv파일을 생성합니다.
ID와 Reached.on.Time_Y.N을 사용하여 각 ID별로 제시간에 도착할 확률을 계산한 csv 파일을 저장합니다.
submission = pd.DataFrame({"ID":X1_submission.ID, 'Reached.on.Time_Y.N' : ypred })
submission.to_csv('931226.csv', index = False)
df2 = pd.read_csv('931226.csv' )
df2
캐글출처 : https://www.kaggle.com/code/agileteam/tutorial-t2-2-python