[머신러닝 완벽 가이드] 2장_사이킷런으로 시작하는 머신러닝 (1)

이경민·2023년 1월 4일
0

📌사이킷런 기반 프레임워크 익히기

✅ Estimator 이해

  • Estimator 클래스: 지도학습 -> fit(), predict()
    • Classifier: 분류 알고리즘 클래스
    • Regressor: 회귀 알고리즘 클래스

✅ sklearn 주요 모듈

  • sklearn.datasets: 내장된 예제 데이터 세트 제공

  • sklearn.preprocessing: 데이터 전처리 관련 기능 제공 (인코딩, 정규화 등)

  • sklearn.feature_selection: 피처 셀렉션 작업 관련 기능 제공

  • sklearn.feature_extraction: 텍스트나 이미지 데이터의 벡터화된 피처 추출 관련 기능 제공

  • sklearn.decomposition: 차원축소 기능 제공

  • sklearn.model_selection: 데이터 분리, 검증, 파라미터 튜닝 등의 기능 제공

  • sklearn.metrics: 성능 평가 기능 제공

  • sklearn.ensemble: 앙상블 알고리즘 제공

  • sklearn.linear_model: 회귀 관련 알고리즘 제공

  • sklearn.naive_bays: 나이브 베이즈 알고리즘 제공

  • sklearn.neighbors: 최근접 이웃 알고리즘 제공

  • sklearn.svm: 서포트 벡터 머신 알고리즘 제공

  • sklearn.tree: 의사 결정 트리 알고리즘 제공

  • sklearn.cluster: 비지도 클러스터링 알고리즘 제공

  • sklearn.pipeline: 피처 처리, ML 알고리즘 등을 함께 묶어서 실행할 수 있는 유틸리티 제공

✅ 내장된 예제 데이터 세트

  • 예제 데이터 자료형:
    sklearn.utils.Bunch 클래스 - 딕셔너리 자료형과 유사
  • Key
    • data: 피처의 데이터 세트
    • feature_names: 피처의 이름
    • target: 분류 시 레이블 값, 회귀일 때는 숫자 결괏값 데이터 세트
    • target_names: 개별 레이블의 이름
    • DESCR: 데이터 세트에 대한 설명과 각 피처의 설명
# 예제 데이터 불러오기

from sklearn.datasets import load_iris

iris_data = load_iris()

print(iris_data.feature_names) # ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
print(iris_data.target_names) # ['setosa' 'versicolor' 'virginica']

📌 Model Selection 모듈 소개

✅ 학습/테스트 데이터 세트 분리

  • train_test_split(data, target)

    • test_size: 테스트 데이터 세트 비율 지정
    • shuffle: 데이터 세트를 섞을지 결정, 디폴트=True
    • random_state: 호출할 때마다 동일한 학습/테스트 데이터 세트를 생성하기 위한 난수 값
  • 반환 값은 튜플 형태: X_train, X_test, y_train, y_test

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

iris_data = load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris_data.data, iris_data.target, test_size=0.3, random_state=0)

✅ 교차 검증

  • 고정된 학습 데이터와 테스트 데이터로 평가할 경우, 해당 테스트 데이터에만 과적합되는 학습 모델이 만들어져 다른 테스트용 데이터가 들어올 경우에는 성능이 저하될 수 있다.

  • 데이터의 편중을 막기 위해 별도의 여러 세트로 구성된 학습 데이터와 검증 데이터 세트에서 학습과 평가를 수행

    📝 과적합
    모델이 학습 데이터에만 과도하게 최적화되어, 실제 예측을 다른 데이터로 수행할 경우에는 예측 성능이 과도하게 떨어지는 것을 말한다.

(1) K 폴드

  • kfold = KFold(n_splits)

  • kfold.split(data): 학습용/검증용 데이터로 분할할 수 있는 인덱스 반환

  • K개의 데이터 폴드 세트를 만들어 K번만큼 각 폴드 세트에 학습과 검증 평가를 반복적으로 수행하는 방법

  • 교차 검증 최종 평가: 평균(K개의 예측 평가)

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import KFold
from sklearn.metrics import accuracy_score
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 = []

n_iter = 0

# KFold객체의 split( ) 호출하면 폴드 별 학습용, 검증용 테스트의 로우 인덱스를 array로 반환  
for train_index, test_index  in kfold.split(features):
    # kfold.split( )으로 반환된 인덱스를 이용하여 학습용, 검증용 테스트 데이터 추출
    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)
    cv_accuracy.append(accuracy)

# 개별 정확도를 합하여 평균 정확도 계산 
print('\n## 평균 검증 정확도:', np.mean(cv_accuracy)) 

