본문 바로가기

AI Study/Machine Learning

sklearn 기반 프레임워크 살펴보기

Iris dataset을 통해 알아보는 Scikit-Learn 기반 프레임워크

 

iris 품종 예측이란?

  • iris data set로 붓꽃의 품종을 분류하는 것
    • 꽃잎의 길이, 너비 / 꽃받침의 길이, 너비 총 4개의 feature

  • Classification : 대표적인 지도학습(Supervised Learning)
    • 지도학습
      • 학습을 위한 feature + 분류결정값인 Lable = 학습 -> 별도의 테스트 데이터세트에서 미지의 레이블 예측
      • 정확한 정답이 주어진 데이터를 먼저 학습한 후, 미지의 정답을 예측하는 방식
        • training data set(학습을 위한 데이터 세트)
        • test data set(머신러닝 모델의 예측 성능을 평가하기 위한 별도의 데이터 세트)

  • scikit-learn package내의 module명 명명규칙(sklearn으로 시작)
    • sklearn.datasets : 사이킷런에서 자체적으로 제공하는 데이터 세트를 생성하는 모듈의 모임
    • sklearn.tree : 트리기반 ML 알고리즘을 구현한 클래스의 모임
    • sklearn.model_selection : 학습 데이터와 검증데이터, 예측 데이터로 데이터를 분리하거나 최적의 하이퍼 파라미터로 평가하기 위한 다양한 모듈의 모임
      • 하이퍼 파라미터 : ML 알고리즘별로 최적의 학습을 위해 직접 입력하는 파라미터들을 총칭, 하이퍼파라미터->ML알고리즘 성능 튜닝
      • train_test_split() : data set를 train/test로 분리하는데에 사용
    • sklearn.metrics : 모델의 성능을 확인하기 위한 accuracy_score 등을 제공

  • iris classification process
    • 데이터 세트 분리 : 데이터를 train/test로 분리 (by train_test_split() method)
    • 모델 학습 : model 객체.fit(X_train, y_train)
    • 예측 수행 : model 객체.predict(X_test)
    • 평가 : 실제 결과인 y_test VS 예측된 결과인 model 객체.predict(X_test)
In [1]:
from sklearn.datasets import load_iris #from sklearn.datasets : 사이킷런 자체 data set 생성하는 module 모임
from sklearn.tree import DecisionTreeClassifier #from sklearn.tree : 트리기반 ML AL을 구현한 class 모임 
from sklearn.model_selection import train_test_split #form sklearn.model_selection : 학습/검증/예측 data로 분리 or 하이퍼파라미터 최적을 위한 module 모임

import pandas as pd

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

# iris.data는 Iris 데이터 세트에서 feature만으로 된 데이터를 numpy로 가짐
iris_data = iris.data

# iris.target은 Iris 데이터 세트에서 label(결정값) 데이터를 numpy로 가짐
iris_label = iris.target

print('iris target값 : ', iris_label)

# iris의 분류품종인 setosa, versicolor, virginica가 속함
print('iris target명 : ', iris.target_names)

# 붓꽃 데이터 세트를 자세히 보기 위해 DataFrame으로 변환
# feature_names : sepal length, sepal width, petal length, petal width의 4가지
iris_df = pd.DataFrame(data=iris_data, columns=iris.feature_names)

# label column에 label값을 도입. 0은 seposa, 1은 versicolor, 2는 virginica 품종을 의미
iris_df['label'] = iris.target 
iris_df.head(3)
 
iris target값 :  [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2]
iris target명 :  ['setosa' 'versicolor' 'virginica']
 
Out[1]:
  sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) label
0 5.1 3.5 1.4 0.2 0
1 4.9 3.0 1.4 0.2 0
2 4.7 3.2 1.3 0.2 0

train_test_split API란?

  • train_test_split() API : data를 train/test로 쪼갬. 호출 시 무작위로 데이터를 분리함. -> tuple 형태로 반환
  • random_state : train_test_split가 무작위로 데이터를 쪼개므로, random_state를 지정하지 않으면 매번 다르게 date set가 쪼개짐.
    • 수행할 때마다 같은 train/date set로 쪼개질 수 있게 해주는 장치
    • 숫자 자체의 의미는 없음
In [2]:
# X_train : train_feature data set
# X_test : test_feature data set
# y_train : train_label data sets
# y_test : test_label data set

X_train, X_test, y_train, y_test = train_test_split(iris_data, # feature data set
                                                    iris_label, # label data set
                                                    
                                                    # 전체 data set 중 test data의 비율
                                                    test_size=0.2, 
                                                    
                                                    # 호출할 때마다 
                                                    # 같은 train/test data set를 생성하기 위한 것
                                                    random_state=11 ) 

 

In [3]:
# DecisionTreeClassifier 의사결정 트리로 학습(trian data를 사용)
# DecisionTreeClassifier 객체 생성
dt_clf = DecisionTreeClassifier(random_state=11)

# 학습 수행 : 생성된 DecisionTreeClassifier 객체의 fit() 메서드에 X_train(학습용 피처 데이터 속성), 
# y_train(학습용 레이블 데이터 세트)를 입력함
dt_clf.fit(X_train, y_train)
# 이제 의사결정트리 기반의 dt_clf 객체는 train data를 기반으로 학습이 완료된 상태

# 학습이 완료된 DecisionTreeClassifier 객체에서 test date set로 예측 수행
# pred = 학습을 통한 예측 값, label 값들로 이루어져 있음. [2,2,1,2,1,0,....] 형태
pred = dt_clf.predict(X_test) 
 
In [4]:
from sklearn.metrics import accuracy_score

# 순서 : 실제 label(y_test), 예측된 label(pred)
print('예측 정확도 : {0:.4f}'.format(accuracy_score(y_test, pred)))
 
