티스토리 뷰

INDEX

1. 사이킷런 소개 

2. 붓꽃 품종 예측하기

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

4. Model Selection 소개  - train_test_split()

5. 교차검증 - K-Fold, Stratified K-Fold 이해

6. cross_val_score() 와 GridSearchCV

 

 

 

1. 사이킷런 소개

사이킷런 (scikit-learn) 파이썬 머신러닝 라이브러리 가장 많이 사용되는 라이브러리

사이킷런의 특징

  • 파이썬 기반의 다른 머신러닝 패키지도 사이킷런 스타일의 API 지향할정도로 쉽고 가장 파이썬스러운 API 제공
  • 머신러닝을 위한 매우 다양한 알고리즘과 개발을 위한 편리한 프레임워크와 API 제공
  • 오랜 기간 실전환경에서 검증, 매우 많은 환경에서 사용되는 성숙한 라이브러리
  • Numpy, Scipy 기반위에서 구축되어있음

 

2. 붓꽃(Iris) 품종 예측하기

사이킷런을 이용한 붓꽃(Iris) 데이터 분류(가장 대표적인 예제. 머신러닝의 Hello world 느낌)

사이킷런을 통해 첫번째로 만들어볼 머신러닝 모델은 붓꽃 데이터 세트로 붓꽃의 품종을 분류(Classification)하는 것

간단히 말하자면 꽃잎의 길이(length), 너비(width), 꽃밭침의 길이와 너비의 4가지 피쳐(Feature)기반으로 꽃 품종 예측하기 위한 것

(각각 Sepal length, Sepal width, Petal length, Petal width라고 부름)

=> 붓꽃 데이터 품종(레이블) Setosa(0), Vesicolor(1), Virginica(2) 3중 1개 예측

 

코드에 앞서 용어 정리

  1. 피처(Feature):
    • 정의: 데이터 세트의 일반 속성.
    • 비고: 2차원 이상의 다차원 데이터에서도 사용되며, 특정 데이터 값 (예: 타켓 값)를 제외한 나머지 속성을 모두 피처로 지칭.
  2. 레이블/클래스/타겟(값)/결정(값)
    • 정의: 지도학습에서 데이터 학습을 위해 주어지는 정답 데이터.
    • 지도학습 중 분류의 경우에는 이 값을 클래스 또는 레이블로 지칭(4개다 동일하게 생각해도 무방함)
  3. 지도학습 (Supervised Learning):
    • 정의: 학습을 위한 다양한 피처와 레이블 데이터로 모델을 학습한 후, 별도의 테스트 데이터 세트에서 레이블을 예측하는 방법.
    • 분류 (Classification): 대표적인 지도학습 방법. 미리 정의된 여러 클래스 레이블 중 하나를 예측하는 것.
    • 비고: 학습 데이터를 통해 모델이 학습되고, 테스트 데이터를 통해 모델의 성능이 평가됨.

 

붓꽃 데이터 분류 예측 프로세스

  1. 데이터 세트 분리: 데이터를 학습 데이터와 테스트 데이터로 분리.
  2. 모델 학습: 학습 데이터를 기반으로 ML 알고리즘을 사용하여 모델 학습.
  3. 예측 수행: 학습된 ML 모델로 테스트 데이터의 분류(예: 붓꽃 종류)를 예측.
  4. 평가: 예측된 값과 테스트 데이터의 실제 값 비교로 ML 모델의 성능 평가.

 

데이터 세트 로딩

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

# 사이킷런 모듈 로딩
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는 데이터 세트에서 피처만으로 구성된 데이터의 numpy
iris_data = iris.data # fetaure
# iris.target은 데이터 세트에서 레이블(결정값, 정답) 데이터의 numpy
iris_label = iris.target # label

print('iris target값:', iris_label) # 0,1,2로만 구성
print('iris target명', iris.target_names)