(2) Stratified K 폴드

  • skf = StratifiedKFold(n_splits)

  • skf.split(data, target): 학습용/검증용 데이터로 분할할 수 있는 인덱스 반환

  • 불균형한(imbalanced) 분포도를 가진 레이블 데이터 집합을 위한 K 폴드 방식

  • KFold로 분할된 레이블 데이터 세트가 전체 레이블 값의 분포도를 반영하지 못하는 문제를 해결

  • 원본 데이터의 레이블 분포를 먼저 고려한 뒤 이 분포와 동일하게 학습과 검증 데이터 세트를 분배

  • 회귀에서는 지원 X

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import accuracy_score
import numpy as np

iris = load_iris()
features = iris.data
label = iris.target
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):
    # split( )으로 반환된 인덱스를 이용하여 학습용, 검증용 테스트 데이터 추출
    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)
    cv_accuracy.append(accuracy)
  
# 평균 정확도 계산 
print('## 평균 검증 정확도:', np.mean(cv_accuracy)) 

(3) cross_val_score( )

  • 교차 검증을 좀 더 편리하게 수행 가능 (1, 2, 3 한꺼번에 수행)

  • cv로 지정된 횟수만큼 scoring 파라미터로 지정된 평가 지표로 평가 결괏값을 배열로 반환

  1. 폴드 세트 설정
  2. for 루프에서 반복으로 학습 및 테스트 데이터의 인덱스 추출
  3. 반복적으로 학습과 예측을 수행, 예측 성능 반환
  • cross_val_score(estimator, X, y, scoring, cv)

    • 분류 모델 (Stratified K 폴드 방식), 회귀 모델 (K 폴드 방식)
    • estimator: 분류/회귀 알고리즘 클래스
    • X: 피처
    • y: 레이블
    • scoring: 예측 성능 평가 지표
    • cv: 교차 검증 폴드 수
  • cross_validate(): 여러 개의 평가 지표를 반환할 수 있음

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score

iris_data = load_iris()
data = iris_data.data
label = iris_data.target

dt_clf = DecisionTreeClassifier(random_state=156)

# 성능 지표는 정확도(accuracy), 교차 검증 세트는 3개 
scores = cross_val_score(dt_clf, data, label, scoring='accuracy', cv=3)
print('교차 검증별 정확도:',np.round(scores, 4))
print('평균 검증 정확도:', np.round(np.mean(scores), 4))

✅ GridSearchCV - 하이퍼 파라미터 튜닝

  • 최적의 파라미터 도출

  • 교차 검증을 기반으로 최고 성능을 가지는 파라미터 조합을 찾아줌

  • GridSearchCV(estimator, param_grid, scoring, cv, refit)

    • estimator: classifier, regressor, pipeline
    • param_grid: dict({key:list}) -> {파라미터명: 파라미터 값}
    • scoring: 성능 평가 지표
    • cv: 교차검증 폴드 수
    • refit: 최적의 파라미터로 재학습 여부, 디폴트=True
  • GridSearchCV.fit(X, y): 교차 검증을 기반으로 하이퍼 파라미터를 순차적으로 변경하면서 학습/평가를 수행

  • GridSearchCV.best_params_: 최고 성능을 나타낸 하이퍼 파라미터 값

  • GridSearchCV.best_score_: 최고 성능을 나타낸 평가 결과 값

  • GridSearchCV.cv_results_: 결과 세트를 딕셔너리 형태로 저장

    • params: 수행에 적용된 하이퍼 파라미터 조합
    • rank_test_score: 예측 성능 순위, 1이 가장 뛰어난 순위
    • mean_test_score: 평가 평균값
    • split{n}_test_score: 각각의 폴딩 세트에서의 성능
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
import pandas as pd

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]}

# refit=True, 최적의 파라미터로 재학습
grid_dtree = GridSearchCV(dtree, param_grid=parameters, cv=3, refit=True)
grid_dtree.fit(X_train, y_train)

# GridSearchCV 결과 DataFrame으로 변환
scores_df = pd.DataFrame(grid_dtree.cv_results_)
scores_df[['params', 'mean_test_score', 'rank_test_score', 'split0_test_score', 'split1_test_score', 'split2_test_score']]

print('GridSearchCV 최적 파라미터:', grid_dtree.best_params_)
print('GridSearchCV 최고 정확도: {0:.4f}'.format(grid_dtree.best_score_))

# refit=True를 통해 최적의 하이퍼 파라미터로 재학습 -> best_estimator_로 저장
estimator = grid_dtree.best_estimator_
pred = estimator.predict(X_test)
print('테스트 데이터 세트 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))
profile
열정 가득한 공간

0개의 댓글