예측 정확도 : 0.9333

sklearn 기반 프레임워크의 이해

  • Estimator 이해
    • Estimator = Classifier + Regressor = 지도학습의 모든 AL을 구현한 class를 통칭
    • Classifier(분류 알고리즘을 구현한 class)
      • DecisionTreeClassifier / RandomForestClassifier / GradientBoostingClassifier / GaussianNB / SVC
    • Regressor(회귀 알고리즘을 구현한 클래스)
      • LinearRegression / Ridge / Lasso / RandomForestRegressor / GradientBoostingRegressor
  • sklearn의 fit(), predict() method
    • ML 모델 학습을 위한 fit()
    • 학습된 모델의 예측을 위한 predict()
    • 모든 sklearn의 클래스(분류, 회귀)는 fit()으로 학습을, predict()로 예측 결과를 반환
  • sklearn의 비지도 학습(차원 축소, 클러스터링, 피쳐 추출(feature Extraction)등의 class : fit() / transform() 적용
    • fit() : 지도 학습과 다른 의미. 입력 데이터의 형태에 맞춰 데이터를 변환하기 위한 사전 구조를 맞추는 작업
    • 실제 작업을 transform()으로 수행
    • fit + transform = fit_transform()도 제공
  • 일반적인 ML model 구축 주요 프로세스
    • feature processing : feature의 가공, 변경 추출
    • ML AL 학습/예측 수행
    • 모델 평가
    • ...반복
    • 내장된 예제 데이터셋 설명은 아래와 같음
    • API명 문제 유형 설명
      datasets.load_boston() 회귀 미국 보스턴의 집 피처들과 가격에 대한 데이터 세트
      datasets.load_breast_cancer() 분류 위스콘신 유방암 피처들과 악성/음성 레이블 데이터 세트
      datasets.load_diabetes() 회귀 당뇨 데이터 세트
      datasets.load_digits() 분류 0에서 9까지의 숫자 이미지 픽셀 데이터 세트
      datasets.load_iris() 분류 붓꽃에 대한 피처를 가진 데이터 세트
  • 분류와 클러스터링을 위한 표본 데이터 생성기
  • API명 설명
    from sklearn.datasets import make_classification() 분류를 위한 데이터 세트를 만든다. 특히 높은 상관도, 불필요한 속성 등의 노이즈 효과를 위한 데이터를 무작위로 생성한다.
    from sklearn.datasets import make_blobs() 클러스터링을 위한 데이터 세트를 무작위로 생성한다. 군집 지정 개수에 따라 여러 가지 클러스터링을 위한 데이터 세트를 쉽게 만들어준다.

(분류 가상 데이터 생성 참고 자료) https://datascienceschool.net/03%20machine%20learning/09.02%20%EB%B6%84%EB%A5%98%EC%9A%A9%20%EA%B0%80%EC%83%81%20%EB%8D%B0%EC%9D%B4%ED%84%B0%20%EC%83%9D%EC%84%B1.html#make-gaussian-quantiles

  • 예제 데이터 세트의 구성
  • sklearn에 내장된 데이터 세트들은 일반적으로 딕셔너리 형태
  • key : data, target, target_name, feature_names, DESCR로 구성
    • data : feature data set -> ndarray 넘파이 배열 타입
    • target : 분류 시 label값, 회귀일 때는 숫자 결괏값 data set -> ndarray 넘파이 배열 타입
    • target_names : 개별 label의 이름 -> 넘파이 배열 or list 타입
    • feature_names : feature의 이름 -> 넘파이 배열 or list 타입
    • DESCR : data set에 대한 설명과 각 feature의 설명 -> string 타입
  • feature의 데이터 값을 반환받으려면? 내장 데이터 세트 API를 호출 -> key값을 지정

 

In [5]:
# 붓꽃 데이터 세트 생성
from sklearn.datasets import load_iris

iris_data = load_iris()
print(type(iris_data)) 

# load_iris() API의 반환 결과 : sklearn.utils.Bunch Class. 
# Bunch Class는 python의 dictionary 자료형과 유사함
# 데이터 세트에 내장된 대부분의 data set는 이처럼 dictionary 형태의 값을 반환
 
<class 'sklearn.utils.Bunch'>
 
In [6]:
# data set가 dictionary 형태이므로 key값을 확인해보자
keys = iris_data.keys()
print('붓꽃 데이터 세트의 키들:', keys)
 
붓꽃 데이터 세트의 키들: dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename'])
 

key값 사용 : data set.key or data set['key'] 를 이용

 
In [7]:
# data set의 key 중 target_names key를 사용해보면
iris_data.target_names
Out[7]:
array(['setosa', 'versicolor', 'virginica'], dtype='<U10')
In [8]:
# data set의 key 중 target_names key를 사용해보면
iris_data['target_names']
Out[8]:
array(['setosa', 'versicolor', 'virginica'], dtype='<U10')
In [9]:
# load_iris()가 반한하는 객체의 키 feature_names, target_name, data, target이 가리키는 값 출력
print('\n feature_names의 type:', type(iris_data.feature_names))
print(' feature_names의 shape:', len(iris_data.feature_names)) # 1차원 array이기에 len()
print(iris_data.feature_names)

print('\n target_names의 type:', type(iris_data.target_names))
print(' target_names의 shape:', len(iris_data.target_names)) # 1차원 array이기에 len()
print(iris_data.target_names)

print('\n data의 type:', type(iris_data.data))
print(' data의 shape:', iris_data.data.shape) # 2차원 array이기에 shape
# print(iris_data.data)

print('\n target의 type:', type(iris_data.target))
print(' target의 shape:', iris_data.target.shape) # 2차원 array이기에 shape
print(iris_data.target)