#붓꽃 데이터세트 자세히 보기 위해 DataFrame으로 변환함
iris_df = pd.DataFrame(data=iris_data, columns=iris.feature_names) # feature_names: sepal length,sepal width
iris_df['label'] = iris.target # label이란 column 추가!
iris_df.head(3)

 

 

Feature -> sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)

Target(결정값) -> 레이블 0,1,2

0이 Setosa, 1이 versicolor, 2가 virginica

테스트세트와 학습데이터로 나누기 위해 train_test_split 사용

 

학습 데이터 세트와 테스트 데이터 세트로 분리

# 피처 데이터 세트 iris_data, 타겟(결정값), 데이터 세트 iris_label, 20%(test_size)만 테스트로 만들어라. 
# random_state는 반환값으로 고정값으로 넣는다
x_train, x_test, y_train, y_test = train_test_split(iris_data, iris_label, test_size=0.2, random_state=11)
  1. x_train : 학습용 데이터 feature
  2. x_test : 테스트용 데이터 feature
  3. y_train: 학습용 데이터 label
  4. y_test: 테스트용 데이터 label

간단히, "x"는 데이터의 특성, "y"는 정답 라벨을 나타내며, "train"은 학습용, "test"는 검증용 데이터를 의미

 

머신러닝 분류 알고리즘의 하나인 의사 결정 트리를 이용해 학습과 예측을 수행

(학습 데이터 세트로 학습(Train)수행, 테스트 데이터 세트로 예측(Predict)수행)

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

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

# 예측 수행(학습이 완료된 DecisionTreeClassifier 객체에서 테스트 데이터 세트로 예측 수행)
pred = dt_clf.predict(x_test) # 예측!을 해야하므로 문제(x_test)만 넣어준다

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

# 예측 정확도: 0.9333

 

붓꽃 예제를 통해 배울 수 있었던 것

  • 데이터 나누기: train_test_split을 사용하여 학습용과 테스트용 데이터로 분류한다.
  • 학습: 학습 데이터와 ML 알고리즘을 활용하여 모델을 구축한다.
  • 예측: 학습된 모델로 테스트 데이터를 이용해 붓꽃의 종류를 예측한다.
  • 성능 평가: 예측 결과와 테스트 데이터의 실제 값을 대조하여 모델의 정확도를 평가한다. (이 경우, 정확도 지표가 사용되었다)

 

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

3-1. Estimator 이해 및 fit(), predict() 메서드

Estimator:

  • 사이킷런의 주요 API
  • 분류 알고리즘 클래스 = Classifier, 회귀 알고리즘 클래스 = Regressor. 이 두 클래스를 합쳐 Estimator라고 합니다.

기본 메서드:

  • fit(): 학습 데이터를 입력하여 학습을 진행.
  • predict(): 학습된 모델로 결과 값을 예측.
from sklearn.datasets import load_iris

iris_data = load_iris()
print(type(iris_data)) #<class 'sklearn.utils._bunch.Bunch'>

#dictionary 느낌
keys = iris_data.keys()
print('붓꽃 데이터 세트의 키들:',keys)

 

3-2. 내장된 데이터 세트

데이터 구성:

  • data: 피처 데이터 세트
  • target: 분류 시 레이블 값, 회귀 시 숫자 결과 값 데이터 세트
  • target_names: 각 레이블의 이름
  • feature_names: 피처의 이름
  • DESCR: 데이터 세트 설명
print('\n feature_names 의 type:',type(iris_data.feature_names))
print(' feature_names 의 shape:',len(iris_data.feature_names))
print(iris_data.feature_names) # ['sepal length (cm)', 'sepal width (cm)', ...]

print('\n target_names 의 type:',type(iris_data.target_names))
print(' target_names 의 shape:',len(iris_data.target_names))
print(iris_data.target_names) # ['setosa' 'versicolor' 'virginica']

