from sklearn.datasets import load_iris X, y = load_iris(return_X_y=True) # data와 target값만 추출(X, y) X.shape, y.shape((150, 4), (150,))
# Train/Test set 분리 from sklearn.model_selection import train_test_split # X, y -> 3개 dataset으로 분리 ## train_test_split() -> 2개 dataset으로 분리 X_train, X_test, y_train, y_test = train_test_split( X, y, # input, output test_size=0.2, # testset의 비율. default:0.25 stratify=y, # 분류 데이터셋에만 적용. (y(target)이 범주형) 원본 클래스들 비율과 동일한 비율로 나누기. random_state=0 # random seed값. ) X_train.shape, X_test.shape((120, 4), (30, 4))
# Train/Validation/Test set 분리 ### Train set을 두개로 나눠서 하나는 train, 다른 하나는 validation set으로 사용. X_train, X_val, y_train, y_val = train_test_split( X_train, y_train, test_size=0.2, stratify=y_train, # stratify=output(y값, target, label) 지정. random_state=0) X_train.shape, X_test.shape, X_val.shape((96, 4), (30, 4), (24, 4))
from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score # 모델 생성 max_depth = 4 # 하이퍼파라미터 - 사람이 지정하는 설정값. (모델 성능에 영향을 줌.) -> 어떻게 모델이 데이터를 학습할지 설정. tree = DecisionTreeClassifier(max_depth=max_depth, random_state=0) # 모델 학습 -trainset tree.fit(X_train, y_train) # 모델 검증 - validationset/trainset ## 1. 예측(추론) pred_train = tree.predict(X_train) pred_val = tree.predict(X_val) ## 2. 평가(검증) ==> accuracy train_acc = accuracy_score(y_train, pred_train) val_acc = accuracy_score(y_val, pred_val)# max_depth = 1 print(f"max_depth: {max_depth}") print("Train accuracy:", train_acc) print("Validation accuracy:", val_acc)max_depth: 1
Train accuracy: 0.6666666666666666
Validation accuracy: 0.6666666666666666# max_depth = 3 print(f"max_depth: {max_depth}") print("Train accuracy:", train_acc) print("Validation accuracy:", val_acc)max_depth: 3
Train accuracy: 0.9583333333333334
Validation accuracy: 0.9583333333333334
# Testset으로 최종평가 ## max_depth = 2 모델로 최종평가 model = DecisionTreeClassifier(max_depth=2, random_state=0) model.fit(X_train, y_train) pred = model.predict(X_test) test_acc = accuracy_score(y_test, pred) print("최종평가 결과:", test_acc)최종 평가결과: 0.9333333333333333

