머신러닝

[2장] 파이썬 머신러닝 완벽 가이드_사이킷런_1

zsun 2023. 4. 21. 14:48

01. 사이킷런(scikit-learn)

- 파이썬 머신러닝 라이브러리 중 가장 많이 사용되는 라이브러리

#설치
pip install scikit-learn==1.0.2
pip instll -U scikit-learn

#버전확인
import sklearn
print(sklearn.__version__)

 

02. 머신러닝 만들어보기 - 붓꽃 품종 예측하기

: 꽃잎의 길이와 너비, 꽃받침의 길이와 너비 피처 기반으로 품종 예측

 

- Classification은 대표적인 지도학습의 예시

- 지도학습은 다양한 피처와 분류 결정값인 레이블(Lable) 데이터로 모델을 학습한 뒤, 별도의 테스트 데이터셋에서 레이블 예측

  : 명확한 정답이 주어진 데이터를 먼저 학습한 뒤 정답 예측

- 학습데이터셋 + 테스트 데이터셋 으로 구성

 

  • sklearn.datasets : 사이킷런에서 자체적으로 제공하는 데이터셋을 생성하는 모듈의 모임
  • 하이퍼파라미터 : 머신러닝 알고리즘별로 최적의 학습을 위해 직접 입력하는 파라미터, 이를 통해 머신러닝 알고리즘의 성능 튜닝

 

 

붓꽃(iris) 데이터 품종 예측하기

from sklearn.datasets import load_iris #붓꽃 데이터셋 생성
from sklearn.tree import DecisionTreeClassifier #ML알고리즘:의사결정트리
from sklearn.model_selection import train_test_split #학습셋과 테스트셋으로 분리
import pandas as pd

# 붓꽃 데이터셋 로딩 
iris = load_iris()

 

- 학습용 데이터와 테스트용 데이터 분리
- 사이킷런에서는 train_test_split() API제공
- test_size 파라미터 입력값의 비율로 쉽게 분할

# iris_data:피처 데이터셋, iris_label:레이블 데이터셋, random_state:난수 발생 값(seed 개념과 비슷)
# 학습용 피처 데이터셋 : X_train, 테스트용 피처 데이터셋 : X_test
# 학습용 레이블 데이터셋 : y_train, 테스트용 레이블 데이터셋 : y_test


X_train, X_test, y_train, y_test = train_test_split(iris_data, iris_label, 
                                                    test_size=0.2, random_state=11)

- 학습 수행

# DecisionTreeClassifier 객체 생성 
dt_clf = DecisionTreeClassifier(random_state=11)

# 학습 수행 
dt_clf.fit(X_train, y_train)

- 예측 수행

# 학습이 완료된 DecisionTreeClassifier 객체에서 테스트 데이터 세트로 예측 수행. 
pred = dt_clf.predict(X_test)

- 예측 성능 평가

# DecisionTreeClassifier의 예측 성능 평가 
# 정확도 예측 : 실제 레이블 값과 예측 결과가 얼마나 정확하게 맞는지 평가

from sklearn.metrics import accuracy_score
print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))

 

분류 예측 프로세스

1. 데이터셋 분리 : 데이터를 학습 데이터와 테스트 데이터로 분리
2. 모델 학습 : 학습 데이터를 기반으로 ML 알고리즘을 적용해 모델을 학습시킴
3. 예측 수행 : 학습된 ML 모델을 이용해 테스트 데이터의 분류(즉, 붓꽃 종류)를 예측
4. 평가 :  이렇게 예측된 결괏값과 테스트 데이터의 실제 결괏값을 비교해 ML 모델 성능 평가

 

 

 

03.사이킷런의 기반 프레임워크 익히기

- Estimator 이해 및 fit(), predict() 메서드
- 분류알고리즘 구현 클래스 : Classifier, 회귀 알고리즘 구현 클래스 : Regressor 로 지칭
- Classifier + Regressor = Estimator 클래스 (fit()과 predict() 내부 구현)
- 비지도학습에서의 fit()은 지도학습의 fit()처럼 학습을 의미하는 것이 아님
- 입력 데이터의 형태에 맞춰 데이터를 변환하기 위한 사전 구조를 맞추는 작업

 

 

  • 사이킷런에 내장된 데이터셋은 일반적으로 딕셔너리 형태로 되어있음