print('\n data 의 type:',type(iris_data.data))
print(' data 의 shape:',iris_data.data.shape)
print(iris_data['data']) # [[5.1 3.5 1.4 0.2],...]

print('\n target 의 type:',type(iris_data.target))
print(' target 의 shape:',iris_data.target.shape)
print(iris_data.target) # 0 0 0 1 1 1

 

4. Model Selection 소개

학습/테스트 데이터 분리 - train_test_split()

  • sklearn.model.selection의 train_test_split()
  • 데이터를 학습용과 테스트용으로 분리
  • 학습된 모델로 테스트 데이터를 사용해 예측 후, 예측된 결과와 테스트 데이터의 실제 값을 비교하여 모델의 성능을 평가
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

iris = load_iris()
dt_clf = DecisionTreeClassifier()
train_data = iris.data
train_label = iris.target
dt_clf.fit(train_data, train_label) #학습도 train_data

# 학습 데이터 셋으로 예측 수행
pred = dt_clf.predict(train_data) # 예측도 train_data로 한다면?
print('예측 정확도:',accuracy_score(train_label,pred)) # 예측 정확도: 1.0
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

 

넘파이 ndarray 뿐만 아니라 판다스 DataFrame/Series train_test_split( )으로 분할 가능

import pandas as pd

iris_df = pd.DataFrame(iris_data.data, columns=iris_data.feature_names)
iris_df['target']=iris_data.target
iris_df.head()

 

ftr_df = iris_df.iloc[:, :-1]
tgt_df = iris_df.iloc[:, -1]
X_train, X_test, y_train, y_test = train_test_split(ftr_df, tgt_df, 
                                                    test_size=0.3, random_state=121)
dt_clf = DecisionTreeClassifier( )
dt_clf.fit(X_train, y_train)
pred = dt_clf.predict(X_test)
print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test,pred))) # 예측 정확도: 0.9556

 

 

5. 교차검증 - K-Fold, Stratified K-Fold 이해

교차 검증

과적합(Overfitting)은 모델이 학습 데이터에만 과도하게 최적화되어, 실제 예측을 다른 데이터로 수행할 경우 예측 성능이 과도하게 떨어지는 것을 말한다. 이러한 문제점을 개선하기 위해 교차 검증을 이용해 더 다양한 학습과 평가를 수행한다.

1. K-Fold

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

KFold 클래스를 이용해 붓꽃 데이터 세트를 교차 검증하고 예측 정확도를 알아보자.

 

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]) # 학습데이터 건수는 4/5

# 붓꽃 데이터 세트 크기: 150


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

 

 

2. Stratified K-Fold

Stratified K 폴드는 불균형한 분포도를 가진 레이블(결정 클래스) 데이터 집합을 위한 K 폴드 방식

불균형한 분포도를 가진 레이블 데이터 집합은 특정 레이블 값이 특이하게 많거나 매우 적어서 값의 분포가 한쪽으로 치우치는 것을 의미

 

import pandas as pd

iris = load_iris()

iris_df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
iris_df['label']=iris.target
iris_df['label'].value_counts()

 

 

Stratified K 폴드는 K 폴드가 레이블 데이터 집합이 원본 데이터 집합의 레이블 분포를 학습 및 테스트 세트에 제대로 분배하지 못하는 경우의 문제를 해결해 준다.

 

K 폴드의 문제점

kfold = KFold(n_splits=3)
# kfold.split(X)는 폴드 세트를 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())

현재 학습 데이터가 골고루 분포되지 않아 제대로 학습이 되지 않고 있는 단점ㅜ

 

Stratified K 폴드 적용

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

 

 

5. cross_val_score() 와 GridSearchCV

 

cross_val_score()는 사이킷런의 API로, 교차 검증을 보다 간편하게 수행할 수 있게 도와준다

GridSearchCV와는 다르게, 하이퍼 파라미터 튜닝을 자동으로 수행하지 않지만,

