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

2023년6월9일 머신러닝-Regression

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

 

 

import pandas as pd 
import numpy as np

# 보험료 예측. RMSE 로 평가. CSV는 ID과 예측값. 

train = pd.read_csv('insurance/train.csv')
test = pd.read_csv('insurance/test.csv')

print(train.shape, test.shape)

print(train.head(3))
print(test.head(3))

print(train.isnull().sum())
print(test.isnull().sum())

#train,test 둘다 결측치가 없음. 
############################################

#기초 통계값 확인 후 이상치 처리 

print(train.describe())
print(train.describe(include=object))
print(test.describe())
print(test.describe(include=object))

#region 종류가 test와 train이 동일하다. 
#이상치도 눈에 띄는 것은 없음.
############################################
# categorical data 가 2개, 2개, 4개 정도여서 원핫인코딩 처리 하려고함
print(train.head(1))
# cols = ['sex','smoker','region'] #이렇게 써도 됨
cols = train.select_dtypes(include=object) 
print(cols) # object 타입의 데이터 프레임이 생긴다. 

cols = train.select_dtypes(include=object).columns
print(cols)

#원핫인코딩 수행
train = pd.get_dummies(train,columns=cols)
test = pd.get_dummies(test,columns=cols)

print(train.head())
print(test.head())
############################################

# (2) 돌아와서 다시 살펴보기. 뭔가 더 할것은 없는지?
# 스케일링을 해보자

# from sklearn.preprocessing import StandardScaler 
# scaler = StandardScaler()

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()

# cols = ['age','bmi']
cols = ['bmi']
train[cols] = scaler.fit_transform(train[cols])
test[cols] = scaler.transform(test[cols])
print("scaler================")
print(train[cols].head())
print(test[cols].head())


############################################

# 또 어떤 것을 해서 더 최적화 시킬 수 있을지 생각 해보기.
# charges 값을 보니, 분포가 굉장히 큼. charge 값에 로그를 씌워서 다시 머신러닝을 해보기로함.

# train['charges'].hist() #matplotlib #왼쪽에 치우침
train['charges'] = np.log1p(train['charges'])
# train['charges'].hist() #matplotlib # 정규분포스럽게 바뀜


############################################

# train dataset에 원핫인코딩 먼저 수행한 후, validation data 분리해야함. 

from sklearn.model_selection import train_test_split 

X_tr, X_val, y_tr, y_val = train_test_split( train.drop('charges',axis=1), train['charges'], test_size = 0.15, random_state=2022)

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

print(X_tr.head(1))
print(y_tr.head(1))


############################################
# sklearn.metrics 에서 accuracy_score, roc_auc_score는 지원을 해준다. RMSE는 지원이 안되고 MSE는 지원이 된다. RMSE는 MSE에 root를 씌워주면 된다. 
# root를 씌우려면 numpy 필요함. np.sqrt(n) 

from sklearn.metrics import mean_squared_error
# import numpy as np 

def rmse(y_test, pred):
  return np.sqrt(mean_squared_error(y_test,pred))

# y_test는 실제값, pred 는 예측한 값. 
# 예측한 값이 실제 값과 얼마나 맞는지 평가하는 지표. rmse. 

# 회귀 분석 여러종류 해보고, 어느 분석이 가장 나은지 선택. 
############################################
# LinearRegression 
from sklearn.linear_model import LinearRegression 

model = LinearRegression()
model.fit(X_tr, y_tr)
pred = model.predict(X_val)
# print(rmse(y_val,pred))
print(rmse(np.exp(y_val),np.exp(pred)))

# 모델 선택, 훈련, 평가, 이후에 다시 살펴보기. 전처리? 피쳐엔지니어링? 반복하면서 데이터를 다듬어봐라. 
# 실행시키기 전에 맨 처음의 rmse를 다시 저장해두어라. 베이스라인으로 메모해두기. 
#Scaler를 위에다가 추가해본 후, 다시 rmse를 구해서 베이스라인rmse와 비교. #어떤 스케일러 썼을 때 값이 뭔지 적어두기.

# 5888 베이스라인
# 5888 StandardScaler ( age, bmi 2개 컬럼 적용)
# 5888 MinMaxScaler ( age, bmi 2개 컬럼 적용)
# 5888 MinMaxScaler (bmi 컬럼 1개 적용)
# train['charges']에 np.log1p를 적용한 이후에 rmse 구할때는 np.exp를 씌워줘야한다. print(rmse(np.exp(y_val),np.exp(pred)))
# 8258 MinMaxScaler (bmi컬럼 1개 적용), np.log1p(['charges']) 적용

############################################
# RandomForestRegressor 로도 해보기.
from sklearn.ensemble import RandomForestRegressor 
model = RandomForestRegressor() 
model.fit(X_tr,y_tr)
pred = model.predict(X_val)
# print(rmse(y_val,pred))
print(rmse(np.exp(y_val),np.exp(pred)))

# RMSE 는 값이 커지면 에러값이 커진거라서 안 좋음. 

# 4722 베이스라인
# 4785 StandardScaler ( age, bmi 2개 컬럼 적용)
# 4762 MinMaxScaler ( age, bmi 2개 컬럼 적용)
# 4705 MinMaxScaler (bmi 컬럼 1개 적용)
# 4675,4566,4612 MinMaxScaler (bmi컬럼 1개 적용), np.log1p(['charges']) 적용

############################################
# 머신러닝모델마다 효과있는 전처리가 다르다. 

# 랜덤포레스트는 어디서든 잘 통한다. 시험때 쓰기 좋다. 
# XGBoost는 파라메터 튜닝을 조금 공부해야 좋다. 
# XGBoost는 파라메터를 안써주면 warning이 뜰수도 있다. warning이 걱정된다면 그냥 RandomForestRegressor를 쓰는 것도 좋은 선택지가 될 수 있다.

############################################
from xgboost import XGBRegressor 
model = XGBRegressor(objective='reg:squarederror')
model.fit(X_tr,y_tr)
pred = model.predict(X_val)
print(rmse(np.exp(y_val),np.exp(pred)))
# 6025 MinMaxScaler (bmi컬럼 1개 적용), np.log1p(['charges']) 적용
print("xgboost End===")
############################################
#lightgbm 
#분류: model = lgb.LGBMClassifier()
#회귀: model = lgb.LGBMRegressor()
from sklearn import lightgbm as lgb 
model = lgb.LGBMRegressor()
model.fit(X_tr,y_tr)
y_pred= model.predict(X_val)
print(rmse(np.exp(y_val),np.exp(pred)))
# 6025 MinMaxScaler (bmi컬럼 1개 적용), np.log1p(['charges']) 적용

############################################
# test 데이터 예측 
# 모델들 중에 제일 성능이 좋은 것을 선택하고, 나머지는 주석처리한다. 
pred = model.predict(test)
submit = pd.DataFrame({
# csv: id, 예측값 적으라는 지시문구에 따라 작성
  'id':test['id'],
  'charges': np.exp(pred) #log해준뒤니까 exp해줘야함 
})
submit.to_csv('insurance/20230610_01.csv',index=False)

print("==End===")
#원래라면 여기서 끝나는데, 우리는 실제값을 아니까 평가를해본다. 
y_test = pd.read_csv('insurance/y_test.csv')
print(rmse(y_test['charges'],np.exp(pred)))

 

 

 

 

 

반응형

댓글