<수행 과정>
1. 데이터 세트 분리 (train/test)
2. 모델 학습 (decision tree)
3. 예측 수행
4. 평가 (정확도)
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd
# 붓꽃 데이터 불러오기
iris = load_iris()
iris_data = iris.data
iris_label = iris.target
print('iris target값:', iris_label)
print('iris target명:', iris.target_names)
# DataFrame으로 변환
iris_df = pd.DataFrame(data=iris_data, columns=iris.feature_names)
iris_df['label'] = iris.target
iris_df.head(3)
# train, test set을 분리
# test_size: test set에 할당되는 데이터의 size를 의미. 여기서는 전체 데이터의 20%를 test data로 사용.
# random_state: 코드를 수행할 때마다 동일한 결과를 나타내기 위해 지정. R에서의 set.seed()와 같은 역할.
X_train, X_test, y_train, y_test = train_test_split(iris_data, iris_label, test_size=0.2, random_state=11)
# ML 알고리즘은 의사 결정 트리 사용
# DecisionTreeClassifier 객체 생성
dt_clf = DecisionTreeClassifier(random_state=11)
# 학습 수행
dt_clf.fit(X_train, y_train)
# 예측 수행
pred = dt_clf.predict(X_test)
# 예측 정확도 계산 (소수점 넷째자리까지)
# 예측 수행 결과 pred와 y_test 값 비교 (붓꽃 품종이 얼마나 일치하는지 확인)
print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test,pred))) #예측 정확도: 0.9333
Estimator: 지도학습의 모든 알고리즘을 구현한 클래스
비지도학습 알고리즘을 구현한 클래스
: 학습/테스트 데이터 세트 분리
: 과적합이라는 문제점을 개선하기 위함
K-fold 교차 검증
: K개의 데이터 폴드 세트를 만들어서 K번 만큼 각 폴드 세트에 학습과 검증 평가를 반복적으로 수행하는 방법
ex. 5-fold 교차 검증
5개의 예측 평가를 구한 거의 평균을 5-fold 평가 결과로 반영
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold
import numpy as np
iris = load_iris()
features = iris.data
label = iris.target
dt_clf = DecisionTreeClassifier(random_state=156)
# 5개의 폴드 세트로 분리하는 KFold 객체 생성
kfold = KFold(n_splits=5)
# 폴드 세트별 정확도를 담을 리스트 객체 생성
cv_accuracy = []
# 전체 붓꽃 데이터 크기
print('붓꽃 데이터 세트 크기:',features.shape[0])
n_iter = 0
# kfold.split(features): 폴드 별 학습용, 검증용 테스트의 로우 '인덱스'를 array로 반환
for train_index, test_index in kfold.split(features):
# 학습용, 검증용 테스트 데이터 추출
X_train, X_test = features[train_index], features[test_index]
y_train, y_test = label[train_index], label[test_index]
#학습 및 예측
dt_clf.fit(X_train , y_train)
pred = dt_clf.predict(X_test)
n_iter += 1
# 반복 시 마다 정확도 측정
accuracy = np.round(accuracy_score(y_test,pred), 4)
train_size = X_train.shape[0]
test_size = X_test.shape[0]
print('\n#{0} 교차 검증 정확도 :{1}, 학습 데이터 크기: {2}, 검증 데이터 크기: {3}'
.format(n_iter, accuracy, train_size, test_size))
print('#{0} 검증 세트 인덱스:{1}'.format(n_iter,test_index))
cv_accuracy.append(accuracy)
# 개별 iteration별 정확도를 합하여 평균 정확도 계산
print('\n## 평균 검증 정확도:', np.mean(cv_accuracy)) #평균 검증 정확도: 0.9
교차 검증을 할 대마다 검증 세트의 인덱스가 달라짐.
Stratified K-fold
: 불균형한 분포도를 가진 레이블(결정 클래스) 데이터 집합을 위한 K-fold 방식
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=3)
n_iter=0
for train_index, test_index in skf.split(iris_df, iris_df['label']):
n_iter += 1
label_train= iris_df['label'].iloc[train_index]
label_test= iris_df['label'].iloc[test_index]
print('## 교차 검증: {0}'.format(n_iter))
print('학습 레이블 데이터 분포:\n', label_train.value_counts())
print('검증 레이블 데이터 분포:\n', label_test.value_counts())
학습 데이터와 검증 데이터 레이블이 동일하게 할당됨.
dt_clf = DecisionTreeClassifier(random_state=156)
skfold = StratifiedKFold(n_splits=3)
n_iter=0
cv_accuracy=[]
# StratifiedKFold의 split( ) 호출시 반드시 레이블 데이터 셋도 추가 입력 필요
for train_index, test_index in skfold.split(features, label):
# 학습용, 검증용 테스트 데이터 추출
X_train, X_test = features[train_index], features[test_index]
y_train, y_test = label[train_index], label[test_index]
#학습 및 예측
dt_clf.fit(X_train , y_train)
pred = dt_clf.predict(X_test)
# 반복 시 마다 정확도 측정
n_iter += 1
accuracy = np.round(accuracy_score(y_test,pred), 4)
train_size = X_train.shape[0]
test_size = X_test.shape[0]
print('\n#{0} 교차 검증 정확도 :{1}, 학습 데이터 크기: {2}, 검증 데이터 크기: {3}'
.format(n_iter, accuracy, train_size, test_size))
print('#{0} 검증 세트 인덱스:{1}'.format(n_iter,test_index))
cv_accuracy.append(accuracy)
# 교차 검증별 정확도 및 평균 정확도 계산
print('\n## 교차 검증별 정확도:', np.round(cv_accuracy, 4))
print('## 평균 검증 정확도:', np.mean(cv_accuracy))
## 평균 정확도: 0.9604
cross_val_score()
: 교차 검증을 편리하게. 위의 과정들을 한 번에 수행.
: 하이퍼 파라미터를 순차적으로 입력하면서 최적의 파라미터를 도출할 수 있는 방안 제공하는 방식
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
# 데이터를 로딩, 학습데이터와 테스트 데이터 분리
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.2, random_state=121)
dtree = DecisionTreeClassifier()
# 하이퍼 파라미터 지정
parameters = {'max_depth':[1,2,3], 'min_samples_split':[2,3]}
# 3-fold
grid_dtree = GridSearchCV(dtree, param_grid=parameters, cv=3, refit=True)
# 하이퍼 파라미터들을 순차적으로 학습 및 평가
grid_dtree.fit(X_train, y_train)
# 최적 하이퍼 파라미터 및 정확도
print('GridSearchCV 최적 파라미터:', grid_dtree.best_params_)
print('GridSearchCV 최고 정확도: {0:.4f}'.format(grid_dtree.best_score_))
총 3x2=6가지의 결과가 도출됨.
# GridSearchCV의 refit으로 이미 학습이 된 estimator 반환
estimator = grid_dtree.best_estimator_
pred = estimator.predict(X_test)
print('테스트 데이터 세트 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))
GridSearchCV 최적 파라미터: {'max_depth': 3, 'min_samples_split': 2}
GridSearchCV 최고 정확도: 0.9667
레이블 인코딩(Label Encoding)
: 카테고리 피처를 코드형 숫자 값으로 변환 (LableEncoder 클래스)
ex. TV, 냉장고, 컴퓨터 (문자형) -> 1, 2, 3 (숫자형)
--> 숫자형이므로 수의 크기가 알고리즘에 작용하여 성능 저하로 이어질 수 있음.
from sklearn.preprocessing import LabelEncoder
items=['TV','냉장고','전자렌지','컴퓨터','선풍기','선풍기','믹서','믹서']
# LabelEncoder를 객체로 생성한 후 , fit( ) 과 transform( ) 으로 label 인코딩 수행.
encoder = LabelEncoder()
encoder.fit(items)
labels = encoder.transform(items)
print('인코딩 변환값:',labels)
원-핫 인코딩 (One-Hot Encoding)
: 새로운 피처를 추가해 고유 값에 해당하는 칼럼에만 1, 나머지 칼럼에는 0을 표시
(1) 문자열 값을 숫자형 값으로 변환 (LableEncoder 클래스)
(2) 입력 값은 2차원 데이터 (변환값.reshape(-1,1))
(3) 원-핫 인코딩 적용( OneHotEncoder 클래스)
# 먼저 숫자값으로 변환을 위해 LabelEncoder로 변환
encoder = LabelEncoder()
encoder.fit(items)
labels = encoder.transform(items)
# 2차원 데이터로 변환
labels = labels.reshape(-1,1)
# 원-핫 인코딩 적용
oh_encoder = OneHotEncoder()
oh_encoder.fit(labels)
oh_labels = oh_encoder.transform(labels)
**get_dummies()를 이용하면 숫자형 변환 없이 바로 가능
df = pd.DataFrame({'item':['TV','냉장고','전자렌지','컴퓨터','선풍기','선풍기','믹서','믹서'] })
pd.get_dummies(df)
피처 스케일링: 서로 다른 변수의 값 범위를 일정한 수준으로 맞추는 작업
표준화: 피처 각각을 N(0,1)인 가우시안 정규분포를 가진 값으로 변환
ex. StandardScaler()
정규화: 서로 다른 피처의 크기를 통일하기 위해 0~1 사이 값으로 변환 (=같은 단위로 변환)
ex. MinMaxScaler(): 0~1, 음수가 있으면 -1~1
scaler = StandardScaler()
scaler.fit(train)
train_scaled = scaler.tansform(train)
#scaler.fit(test) 으로 다시 fit 시키면 test 데이터에 대해 변환이 새롭게 됨
#train으로 fit 시킨 scaler 바로 사용
test_scaled = scaler.transform(test)