사이킷런?
지도학습
- fit() : ML 모델 학습
- predict() : 학습된 모델의 예측
- 위의 두 함수를 활용, 다양한 분류(Classifier), 회귀(Regressor) 문제 해결 가능
- Estimator 클래스 : Classifier() + Regressor()
비지도학습
- 차원 축소, 클러스터링, 피처 추출
- fit() : 지도학습과 다르게 데이터의 구조 변환
- transform() : 실제 작업
- fit_transform() : fit() + transform() (하지만 사용에 주의가 필요하다.)
사이킷런 주요 모듈
분류 | 모듈명 |
예제 데이터 | sklearn.datasets |
피처 처리 | sklearn.preprocessing sklearn.feature_selection sklearn.feature_extraction |
유틸리티 | sklearn.pipeline |
피처 처리 & 차원 축소 | sklearn.decomposition |
데이터 분리, 검증 & 파라미터 튜닝 | sklearn.model_selection |
평가 | sklearn.metrics |
ML 알고리즘 | sklearn.ensemble sklearn.linear_model sklearn.naive_bayes sklearn.neighbors sklearn.svm sklearn.tree sklearn.cluster |
예제
목표 : 붓꽃 데이터 세트로 붓꽃의 품종 분류
(붓꽃 데이터 셋 : 꽃잎의 길이, 너비, 꽃받침의 길이, 너비)
분류(Classification)
- 지도학습(label 데이터로 모델 학습 후 미지의 label 예측, 주어진 데이터 학습 후 미지의 데이터 예측)
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
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_split
X_train, x_test, y_train, y_test = train_test_split(iris_data, iris_label, test_size = 0.2, random_state=42)
의사결정나무 모델 활용, 예측
from sklearn.metrics import accuracy_score
dt_clf = DecisionTreeClassifier(random_state = 42)
#학습 데이터, 학습 타겟 훈련
dt_clf.fit(X_train, y_train)
#학습된 모델을 활용하여 예측 수행
pred_dt = dt_clf.predict(x_test)
#예측 정확도 확인
print('예측 정확도:{0:.4f}'.format(accuracy_score(y_test, pred_dt)))
위 예제 프로세스 요약
위 예제에서,,,
보통 정확도 100%는 학습이 잘못되었음을 의미한다. (훈련 데이터를 테스트에 사용하였다던가...)
물론 해당 예제에서 적은 양의 데이터를 사용하였기 때문에 이러한 결과가 나올 수 있겠지만 다양한 데이터를 기반으로 예측 성능을 평가해야한다.
모델의 성능을 높이기 위해...
교차 검증
앞의 예제처럼 train_test_split()을 활용하여 학습 데이터와 훈련 데이터를 나누는 방법은 과적합에 취약하다. (학습 데이터에만 과도하게 훈련되어 새로운 테스트 데이터에서의 성능이 떨어지는 경우) 뿐만 아니라, 위의 예제처럼 고정된 데이터를 사용하게 된다면 테스트 데이터에만 최적의 성능을 발휘할 수 있도록 편향된 모델이 생성될 수도 있다.
이러한 과적합과 편향을 막는 방법이 바로 교차 검증이다. 여러 세트로 구성된 학습 데이터, 검증 데이터를 형성하여 훈련하는 방식이다. (테스트 데이터는 절대로 손대지 않는다.)
교차 검증 1 - K 폴드 교차 검증
- K개의 데이터 폴드 세트 생성
- K번만큼 각 폴드 세트에 학습과 검증 평가 수행
from sklearn.model_selection import KFold
kfold = KFold(n_splits=6)
cv_accuracy = []
print('붓꽃 데이터 세트 크기:', iris.data.shape[0])
데이터의 수는 150개이므로, 6개의 폴드로 나눠 데이터의 6/5 = 125는 훈련, 나머지 25개는 검증 데이터로 분류될 것이다.
import numpy as np
n_iter = 0
cv_accuracy = []
for train_index, test_index in kfold.split(iris.data):
X_train, X_test = iris.data[train_index], iris.data[test_index]
y_train, y_test = iris.target[train_index], iris.target[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('\n{0} 검증 세트 인덱스 :{1}'.format(n_iter, test_index))
cv_accuracy.append(accuracy)
print('\n## 평균 검증 정확도:', np.mean(cv_accuracy))
교차 검증 2 - Stratified K 폴드
- 불균형한 분포도를 가진 레이블 데이터 집합을 위한 K 폴드 방식
- 특정 레이블이 많거나 매우 적어서 분포가 치우치는 경우
- 즉, 폴드 생성 시 원본 데이터의 분포와 유사하게 생성하는 방식
iris_df['label'].value_counts()
각 클래스 별로 50개의 데이터를 가지고 있다. 그리고 데이터를 shuffle하지 않았기 때문에 0번 클래스50개 ~ 1번 클래스 50개~ 2번 클래스 50개 의 연속적인 데이터 구조를 띄고 있다. 해당 데이터를 3개의 폴드로 나눠보고 각 데이터의 레이블 비율을 살펴보자.
kfold = KFold(n_splits=3)
n_iter = 0
for train_index, test_index in kfold.split(iris_df):
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())
만약 이러한 결과를 활용한다면 모델은 첫 번째 폴드에서는 0을 절대 검증해내지 못할 것이고, 두 번째 폴드에서는 1을 절대로 검증할 수 없을 것이다.
데이터를 제대로 섞고 다시 수행하면 상관이 없겠지만 이러한 경우 stratifiedKFold를 사용하면 해결할 수 있다.
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())
레이블 데이터 분포도에 따라 학습/검증 데이터를 나눈다.
그렇다면 StratifiedKFold를 활용하여 다시 한 번 모델을 만들어보겠다.
df_clf = DecisionTreeClassifier(random_state = 13)
skfold = StratifiedKFold(n_splits=3)
n_iter = 0
cv_accuracy = []
for train_index, test_index in skfold.split(iris.data, iris.target):
X_train, X_test = iris.data[train_index], iris.data[test_index]
y_train, y_test = iris.target[train_index], iris.target[test_index]
df_clf.fit(X_train,y_train)
pred = df_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))
교차 검증 3 - cross_val_score()
- 1. 폴드 세트 설정
- 2. for 루프에서 반복으로 학습 및 테스트 데이터의 인덱스 추출
- 3. 반복적으로 학습과 예측 수행
cross_val_score()는 위의 과정을 한 번에 수행해주는 API이다.
cross_val_score(알고리즘, X(피처 데이터), y=None(레이블 데이터), scoring=None(예측 성능 평가 지표),
cv=n(교차 검증 폴드 수), n_jobs=1, verbose=0, fit_params=None, pre_dispatch='2*n_jobs')
cross_val_score()을 활용해보겠다.
from sklearn.model_selection import cross_val_score, cross_validate
iris_data = load_iris()
data = iris_data.data
label = iris_data.target
scores = cross_val_score(df_clf, data, label, scoring='accuracy', cv=3)
print('교차 검증별 정확도', np.round(scores,4))
print('평균 검증 정확도', np.round(np.mean(scores),4))
'파이썬 머신러닝 완벽가이드' 카테고리의 다른 글
판다스 (Pandas) (0) | 2021.05.12 |
---|---|
넘파이 (ndarray) (0) | 2021.05.10 |