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

2023년6월8일 파이썬공부 - 머신러닝 기초 프로세스

by 착실하게 2023. 6. 8.
반응형
import pandas as pd 
import numpy as np 

X_train = pd.read_csv('data_atype/X_train.csv')
X_test = pd.read_csv('data_atype/X_test.csv')
y_train = pd.read_csv('data_atype/y_train.csv')

# 모델링 및 평가 (분류)
# 머신러닝
# 문제: <=50K 면 0으로 분류, >50K 면 1 으로 분류 하는 문제 

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

# 목표값 확인 
# y_train.head()
print(y_train['income'].value_counts())

# 머신러닝 하려는 대상 컬럼들 결정 
# 간단하게 수치형 데이터 컬럼으로만 해보려고함 
cols = ['age','fnlwgt','education.num','capital.gain','capital.loss','hours.per.week']

#수치형 데이터 통계 확인
# print(X_train.describe()) # id가 포함되어져 나옴 
print(X_train[cols].describe()) # 대상 컬럼들에 대해서만 확인 
# print(X_train.describe(include=object))
# describe 함수의 디폴트 세팅은 object 없이 수치형만 나옴. 이렇게 해줘야 object 만 나옴 
# print(X_train.describe(numeric_only=True)) # describe 에는 numeric_only는 없음 

#결측값
print(X_train[cols].isnull().sum())

#결측치 처리 
X_train = X_train.fillna(0)
X_test = X_test.fillna(0)

#결측치 처리 확인 # null 인 데이터 갯수가 0 인 것을 확인함. 
print(X_train.isnull().sum())
print(X_test.isnull().sum())

# 머신러닝 하기 위해서 
# 문자값을 숫자로 바꾸기 
print(y_train['income'] == '>50K') #조건에 대해 T/F로 결과 
y = (y_train['income'] == '>50K').astype(int) # T/F 결과를 int 로 바꾸었음. True는 1 False 는 0 으로 나타났음

print(y[:3])
print(X_train[cols][:3])

# 머신러닝 모델 시작 
# 이진 분류 문제 - 0 또는 1 분류 
# 분류 문제는 Classifier 필요함. RandomForest로 해보려고함

from sklearn.ensemble import RandomForestClassifier 

model = RandomForestClassifier()
model.fit(X_train[cols],y) # 학습 #train 으로 학슴 
predict = model.predict(X_test[cols]) # 예측 #test에 대해 예측 

print(predict[:10]) # 예측한 결과값 ㅡ> 데이터 프레임으로 만들어서 csv 파일로 생성해야함

print(len(X_train),len(y_train),len(X_test),len(predict))

submit = pd.DataFrame({
  'id': X_test['id'],
  'income' : predict 
})

submit.to_csv('results/20230608_01.csv',index=False)
#index=False라고 적어줘야함. 안적으면 디폴트로 인덱스가 따라들어가니까. 

#어떻게 csv 파일을 만들라고 예시가 주어질 것이다. 그걸 따라 만들면 된다. 

# 평가 (수험자는 알 수 없는 부분임) accuracy 

from sklearn.metrics import accuracy_score

# accuracy_score(#실제결과,#예측한결과)

y_test = pd.read_csv('data_atype/y_test.csv')

# y_test에는 0과 1이 아니라 <50K 등으로 들어가 있어서 0,1과 비교불가능함. 

ans = (y_test['income'] == '>50K').astype(int)

score= accuracy_score(ans, predict)
print(score)

# 실제결과가 주어지지 않기 때문에 모델의 성능을 확인하기 위해서 
# train 에서 일부를 validation 데이터 (검증용 데이터)로 사용하는 것이다.

y = (y_train['income'] == '>50K').astype(int)


from sklearn.model_selection import train_test_split 

X_tr, X_val, y_tr, y_val = train_test_split(X_train,y,test_size = 0.1 , random_state = 2022 ) 
#test_size는 내가 결정하는것. 
# random_state = 데이터 나눌 떄 마다 실행이 다르면, 모델이 좋은지 데이터가 잘 나뉜건지 알수 없음. 그래서 고정시켜주면 된다. 숫자는 뭐가 되었든 상관 없음. 

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

from sklearn.metrics import roc_auc_score

# 0과 1이 아니라 확률 값을 예측 할 떄는 DecisionTreeClassifier()를 사용한다. 

#의사결정나무
from sklearn.tree import DecisionTreeClassifier

model = DecisionTreeClassifier()
model.fit(X_tr[cols],y_tr)
pred = model.predict_proba(X_val[cols]) #확률값 예측 _proba() 

print("DecisionTreeClassifier", pred[:10])
#확신을 가지고 나타낸 결과값. 0일확률100 1일확률 0 이런식으로 나타냄 

score = roc_auc_score(y_val,pred[:,1])
print(score)

# 랜덤포레스트
from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier()
model.fit(X_tr[cols],y_tr)
pred = model.predict_proba(X_val[cols]) #확률값 예측 _proba() 

print("RandomForestClassifier", pred[:10])

score = roc_auc_score(y_val,pred[:,1])
print(score)

# XGBoost 
from xgboost import XGBClassifier 

model = XGBClassifier()
model.fit(X_tr[cols],y_tr)
pred = model.predict_proba(X_val[cols]) #확률값 예측 _proba() 
#train 학습용 으로 fit 한 이후 , 
# test 용으로 pred 해서 
print("XGBClassifier", pred[:10])
# 좀더 확률값같은게 나온다. 
# 1일 확률을 알고 싶은것이므로 
print("XGBClassifier", pred[:,1])


# auc_roc_score 의 결과 3 가지 중에 가장 높은 accuracy 결과를 내놓는 모델로 csv 를 만들어서 제출하면 된다. 
# score 확인 후 xgboost로 골랐다 
score = roc_auc_score(y_val,pred[:,1])
print(score)


#주의점
# (1) 문제에서 요구한 내용이 1일 확률로 구해야함 ~ 그래서 model.predict()가 아니라, model.predict_proba()를 사용한다. 
# (2) train에 대해 학습하고 val로 검증한 y예측값을 y_val로 score 평가했는데, 이제 최종 제출할거는 train이나 val이 아니라, x_test 데이터에 대한 예측임 
# 그래서 아까 학습 시켰던 모델을 사용해서, x_test에 대해 다시 예측만 해주는 것임

pred = model.predict_proba(X_test[cols])
submit = pd.DataFrame({
  'id': X_test['id'],
  'income' : pred[:,1] #1인 확률만 가져가려고 하니까 (0일확률,1일확률) 2개의 컬럼 중 뒤에꺼 1개만 가져옴 
})
submit.to_csv("results/20230608_02.csv",index=False) #제출 


# 분류는 Classifier 
# from sklearn.ensemble import RandomForestClassifier ㅡ 0과 1로 분류 (이진분류)
# from sklearn.tree import DecisionTreeClassifier ㅡ 0과 1이 될 확률 
# from xgboost import XGBClassifier ㅡ 

# from sklearn.metrics import roc_auc_score
# roc_auc_score(실제,예측)
반응형

댓글