□ 교차검증이란 테스트 세트만으로 모델학습의 일반화 정도를 검증하기에 부족하여, 기존 트레이닝세트에서 검증세트를 분리 후 Fold 교차검증을 통해 모델에 대한 학습 일반화를 향상시키는 것.
□ 예제
○ 데이터 호출
import pandas as pd
wine = pd.read_csv("https://bit.ly/wine_csv_data")
○인풋/타깃 데이터 분리
#타깃데이터
target = wine["class"].to_numpy()
#특성데이터
data = wine[["alcohol", "sugar", "pH"]].to_numpy()
print(data.shape)
○트레이닝, 테스트 데이터 나누기
#훈련/테스트 세트 나누기
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) #트레이닝 80% + 테스트 20%
print(f"트레이닝 세트(분리 전) : {train_input.shape}")
○검증세트 나누기
#검증 세트 나누기
sub_input, val_input, sub_target, val_target = train_test_split(train_input, train_target, test_size=0.2, random_state=42)
print(f"트레이닝 세트(분리 후) : {sub_input.shape}")
print(f"검증세트 : {val_input.shape}")
○ 모델생성 : Decision_Tree
#모델생성
from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier(random_state=42)
#학습
dt.fit(sub_input,sub_target)
#점수
print(f"트레이닝 세트 훈련점수 : {dt.score(sub_input,sub_target)}")
print(f"검증 세트 훈련점수 : {dt.score(val_input,val_target)}")
※ k-폴드교차 검증(k-fold cross validation) 훈련세트를 몇 부분으로 나누냐에 따라 다르게 부름.
※ k겹 교차검증.
※ 사이킷런의 cross_validate() 사용.
- fit_time: 모델훈련시간
- score_time: 모델검증시간(스코어를 산출하기위한 시간)
- test_score: 검증폴드점수
from sklearn.model_selection import cross_validate
scores = cross_validate(dt, train_input, train_target)
print(scores)
출력값 |
{'fit_time': array([0.00897694, 0.00814533, 0.00896764, 0.01017714, 0.00892115]), 'score_time': array([0.00099778, 0.00199533, 0.0015521 , 0.00209641, 0.00199223]), 'test_score': array([0.86923077, 0.84615385, 0.87680462, 0.84889317, 0.83541867])} |
import numpy as np
final_k_score = np.mean(scores["test_score"])
print(f"최종 폴드교차검증 점수 : {final_k_score}")
※ cross_validate()은 훈련세트를 섞어 폴드를 나누지않음. 때문에 우리는 앞에서 train_test_split()함수로 전체 데이터를 섞었음.
※ 하지만 교차검증을 할 때 훈련세트를 섞으려면 *분할기*를 사용해야함.
※ 분할기는 교차검증에서 폴드를 어떻게 나눌지결정함.
※ corss_validate은 기본적으로 회귀모델인 경우 KFOLD 분할기 사용, 분류모델일경우 타깃클래스를 골고로 나누기위해 StratifiedKFOLD 사용.
※ 분할기를 사용한 교차검증
※ cross_validate()
※ cv crosvaild는 기본적으로 5개 폴드로 교차검증함
※ 분류모델일때는 StratifiedkFold(), 회귀모델일때는 KFOLD
※ cross_validate 파라미터로는 모델명, 훈련데이터, 훈련타겟데이터, cv인 회귀/분류에 따른 폴드 방식을 지정
from sklearn.model_selection import StratifiedKFold
#cross_validate 파라미터로는 모델명, 훈련데이터, 훈련타겟데이터, cv인 회귀/분류에 따른 폴드 방식을 지정
scores = cross_validate(dt, train_input, train_target, cv=StratifiedKFold())
print(np.mean(scores["test_score"]))
○ 만약 10-폴드교차검증을 하고자할시
splitter = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
scores = cross_validate(dt, train_input, train_target, cv=splitter)
print(np.mean(scores["test_score"]))
○ GridSearchCV : 클래스는 친절하게도 하이퍼파라미터 탐색과 교차검증을 한번에 수행함
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) #모델객체생성 파라미터, 객체모델의 파라미터, CPU코어개수 사숑에 대한 파라미터
gs.fit(train_input,train_target)
dt = gs.best_estimator_
print(dt.score(train_input,train_target))
print(f"min_impurity_decrease : {gs.best_params_}")
print(f'''5번 교차검증 점수 : {gs.cv_results_["mean_test_score"]}''')
print(f'''최종 교차검증 점수 : {np.mean(gs.cv_results_["mean_test_score"])}''')
※ 그리드 서치(Grid Search)와 랜덤 서치(Random Search)는 머신 러닝 모델에서 하이퍼파라미터 튜닝을 위해 사용되는 두 가지 주요 기법임.
▶ 검색 공간 탐색 방식
- 그리드 서치: 사전에 지정된 하이퍼파라미터 조합 그리드를 사용하여 탐색합니다. 이 그리드는 사전에 정의된 값들의 조합으로 구성되며, 각 조합에 대해 교차 검증(Cross-validation) 또는 검증 데이터셋을 사용하여 모델을 평가함.
- 랜덤 서치: 가능한 하이퍼파라미터 공간에서 무작위로 하이퍼파라미터를 선택하여 탐색함. 그리드 서치와 달리 랜덤 서치는 하이퍼파라미터의 값들을 사전에 정의된 그리드로 나열하는 것이 아니라 랜덤하게 선택함.
▶ 하이퍼파라미터 탐색 효율성
- 그리드 서치: 사전에 정의된 그리드에 따라 특정 값들의 조합만을 평가하기 때문에 모든 조합을 검색하기 위해 시간이 많이 소요될 수 있음. 특히 하이퍼파라미터 공간이 크고 가능한 조합이 많을 때 효율성이 낮을 수 있음.
- 랜덤 서치: 랜덤하게 선택된 하이퍼파라미터 조합을 평가하기 때문에 더 빠르게 하이퍼파라미터 공간을 탐색할 수 있습니다. 이는 특히 하이퍼파라미터 공간이 매우 크거나 중요한 하이퍼파라미터가 복수 개일 때 유용함.
▶ 결론 : 모델의 파라메터가 범주형일경우 랜덤서치 적용, 특정 후보 값들을 알고 있다면, 그리드서치 적용
from scipy.stats import uniform, randint
#rgen.rvs(10)는 rgen에서 10개의 난수를 생성. 이는 0부터 9까지의 정수 중에서 무작위로 10개를 선택하여 반환
rgen = randint(0,10)
print(rgen.rvs(10))
print("\n")
print(np.unique(rgen.rvs(1000),return_counts=True))
print("\n")
ugen = uniform(0,1)
print(ugen.rvs(10))
params ={"min_impurity_decrease" : uniform(0.0001,0.001),
"max_depth": randint(20,50),
"min_samples_split":randint(2,25),
"min_samples_leaf":randint(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)
print(dt.score(test_input,test_target))
'Python > 머신러닝+딥러닝 Ⅰ' 카테고리의 다른 글
비지도학습 : 군집 알고리즘 기본 (0) | 2024.03.26 |
---|---|
Ensemble Model (0) | 2024.03.25 |
Decision Tree(결정트리 알고리즘) (0) | 2024.03.22 |
확률적경사하강법 (1) | 2024.03.22 |
Logistic_KNN (0) | 2024.03.22 |