keys = iris_data.keys()
print('붓꽃 데이터 세트의 키들:', keys)

# 붓꽃 데이터 세트의 키들: dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename'])

 

  • data : 피처의 데이터셋 , ndarray
  • target : 분류 시 레이블 값, 회귀일 때는 숫자 결괏값 데이터셋 , ndarray
  • target_names : 개별 레이블의 이름
  • feature_names :  피처의 이름
  • DESCR : 데이터셋에 대한 설명과 각 피처의 설명 , string

  • 데이터 키 :  피처들의 데이터 값
  • 데이터셋이 딕셔너리 형태이기 떄문에 피처 데이터 값 추출을 위해서는 데이터셋.data 또는 데이터셋['data']를 이용

 

 

04.  Model selection 모듈 소개

- train_test_split 로드
- 첫번째 파라미터로 피처 데이터셋, 두 번째 파라미터로 레이블 데이터셋 입력 받음
- test_size : 전체 데이터셋에서 테스틑 데이터셋 크기를 얼마로 할건지, 디폴트는 0.25
- shuffle : 데이터를 분리하기 전에 데이터를 미리 섞을지 결정, 디폴트는 True
- trian_test_split()의 반환값은 튜플 형태

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

dt_clf = DecisionTreeClassifier( )
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=121)
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))

# 예측 정확도: 0.9556

 

 

교차검증

- 학습데이터셋을 학습데이터셋과 검증데이터셋으로 분할, 최종적으로 성능 평가하기 위해 테스트 데이터셋 사용

 

K 폴드 교차 검증

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

 

- KFold 객체는 split()을 호출하면 학습용/검증용 데이터롤 분할할 수 있는 인덱스를 반환
- 실제로 학습용 / 검증용 데이터 추출은 반환된 인덱스를 기반으로 개발 코드에서 직접 수행해야 함

 

Stratified K 폴드

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

 

* Stratified K 폴드와 K 폴드의 차이

: Stratified는 레이블 데이터 분포도에 따라 학습/검증 데이터를 나누기 때문에 split() 메서드에 인자로 피처 데이터셋 뿐만 아니라 레이블 데이터셋도 반드시 필요함

 

- 일반적으로 분류(Classification)에서의 교차 검증은 K폴드가 아니라 Stratified로 분할 되어야 함
- 회귀의 결정값은 이산값 형태의 레이블이 아니라 연속된 숫자 값이기 때문에 결정값별로 분포를 정하는 의미가 없어서 회귀에서는 Stratified가 지원되지 않음

 

 

cross_val_score( )

- 교차 검증을 편리하게 수행할 수 있는 API 제공


1. 폴드세트를 설정하고 

2. for 루프에서 반복으로 학습및 테스트 데이터 인덱스 추출한 뒤 

3. 반복적으로 학습과 예측을 수행하고 예측 성능 반환하는 일련의 과정을 한번에 수행해주는 API

- 기본 선언 형태

cross_val_score(estimator, X, y=None, scoring=None, cv-None, n_jobs=1, verbose=0, fit_params=None,pre_dispatch='2*n_jobs')


- 주요 파라미터 : X, y, scoring, cv
- estimator는 사이킷런의 분류 알고리즘 클래스인 Classifier 또는 회귀 알고리즘 클래스인 Regression
- X: 피처 데이터셋 , y: 레이블 데이터 셋 , scoring: 예측 성능 평가 지표 , cv: 교차 검증 필드 수
- cross_val_score() 수행 후 반환 값은 scoring 파라미터로 지정된 성능 지표 측정값을 배열 형태로 반환함

 

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

iris_data = load_iris()
dt_clf = DecisionTreeClassifier(random_state=156)

data = iris_data.data
label = iris_data.target