주어진 알고리즘(estimator)에 대한 교차 검증을 쉽게 실행할 수 있다.

cross_val_score() 함수에 사용되는 파라미터

  1. estimator: 교차 검증을 수행할 알고리즘. 분류 알고리즘일 경우 Classifier, 회귀 알고리즘일 경우 Regressor를 지정.
  2. X: 독립 변수 데이터 세트.
  3. y: 종속 변수(레이블) 데이터 세트.
  4. scoring: 모델의 성능을 평가할 지표. 예를 들어, 분류일 경우 'accuracy', 회귀일 경우 'mean_squared_error' 등을 사용.
  5. cv: 교차 검증을 위해 데이터를 몇 개의 세트로 나눌지 지정.

교차 검증을 쉽게 수행할 수 있으며, 결과로 각 폴드별 검증 점수를 배열로 반환.

알고리즘의 성능을 빠르게 확인하거나 여러 알고리즘들의 성능을 비교할 때 유용하게 사용.

from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
import numpy as np

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) 
print(scores, type(scores))
print('교차 검증별 정확도:',np.round(scores,4))
print('평균 검증 정확도:', np.round(np.mean(scores),4))

 

 

GridSearchCV - 교차 검증과 최적 하이퍼 파라미터 튜닝을 한 번에 가능함

GridSearchCV는 사이킷런의 API로, 교차 검증을 기반으로 하이퍼 파라미터의 최적 값을 찾는 작업을 자동화해준다.

이를 통해, 머신러닝 알고리즘의 다양한 하이퍼 파라미터 조합을 시험하여 그 중에서 최적의 성능을 보이는 파라미터 값을 쉽게 찾을 수 있다.

예를 들어, 결정 트리 알고리즘의 다양한 하이퍼 파라미터 값을 조합하여 테스트하고 싶다면, 해당 파라미터들의 가능한 값들을 지정하고 GridSearchCV를 사용해 자동으로 최적의 조합을 탐색하게 할 수 있다.

GridSearchCV를 사용하기 위해서는 반드시 'fit' 메서드를 호출해야 한다. 이 메서드는 주어진 데이터와 지정된 하이퍼 파라미터 범위에 대해 교차 검증을 수행한다.

GridSearchCV의 주요 파라미터들은 다음과 같다:

  1. estimator: 사용하려는 알고리즘을 지정한다. Classifier, Regressor 또는 Pipeline 등이 될 수 있다.
  2. param_grid: 탐색하려는 파라미터의 범위를 딕셔너리 형태로 지정한다. 각 키는 파라미터의 이름이며, 해당 키의 값은 그 파라미터의 가능한 값들의 리스트이다.
  3. scoring: 모델의 성능을 평가하는 기준을 지정한다.
  4. cv: 교차 검증 시 데이터를 몇 개의 세트로 분할할지 지정한다.
  5. refit: 기본값은 True이다. True로 설정하면, 최적의 하이퍼 파라미터를 찾은 후 해당 파라미터로 전체 데이터를 다시 학습한다.

 -> 수동으로 여러 하이퍼 파라미터 조합을 시도하는 대신 자동화된 프로세스로 최적의 조합을 빠르게 찾을 수 있음

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

# 데이터를 로딩하고 학습데이타와 테스트 데이터 분리
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]}


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, return_train_score=True)

# 붓꽃 Train 데이터로 param_grid의 하이퍼 파라미터들을 순차적으로 학습/평가 .
grid_dtree.fit(X_train, y_train)

# GridSearchCV 결과는 cv_results_ 라는 딕셔너리로 저장됨. 이를 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로 설정된 GridSearchCV 객체가 fit()을 수행 시 학습이 완료된 Estimator를 내포하고 있으므로 predict()를 통해 예측도 가능. 
pred = grid_dtree.predict(X_test)
print('테스트 데이터 세트 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))​

# 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

 

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함