- Generator란
- 연속된 값을 제공(생성)하는 객체. 연속된 값을 한번에 메모리에 저장하지 않고 필요시마다 순서대로 하나씩 제공한다.
- 함수형식으로 구현하며 return 대신 yield를 사용한다.
import pandas as pd import numpy as np df = pd.read_csv("data/boston_housing.csv") print(df.shape) df.head()(506, 14)
# X, y 를 분리 y = df['MEDV'].values X = df.drop(columns="MEDV").values ## DataFrame/Series.values -> ndarray 변환X.shape(), y.shape()((506, 13), (506,))
# KFold - 회귀용. K개의 fold로 나누는데 순서대로 나눈다. from sklearn.model_selection import KFold # 객체 생성 - k를 지정 kfold = KFold(n_splits=5) # K=5 - 8 : 2 , K=4 - 7.5 : 2.5 # X(input)을 넣어서 나누기 # K개 fold로 나눴을 때 train 데이터와 test 데이터의 index를 반환하는 generator를 반환 gen = kfold.split(X) # generator제공 값을 받기 -> for in 문 사용. next(generator) - 한개씩 반환받기.next(gen)
from sklearn.model_selection import KFold from sklearn.tree import DecisionTreeRegressor # DecisionTree 회귀 모델 from sklearn.metrics import mean_squared_error # 오차제곱평균.(회귀 지표중 하나) import numpy as np # dataset: X, y mse_list = [] kfold = KFold(n_splits=5) gen = kfold.next(X) for train_idx, test_idx in gen : X_train, y_train = X[train_idx], y[train_idx] X_test, y_test = X[test_idx], y[test_idx] # 모델생성 model = DecisionTreeRegressor(max_depth=2, random_state=0) # 학습 model.fit(X_train, y_train) # 검증 pred = model.predict(X_test) mse = mean_squared_error(y_test, pred) mse_list.append(mse)mse_list[19.362900914277557,
25.77734700471067,
58.61675649857523,
63.188138857997195,
41.21802825033429]
from sklearn.datasets import load_iris from sklearn.model_selection import StratifiedKFold from sklearn.tree import DecisionTreeClassified from sklearn.metrics import accuracy_score X, y = load_iris(return_X_y=True)# k를 지정해서 객체생성 s_kfold = StratifiedKFold(n_splits=4) # 나누기 s_gen = s_kfold.splits(X, y) # input, output data 모두 제공 # next(): 제네레이터를 호출할 때 사용하는 함수. 다음 폴드의 train_idx, valid_idx를 가져와서 가져온 인덱스를 사용하여 데이터를 나눔. train_idx, valid_idx = next(s_gen) # fold별 검증 결과를 저장할 리스트 val_result = [] for train_idx, valid_idx in s_gen : # data 추출 X_train, y_train = X[train_idx], y[train_idx] X_test, y_test = X[test_idx], y[test_idx] # 모델링 ## 모델 생성 model = DecisionTreeClassifier(max_depth=4, random_state=0) # 학습 model.fit(X_train, y_train) ## 검증 pred = model.predict(X_test) val_result.append(accuracy_score(y_test, pred))# 가장 validation 결과가 좋은 하이퍼 파라미터로 모델을 만들어서 다시 학습. final_model = DecisionTreeClassifier(max_depth=3, random_state=0) final_modle.fit(X, y)
평가지표: https://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter
## Boston Dataset import pandas as pd df = pd.read_csv('data/boston_hosing.csv') y = df['MEDV'].values X = df.drop(columns="MEDV").values X.shape, y.shape## train/test set 분리 (최종 평가를 위해서) from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)## cross validation(교차검증) - cross_val_score() 이용 from sklearn.model_selection import cross_val_score() from sklearn.tree import DecisionTreeRegressor model = DecisionTreeRegressor(max_depth=2, random_state=0) val_results = cross_val_score( estimator=model, # 교차검증할 모델 X=X_train, # X-input, features y=y_train, # y-output, target, label scoring="neg_mean_squared_error", # 평가지표함수-문자열, 함수객체 cv=4, # fold 수 ) print(val_results) print(-val_results)[-25.325642 -25.07376354 -42.7879561 -42.4207859 ][25.325642 25.07376354 42.7879561 42.4207859 ]
### 모델링 - 하이퍼파라미터 튜닝을 통해서 가장 성능 좋은 모델을 찾기. ## 하이퍼 파라미터: max_depth max_depth_list = [1, 2, 3, 4, 5] # max_depth별 모델의 검증 결과를 저장할 딕셔너리. key: max_depth, scores, mean_score results = {"max_depth":[], "scores":[], "mean_score":[]} for max_depth in max_depth_list : model = DecisionTreeRegressor(max_depth=max_depth, random_state=0) # 교차검증을 이용해 성능 평가 scores = cross_val_score(estimator=model, X=X_train, y=y_train, scoring="neg_mean_squared_error", cv=4) # 결과 dicitionary에 저장 results['max_depth'].append(max_depth) results['scores'].append(scores) results['mean_score'].append(np.mean(scores))results{'max_depth': [1, 2, 3, 4, 5],
'scores': [array([-45.89379405, -40.67507482, -71.05002262, -55.33355572]),
array([-25.325642 , -25.07376354, -42.7879561 , -42.4207859 ]),
array([-15.89637347, -24.77699693, -49.78552275, -25.01324593]),
array([-12.560709 , -16.50424255, -49.41891582, -20.55564482]),
array([-11.13574744, -18.13445467, -52.99608118, -14.40992532])],
'mean_score': [-53.23811180112813,
-33.90203688337762,
-28.868034772038833,
-24.759878046646527,
-24.169052153115132]}results['mean_score'][-53.23811180112813,
-33.90203688337762,
-28.868034772038833,
-24.759878046646527,
-24.169052153115132]# mse 결과에 -를 붙이는 이유 ## scikit-learn은 평가 결과값이 클수록 성능이 더 좋은 모델이라고 처리한다. ## 그런데 MSE 의 경우는 낮을 수록 더 좋은 모델이다. ## 그래서 음수를 붙어서 클수록 좋은 성능이 되도록 하는 scikit-learn 방식에 맞춘다. # sorted(results["mean_score"], reverse=True)[0]####### max_depth가 5일 때 검증결과가 가장 좋음. ### 최종 모델을 max_depth=5 해서 만들고 학습. best_model = DecisionTreeRegressor(max_depth=max_depth, random_state=0) best_model.fit(X_train, y_train)## test set으로 최종 평가 from sklearn.metrics import mean_squared_error pred_test = best_model.predict(X_test) mean_squared_error(y_test, pred_test)32.0407432413041
## 회귀 평가지표 - mse, r-square from sklearn.model_selection import cross_validate, cross_val_score, KFold, StratifiedKFold, train_test_split model2 = DecisionTreeRegressor(max_depth=5) result_dict = cross_validate( estimator=model2, # 모델지정 X=X_train, y=y_train, # input/output dataset 지정 scoring=["neg_mean_squared_error", "r2", "neg_mean_absolute_error"], cv=4 )result_dict.keys() # 'fit_time' : 학습할때 걸린 시간 #'score_time': 검증할 때 걸린 시간 # 'test_neg_mean_squared_error', 'test_r2' : 검증 결과dict_keys(['fit_time', 'score_time', 'test_neg_mean_squared_error', 'test_r2', 'test_neg_mean_absolute_error'])
result_dict{'fit_time': array([0.00296092, 0.00248003, 0.00167894, 0.00161195]),
'score_time': array([0.00116014, 0.00075698, 0.00066113, 0.0005331 ]),
'test_neg_mean_squared_error': array([-11.17146312, -17.23712794, -55.94892177, -15.48784611]),
'test_r2': array([0.86707836, 0.73043523, 0.36438976, 0.85004633]),
'test_neg_mean_absolute_error': array([-2.61823906, -2.96319701, -3.96487468, -2.70686402])}