======================== 05-1 결정트리 ========================
import pandas as pd
wine = pd.read_csv('https://bit.ly/wine_csv_data')
wine.head()
# 열의 데이터타입과 누락된 데이터 확인
wine.info()
# 열에 대한 간단한 통계 출력
wine.describe()
# 데이터프레임을 넘파이 배열로 변환
data = wine[['alcohol','sugar','pH']].to_numpy()
target = wine['class'].to_numpy()
# 사이킷런을 통해 훈련세트와 테스트세트 분류
# test_size=0.2 : 20%를 테스트 세트로 지정
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2 ,random_state=42)
# 훈련세트, 테스트세트 데이터 수,열의 수 확인
print(train_input.shape, test_input.shape)
# 훈련세트 특성표준화 전처리
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)
로지스틱 회귀 모델 훈련
# 로지스틱 회귀 모델 훈련
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(train_scaled, train_target)
print(lr.score(train_scaled, train_target)) # 훈련세트
print(lr.score(test_scaled, test_target)) # 테스트세트
#훈련세트와 테스트세트 점수가 낮다 : 과소적합
# 로지스틱 회귀모델 계수와 절편
print(lr.coef_, lr.intercept_)
결정트리 모델 훈련
# 결정트리 모델 훈련
from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier()
dt.fit(train_scaled, train_target)
print(dt.score(train_scaled, train_target)) # 훈련세트
print(dt.score(test_scaled, test_target)) # 테스트세트
# 결정트리 모델 시각화
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(10,7))
plot_tree(dt)
plt.show()
# 트리의 깊이를 제한해서 출력
plt.figure(figsize=(10,7))
plot_tree(dt, max_depth=1, filled=True, feature_names=['alcohol','sugar','pH'])
plt.show()
# 루트노드 아래로 최대 3개 노드까지만 성장
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(train_scaled, train_target)
print(dt.score(train_scaled, train_target)) # 훈련세트
print(dt.score(test_scaled, test_target)) # 테스트세트
plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol','sugar','pH'])
plt.show()
# 결정트리는 표준화 전처리 과정이 필요없다.
# 루트노드 아래로 최대 3개 노드까지만 성장
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(train_scaled, train_target)
print(dt.score(train_input, train_target)) # 훈련세트
print(dt.score(test_input, test_target)) # 테스트세트
plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol','sugar','pH'])
plt.show()
print(dt.feature_importances_)
====================== 05-2 교차 검증과 그리드 서치 ======================
# Wine데이터 준비
import pandas as pd
wine = pd.read_csv('https://bit.ly/wine_csv_data')
wine.head()
# class열을 타깃으로 사용
# 나머지 열은 특성 배열에 저장
data = wine[['alcohol','sugar','pH']].to_numpy()
target = wine['class'].to_numpy()
# 사이킷런을 통해 훈련세트와 테스트세트 분류
# test_size=0.2 : 20%를 테스트 세트로 지정
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2,random_state=42)
print('train_input :',train_input.shape,'\n',train_input,'\n','test_input :',test_input.shape,'\n',test_input)
# train set을 다시 훈련세트와 검증세트로 나눔
sub_input, val_input, sub_target, val_target = train_test_split(train_input, train_target, test_size=0.2,random_state=42)
# 훈련세트와 검증세트 크기 확인
print('sub_input :',sub_input.shape,'\n',sub_input,'\n','val_input :',val_input.shape,'\n',val_input)
# 결정트리 모델 훈련
from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier(random_state=42)
dt.fit(sub_input, sub_target)
# 훈련결과 : 과대적합
print(dt.score(sub_input, sub_target)) # 훈련세트
print(dt.score(val_input, val_target)) # 테스트세트
# 교차 검증
from sklearn.model_selection import cross_validate
# cross_validate() : fit_time, score_time, test_score키를 가진 딕셔너리 반환
scores = cross_validate(dt, train_input, train_target)
# fit_time : 모델을 훈련하는 시간
print('fit_time(모델을 훈련하는 시간) : ',scores['fit_time'])
# score_time : 모델을 검증하는 시간
print('score_time(모델을 검증하는 시간) : ',scores['score_time'])
# test_score : 교차 검증의 최종점수
print('test_score(교차 검증의 최종점수) : ',scores['test_score'])
# 교차 검증 점수
import numpy as np
print(np.mean(scores['test_score']))
from sklearn.model_selection import StratifiedKFold
score = cross_validate(dt, train_input, train_target, cv=StratifiedKFold())
print(np.mean(score['test_score']))
#훈련세트 섞은 후 교차검증
splitter = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
sclre = cross_validate(dt, train_input,train_target, cv=splitter)
print(np.mean(score['test_score']))
# 그리드 서치
# 0.0001 부터 0.0005까지 0.0001씩 증가하는 5개값으로 시도
from sklearn.model_selection import GridSearchCV
params = {'min_impurity_decrease' : [0.0001, 0.0002, 0.0003, 0.0004, 0.0005]}
gs = GridSearchCV(DecisionTreeClassifier(random_state=42), params, n_jobs=-1)
gs.fit(train_input, train_target)
dt = gs.best_estimator_
print(dt.score(train_input, train_target))
print(gs.best_params_)
print(gs.cv_results_['mean_test_score'])
best_index = np.argmax(gs.cv_results_['mean_test_score'])
print(gs.cv_results_['params'][best_index])
params = {'min_impurity_decrease':np.arange(0.0001, 0.001, 0.0001),
'max_depth':range(5, 20, 1),
'min_samples_split':range(2,100,10)}
gs = GridSearchCV(DecisionTreeClassifier(random_state=42), params, n_jobs=-1)
gs.fit(train_input, train_target)
print(gs.best_params_)
print(np.max(gs.cv_results_['mean_test_score']))
from scipy.stats import uniform, randint
rgen = randint(0,10)
rgen.rvs(10)
np.unique(rgen.rvs(1000), return_counts=True)
ugen = uniform(0,1)
ugen.rvs(10)
params = {'min_impurity_decrease':np.arange(0.0001, 0.001),
'max_depth':range(20, 50),
'min_samples_split':range(2,25),
'min_samples_leaf':range(1,25)}
from sklearn.model_selection import RandomizedSearchCV
gs = RandomizedSearchCV(DecisionTreeClassifier(random_state=42), params, n_iter=100, n_jobs=-1, random_state=42)
gs.fit(train_input, train_target)
print(gs.best_params_)
print(np.max(gs.cv_results_['mean_test_score']))
dt = gs.best_estimator_
print(dt.score(test_input, test_target))
====================== 05-3 트리의 앙상블 ======================
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
wine = pd.read_csv('https://bit.ly/wine_csv_data')
print('Wine Data \n',wine.head(),'\n\n')
data = wine[['alcohol','sugar','pH']].to_numpy()
print("alcohol, sugar, pH를 numpy배열로 변환 후 data에 저장 \n",data.shape,'\n',data,'\n\n')
target = wine['class'].to_numpy()
print("class를 numpy배열로 변환 후 target에 저장 :",target.shape,'\n',target,'\n\n')
print("sklearn을 이용하여 data와 target을 train, test세트 분류\n")
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2,random_state=42)
print('train_input :',train_input.shape,'\n',train_input,'\n','test_input :',test_input.shape,'\n',test_input,'\n\n')
# 랜덤포레스트
print("랜덤포레스트를 이용한 교차 검증 점수 확인")
from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(rf, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']),'\n\n')
rf.fit(train_input, train_target)
print('랜덤 포레스트 모델을 훈련한 train세트의 특성 중요도\n alcohol, sugar, pH\n',rf.feature_importances_,'\n당도점수가 높다\n\n ')
print("train세트로 훈련하여 OOB 점수 출력...")
rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_input, train_target)
print("OOB SCORE :",rf.oob_score_,'\n\n')
# 엑스트라 트리
print("엑스트라 트리로 모델 교차 검증 점수 확인 ")
from sklearn.ensemble import ExtraTreesClassifier
et = ExtraTreesClassifier(n_jobs=-1, random_state=42)
score = cross_validate(et, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']),np.mean(scores['test_score']),'\n\n')
print("엑스트라 트리로 훈련한 train세트의 특성 중요도\n alcohol, sugar, pH")
et.fit(train_input, train_target)
print(et.feature_importances_)
# 그라이언트 부스팅
print("그레이디언트 부스팅을 이용해 와인 데이터셋의 교차 검증 점수 확인")
from sklearn.ensemble import GradientBoostingClassifier
gb = GradientBoostingClassifier(random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']),'\n\n')
print("성능향상을 위해 학습률증가 및 트리개수 증가 후 점수 확인")
gb = GradientBoostingClassifier(n_estimators=500, learning_rate=0.2,random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']),'\n\n')
print("그레이디언트 부스팅으로 훈련한 train세트의 특성 중요도\n alcohol, sugar, pH")
gb.fit(train_input, train_target)
print(gb.feature_importances_,'\n\n')
# 히스토그램 기반 그레이디언트 부스팅
print("히스토그램 기반 그레이디언트 부스팅을 이용한 검증점수 확인")
from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier
hgb = HistGradientBoostingClassifier(random_state=42)
scores = cross_validate(hgb, train_input, train_target, return_train_score=True)
print(np.mean(scores['train_score']), np.mean(scores['test_score']),'\n\n')
print("히스토그램 기반 그레이디언트 부스팅으로 훈련한 train세트의 특성 중요도\n alcohol, sugar, pH")
from sklearn.inspection import permutation_importance
hgb.fit(train_input, train_target)
result = permutation_importance(hgb, train_input, train_target, n_repeats=10, random_state=42, n_jobs=-1)
print(result.importances_mean,'\n\n')
print("히스토그램 기반 그레이디언트 부스팅으로 훈련한 test세트의 특성 중요도\n alcohol, sugar, pH")
result = permutation_importance(hgb, test_input, test_target, n_repeats=10, random_state=42, n_jobs=-1)
print(result.importances_mean,'\n\n')
print("테스트세트의 성능 최종 확인")
hgb.score(test_input, test_target)
print("XGBoost를 사용해 와인 데이터의 교차 검증 점수 확인")
from xgboost import XGBClassifier
xgb = XGBClassifier(tree_method='hist', random_state=42)
scores = cross_validate(xgb, train_input, train_target, return_train_score=True)
print(np.mean(scores['train_score']), np.mean(scores['test_score']),'\n\n')
print("LightGBM를 사용해 와인 데이터의 교차 검증 점수 확인")
from lightgbm import LGBMClassifier
lgb = LGBMClassifier(random_state=42)
scores = cross_validate(lgb, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']),'\n\n')
Wine Data
alcohol sugar pH class
0 9.4 1.9 3.51 0.0
1 9.8 2.6 3.20 0.0
2 9.8 2.3 3.26 0.0
3 9.8 1.9 3.16 0.0
4 9.4 1.9 3.51 0.0
alcohol, sugar, pH를 numpy배열로 변환 후 data에 저장
(6497, 3)
[[ 9.4 1.9 3.51]
[ 9.8 2.6 3.2 ]
[ 9.8 2.3 3.26]
...
[ 9.4 1.2 2.99]
[12.8 1.1 3.34]
[11.8 0.8 3.26]]
class를 numpy배열로 변환 후 target에 저장 : (6497,)
[0. 0. 0. ... 1. 1. 1.]
sklearn을 이용하여 data와 target을 train, test세트 분류
train_input : (5197, 3)
[[10.5 7.7 3.19]
[12.4 2.1 3.26]
[11.8 2.1 3.41]
...
[ 9.5 5.6 3.24]
[ 9.5 8. 3.18]
[ 9.5 2.7 3.51]]
test_input : (1300, 3)
[[12.2 12.8 3.26]
[ 9.9 2.2 3.27]
[12. 7.4 3.18]
...
[12.4 1.8 3.19]
[ 9.4 9.7 3.3 ]
[ 8.7 15.5 2.9 ]]
랜덤포레스트를 이용한 교차 검증 점수 확인
0.9973541965122431 0.8905151032797809
랜덤 포레스트 모델을 훈련한 train세트의 특성 중요도
alcohol, sugar, pH
[0.23167441 0.50039841 0.26792718]
당도점수가 높다
train세트로 훈련하여 OOB 점수 출력...
OOB SCORE : 0.8934000384837406
엑스트라 트리로 모델 교차 검증 점수 확인
0.9973541965122431 0.8905151032797809
엑스트라 트리로 훈련한 train세트의 특성 중요도
alcohol, sugar, pH
[0.20183568 0.52242907 0.27573525]
그레이디언트 부스팅을 이용해 와인 데이터셋의 교차 검증 점수 확인
0.8881086892152563 0.8720430147331015
성능향상을 위해 학습률증가 및 트리개수 증가 후 점수 확인
0.9464595437171814 0.8780082549788999
그레이디언트 부스팅으로 훈련한 train세트의 특성 중요도
alcohol, sugar, pH
[0.15872278 0.68010884 0.16116839]
히스토그램 기반 그레이디언트 부스팅을 이용한 검증점수 확인
0.9321723946453317 0.8801241948619236
히스토그램 기반 그레이디언트 부스팅으로 훈련한 train세트의 특성 중요도
alcohol, sugar, pH
[0.08876275 0.23438522 0.08027708]
히스토그램 기반 그레이디언트 부스팅으로 훈련한 test세트의 특성 중요도
alcohol, sugar, pH
[0.05969231 0.20238462 0.049 ]
테스트세트의 성능 최종 확인
XGBoost를 사용해 와인 데이터의 교차 검증 점수 확인
0.8824322471423747 0.8726214185237284
LightGBM를 사용해 와인 데이터의 교차 검증 점수 확인
0.9338079582727165 0.8789710890649293