본문 바로가기
IT,SW,Data,Cloud,코딩/Python

20230610 파이썬공부 - 작업형2

by 착실하게 2023. 6. 10.
반응형

피쳐엔지니어링들 중에

LabelEncoder 코드는 반복문안에서 적용 

다른것들은 반복문 없이 그냥 한번에 처리 가능 ( MinMaxScaler 등)

그 이유는?  라벨인코딩은 사이킷런에서 한 개의 컬럼 씩 적용하도록 만들어져 있음 

 

# 데이터셋 내용: 백화점 1년 구매 데이터
# cust_id: 고객 ID
# gender: 고객의 성별 (0:여자, 1:남자)
# 고객의 성별 예측값 (남자일 확률)을 CSV 파일로 생성 
# CSV 파일 형식은 cust_id, gender 
# 3500,0.267 과 같은 형태. 파일명은 수험번호.csv 

# 데이터전처리
# Feature Engineering
# 하이퍼파라미터 튜닝 (초매개변수 최적화)
# csv제출(확률값)
# 제출한 모델의 성능은 ROC-AUC 평가지표에 따라 채점. 
###################################

import pandas as pd 
X_train = pd.read_csv('data/X_train.csv',encoding="euc-kr")
y_train = pd.read_csv('data/y_train.csv')
X_test = pd.read_csv('data/X_test.csv',encoding="euc-kr")
print(X_train.head(1))
# 한글 깨짐 현상 관련 에러 처리 ,encoding="euc-kr"

###################################
# EDA

print(X_train.shape, y_train.shape, X_test.shape)
print(X_train.head(3))
print(y_train.head(3))
print(X_test.head(3))

# 만약 시험장 환경이 안 좋아서 모든 컬럼이 다 보이지 않는다면 pandas 에 'display.max_columns' 옵션을 None 으로 설정하면 된다. 
pd.set_option('display.max_columns', None)

# 결측치 확인
print(X_train.isnull().sum())
print(X_test.isnull().sum())
# 결측치 확인 결과, 환불금액 컬럼에만 2295개의 결측치가 있었음

# 기초 통계
print(X_train.describe())

# [Tip] 지수 표현식 (e 사용하는 방식) 말고 익숙한 형태로 보고싶다면 float_format 설정하면 된다. 
# pd.options.display.float_format = '{:.2f}'.format
pd.set_option('display.float_format', '{:.2f}'.format) 
# 이 두가지 코드는 동일한 결과임. 
# {:.2f} 소수점 아래 2째자리 까지 나타냄

print(X_train.describe())
print(X_test.describe())
#데이터를 살펴보았을때, 환불금액의 min이 xx원이면 아마 환불금액의 결측치는 0이 아닐까 생각해보게 된다고 말씀하셨음. 

print(X_train.describe(include=object))
print(X_test.describe(include=object))

# describe함수를 사용해보니, train과 test의 주구매상품 unique 값이 1개 차이가 난다. 그 1개는 뭘까? 

print(X_train['주구매상품'].unique())
print(X_test['주구매상품'].unique())
# 이렇게 unique()를 사용하면 array로 나온다. 
# 그런데 값이 많으면 눈으로 비교하기 어렵다. 

# 이게 뭔지 비교해보는 코드는 set 타입을 활용하면 쉽다. unique() 결과에 set()을 씌워주면 된다. 
a = set(X_train['주구매상품'].unique())
b = set(X_test['주구매상품'].unique())
print(a-b)
print(a.difference(b))
# 이렇게 하면 {'소형가전'} 이라는 결과가 출력된다. 
# 주의점: 위의 코드는 결과가 출력되나, 아래의 코드는 set() 이라고만 나온다. 
# print(b-a)
# print(b.difference(a))

# target(label) 값 확인
# 성비 어떤지 
print(y_train['gender'].value_counts())

###################################
# 데이터 전처리

# (1) 환불금액 결측치 0으로 채움
# X_train = X_train.fillna(0) #이렇게 해도 됨
X_train['환불금액'] = X_train['환불금액'].fillna(0)
X_test['환불금액'] = X_test['환불금액'].fillna(0)
# print(X_train.isnull().sum())

# (2) train의 id 컬럼은 삭제하고, test의 id 값은 csv파일 생성시 필요하므로 옮겨놓음.
X_train = X_train.drop(['cust_id'],axis=1)
cust_id = X_test.pop('cust_id')


###################################
# 피쳐 엔지니어링

# LabelEncoder 
from sklearn.preprocessing import LabelEncoder 

cols = ['주구매상품','주구매지점']
encoder = LabelEncoder()
for col in cols:
  X_train[col] = encoder.fit_transform(X_train[col])
  X_test[col] = encoder.transform(X_test[col])

print(X_train.head(3))
print(X_test.head(3))

# MinMaxScaler
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
cols = ['총구매액','최대구매액','환불금액']
X_train[cols]=scaler.fit_transform(X_train[cols])
X_test[cols]=scaler.transform(X_test[cols])
#Encoder는 반복문으로 해줬는데, MinMaxScaler는 그냥 한번에 해줘야 에러가 안 난다. 반복문 써줬다가 에러 났었음. 

###################################
# 데이터 분리
# Train데이터로 train용, validation용을 분리

from sklearn.model_selection import train_test_split

X_tr, X_val, y_tr, y_val = train_test_split(X_train, y_train, random_state=2022,test_size=0.2)

print(X_tr.shape, X_val.shape, y_tr.shape, y_val.shape)

# test_size 디폴트는 0.25 이다. 

###################################
# 모델링 & 하이퍼파라미터 튜닝 & 앙상블
from sklearn.ensemble import RandomForestClassifier 

model=RandomForestClassifier()
# model=RandomForestClassifier(random_state=2022)
model.fit(X_tr,y_tr)
pred = model.predict_proba(X_val)

###################################
# 평가
# validation dataset으로 평가
from sklearn.metrics import roc_auc_score
print(roc_auc_score(y_val, pred[:1]))


###################################
# 예측 및 제출
# test 데이터 예측
pred = model.predict_proba(X_test)
submit = pd.DataFrame({
  'cust_id' : cust_id,
  'gender' : pred[:,1]
})
submit.to_csv('data/20230610_02.csv',index=False)

# 문제의 안내사항을 확인하고, index=False해야하는경우 놓치지말고 해주기!
반응형

댓글