# 성능 지표는 정확도(accuracy) , 교차 검증 세트는 3개 
scores = cross_val_score(dt_clf , data , label , scoring='accuracy',cv=3)
# cv로 지정된 횟수 만큼 scoring 파라미터로 지정된 평가 지표로 평가 결괏값을 배열로 반환
print('교차 검증별 정확도:',np.round(scores, 4))
print('평균 검증 정확도:', np.round(np.mean(scores), 4))

 

 

GridSearchCV

- 하이퍼 파라미터는 머신러닝 알고리즘을 구성하는 주요 구성 요소이며, 이 값을 조정해 알고리즘의 예측 성능 개선 가능

 

- 사이킷런은 GridSearchCV를 이용해 Classifier나 Regressor와 같은 알고리즘에 사용되는 하이퍼 파라미터를 순차적으로 입력하면서 편리하게 최적의 파라미터를 도출할 수 있는 방안 제공


- GridSearchCV는 교차 검증을 기반으로 이 하이터 파라미터의 최적 값을 찾게 해줌


- 데이터셋을 cross-validation을 위한 학습/테스트셋으로 자동 분할 한 뒤, 하이퍼 파라미터 그리드에 기술된 모든 파라미터를 순차적으로 적용해 최적의 파라미터 찾을 수 있게 함

 

- for문 쓰지 않아도 됨

 

 

[GridSearchCV 클래스의 생성자로 들어가는 주요 파라미터]

  • estimator : classifier, regressor, pipeline
  • param_grid : key+리스트 값을 가지는 딕셔너리가 주어짐, estimator의 튜닝을 위해 파라미터명과 사용될 여러 파라미터값을 지정
  • scoring : 예측 성능을 측정할 평가 방법을 지정함, 보통은 사이킷런의 성능 평가 지표를 지정하는 문자열(ex. 정확도 = accuracy)로 지정하나 별도의 성능 평가 지표 함수도 지정 가능
  • cv: 교차 검증을 위해 분할되는 학습/테스트셋의 개수 지정
  • refit : 디폴트가 True이며 True로 생성시 가장 최적의 하이퍼 파라미터를 찾은 뒤 입력된 estimator 객체를 해당 하이터 파라미터로 재학습 시킴

 

GridSearchCV 적용

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()

### parameter 들을 dictionary 형태로 설정
parameters = {'max_depth':[1,2,3], 'min_samples_split':[2,3]}

# 테스트 할 하이터 파라미터 세트는 딕셔너리 형태로 하이퍼 파라미터의 명칭은 문자열 key 값, 하이터 파라미터 값은 리스트형으로
import pandas as pd

# param_grid의 하이퍼 파라미터들을 3개의 train, test set fold 로 나누어서 테스트 수행 설정 
### refit=True 가 default 임. True이면 가장 좋은 파라미터 설정으로 재 학습 시킴
grid_dtree = GridSearchCV(dtree, param_grid=parameters, cv=3, refit=True)

# 붓꽃 Train 데이터로 param_grid의 하이퍼 파라미터들을 순차적으로 학습/평가
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']]

코드 수행 결과

  • params : 수행할때마다 적용된 개별 하이퍼파라미터값을 나타냄
  • rank_test_score : 하이퍼 파라미터별로 성능이 좋은 score 순위를 나타냄
  • mean_test_score : 개별 하이퍼 파라미터별로 CV의 폴딩 테스트셋에 대해 총 수행한 평가 평균값

 

* 위 예시의 경우

GridSearchCV 최적 파라미터는 'max_depth' : 3 , 'min_samples_split' : 2

GridSearchCV 최고 정확도 : 0.975

 

위 학습데이터를 GridSearchCV를 이용해 최적 하이처 파라미터 튜닝을 수행한 뒤에 별도의 테스트셋에서 이를 평가

# GridSearchCV의 refit으로 이미 학습이 된 estimator 반환
estimator = grid_dtree.best_estimator_

# GridSearchCV의 best_estimator_는 이미 최적 하이퍼 파라미터로 학습이 됨
pred = estimator.predict(X_test)
print('테스트 데이터 세트 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))

# 테스트 데이터셋 정확도 : 0.9667