[F-12] 사이킷런으로 구현해보는 머신러닝

Jake·2022년 1월 13일
0

Aiffel Fundamental

목록 보기
11/23

1. 들어가며

  • 학습목표

    • 머신러닝의 다양한 알고리즘을 소개
    • 사이킷런 라이브러리의 사용법을 익힌다.
    • 사이킷런에서 데이터를 표현하는 방법에 대해 이해하고 훈련용 데이터셋과 테스트용 데이터셋으로 데이터를 나누는 방법을 이해한다.
  • 목차

    1. 다양한 머신러닝 알고리즘

    2. 사이킷런에서 가이드하는 머신러닝 알고리즘

    3. Hello Scikit-learn

    4. 사이킷런의 주요 모듈
      4.1. 데이터 표현법
      4.2. 회귀 모델 실습
      4.3. datasets 모듈
      4.4. 사이킷런 데이터셋을 이용한 분류 문제 실습
      4.5. Estimator

    5. 훈련 데이터와 테스트 데이터 분리하기

2. 머신러닝 알고리즘

  • 지도학습
  • 비지도학습
  • 강화학습
    • 에이전트(Agent): 학습 주체 (혹은 actor, controller)
    • 환경(Environment): 에이전트에게 주어진 환경, 상황, 조건
    • 행동(Action): 환경으로부터 주어진 정보를 바탕으로 에이전트가 판단한 행동
    • 보상(Reward): 행동에 대한 보상을 머신러닝 엔지니어가 설계
    • 강화학습이 궁금하다면 참고할 개발자 커뮤니티

3. 사이킷런에서 가이드하는 머신러닝 알고리즘

사이킷런에서 알고리즘의 Task에는 classification, clustering,regression, dimensionality reduction로 4가지가 있다.

scikit-learn algorithm cheat-sheet

4. Hello Scikit-learn

1) 설치

$ pip install scikit-learn

  • 버전 확인
    사이킷런은 설치명과 모듈을 import할 때 이름이 다르다. 이 모듈을 import할 때는 sklearn이라고 써야한다.
import sklearn
print(sklearn.__version__)
1.0

2) 사이킷런 살펴보기

sckikit-learn 공식 홈페이지

sckikit-learn 사용법 설명

  • 요약
    '사이킷런은 파이썬 기반 머신러닝 라이브러리로 Scipy 및 NumPy 와 비슷한 데이터 표현과 수학 관련 함수를 갖고 있습니다. 일반적으로 머신러닝에서 데이터 가공(ETL)을 거쳐 모델을 훈련하고 예측하는 과정을 거치는데 ETL부분은 ScikitLearn의 transformer()를 제공하고, 모델의 훈련과 예측은 Estimator 객체를 통해 수행되며, Estimator에는 각각 fit()(훈련), predict()(예측)을 행하는 메소드가 있습니다. 모델의 훈련과 예측이 끝나면 이 2가지는 작업을 Pipeline()으로 묶어 검증을 수행합니다.'

5. 사이킷런의 주요 모듈

사이킷런 알고리즘은 파이썬 클래스로 구현되어 있고, 데이터셋은 Numpy의 ndarray, Pandas의 DatatFrame, SciPy의 Sparse Matrix를 이용해 나타낼 수 있다.
그리고 훈련과 예측 등 머신러닝 모델을 다룰 때는 CoreAPI라고 불리는 fit(), transformer(), predict()와 같은 함수들을 이용한다.

다음은 공식 홈페이지에서 소개하는 사이킷런의 모듈들이다.
Scikit-learn: API Reference

이들 중 주로 사용하는 API들은 다음과 같다.


1) 데이터 표현법

사이킷런에서는 데이터 표현 방식을 보통 2가지로 나타내고, 이는 특성 행렬(Feature Matrix)타켓 벡터(Target Vector)이다.
출처

  • 특성 행렬(Feature Matrix)
    • 입력 데이터를 의미한다.
    • 특성: 데이터에서 수치, 이산, 불리언 값으로 표현되는 개별 관측치. 행렬에서는 열에 해당한다.
    • 표본: 각 입력 데이터, 특성 행렬에서는 행에 해당하는 값
    • n_samples: 행의 개수(표본 수)
    • n_features: 열의 개수(특성의 개수)
    • X: 통상적으로 특성 행렬은 변수명 X로 표기한다.
    • [n_samples, n_features]: [행,열] 형태의 2차원 배열 구조를 사용하며 이는 NumPy의 ndarray, Pandas의 DataFrame, SciPy의 Sparse Matrix를 사용하여 나타낼 수 있다.
  • 타겟 벡터(Target Vector)
    • 입력 데이터의 정답을 의미
    • 목표 라벨: Feature Matrix로부터 predict하고자 하는 값
    • n_samples: 벡터의 길이(라벨의 개수)
    • 타겟 벡터에서는 n_features가 존재하지 않는다.
    • y: 통상적으로 타겟 벡터는 변수명 y로 표기한다.
    • 보통 1차원 벡터로 나타내며, 이는 NumPy의 ndarray, Pandas의 Series를 사용하여 나타낼 수 있다.

❗️ 주의: Feature matrix X의 n_samples == Target Vector y의 n_samples !!

2) 회귀 모델 실습

위 데이터와 머신러닝의 회귀 모델을 이용해 데이터를 예측하는 모델을 만들어보자.

import numpy as np
import matplotlib.pyplot as plt
r = np.random.RandomState(10)
x = 10 * r.rand(100)
y = 2 * x - 3 * r.rand(100)
plt.scatter(x,y)
<matplotlib.collections.PathCollection at 0x7f643315f5e0>

x.shape, y.shape # 입력데이터와 정답데이터 모두 (100,)으로 1차원 벡터
((100,), (100,))

사이킷런에서 머신러닝 모델을 사용하기 위해서 모델 객체를 생성하자.
LinearRegression 모델을 사용해보자. 이는 sklearn.linear_model 내에 있다.

from sklearn.linear_model import LinearRegression
model = LinearRegression()
model
LinearRegression()

이제 fit() 메서드를 이용해 모델을 훈련시켜보자.
인자로는 행렬 형태의 입력데이터1차원 벡터 형태의 정답을 넣어준다.

기존 x data가 1차원 벡터 형태이므로, 행렬 형태로 바꾸어서 넣어줘야 한다!
x는 numpy의 ndarray 타입이니, reshape()를 사용해 바꿔주자.

X = x.reshape(100,1)
X.shape
(100, 1)

이제 X를 fit()의 인자로 넣어주자.

model.fit(X,y)
LinearRegression()

training이 완료된 모델에 새 데이터를 넣고 predict를 해보자.
새로운 데이터는 np.linspace()를 이용해서 생성한다.

x_new = np.linspace(-1, 11, 100)
#print(x_new)
X_new = x_new.reshape(100,1)
#print(X_new)
y_new = model.predict(X_new)

training된 모델의 성능을 평가해보자.
모델의 성능 평가 관련 모듈은 sklearn.metrics에 저장되어 있다.
회귀 모델의 경우 RMSE(Root Mean Square Error)를 사용해 평가한다.

from sklearn.metrics import mean_squared_error

error = np.sqrt(mean_squared_error(y,y_new))

print(error)
9.299028215052264

좀 더 직관적으로 regression line을 확인해보자.

plt.scatter(x, y, label='input data')
plt.plot(X_new, y_new, color='red', label='regression line')
plt.show()

3) dataset 모듈

sklearn.datasets 모듈은 크게 dataset loadersdataset fetchers로 나뉘며, 각각 Toy datasetReal world dataset을 제공한다.

예시로 와인 데이터셋을 사용해보자.
와인 분류 데이터를 다운로드하고 자료형을 살펴보자.

from sklearn.datasets import load_wine
data = load_wine()
type(data)
sklearn.utils.Bunch

Bunch는 파이썬의 딕셔너리와 유사한 형태의 데이터 타입이다.
data를 출력해보면 데이터들이 중괄호에 담겨 있고, 콜론을 이용해서 구분되어 있다.
번치 데이터 타입에도 keys()를 사용할 수 있다.

data.keys()
dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names'])

사이킷런 데이터셋을 이용한 분류 문제 실습

import pandas as pd
from sklearn.ensemble import RandomForestClassifier #분류 문제
from sklearn.metrics import accuracy_score #성능평가
from sklearn.metrics import classification_report #성능평가


#DataFrame으로 나타내기
pd.DataFrame(data.data, columns=data.feature_names)

#머신러닝
X = data.data
y = data.target
 
model = RandomForestClassifier()
model.fit(X, y)

y_pred = model.predict(X)

#타겟 벡터 즉 라벨인 변수명 y와 예측값 y_pred을 각각 인자로 넣습니다. 
print(classification_report(y, y_pred))
#정확도를 출력합니다. 
print("accuracy = ", accuracy_score(y, y_pred))
              precision    recall  f1-score   support

           0       1.00      1.00      1.00        59
           1       1.00      1.00      1.00        71
           2       1.00      1.00      1.00        48

    accuracy                           1.00       178
   macro avg       1.00      1.00      1.00       178
weighted avg       1.00      1.00      1.00       178

accuracy =  1.0

위와 같이 정확도가 100%가 나와버렸다. 이 부분에 대한 해답은 6. 훈련 데이터와 테스트 데이터 분리하기를 참고하자.

5) Estimator

앞서 실습에서 머신러닝 모델의 훈련은 fit()메서드를 이용하고, 예측은 predict()메서드를 이용했다.
사이킷런의 장점은 API가 매우 일관성 있게 설계되어 있다는 점이다.

이번에는 모델 훈련에서 핵심이 되는 API를 살펴보자.

Esitmator 객체

Estimator: 데이터셋을 기반으로 머신러닝 모델의 파라미터를 추정하는 객체
사이킷런의 모든 머신러닝 모델은 Estimator라는 파이썬 클래스로 구현되어 있다. 추정을 하는 과정 즉, 훈련은 Estimatorfit() 메서드를 통해 이루어지고, 예측은 predict() 메서드를 통해 이뤄진다.

앞서 사용한 Estimator객체는 LinearRegression()RandomForestClassifier()이다.

와인 분류 문제의 해결과정은 다음 그림과 같이 표현할 수 있다.

선형 회귀 문제의 해결과정은 다음 그림과 같이 표현할 수 있다.

위 예와 다르게, 타겟 벡터가 없는 경우는 어떻게 표현할까? 비지도학습의 경우 fit() 메서드의 인자로 Target Vector를 넣지 않는다.

사이킷런의 Estimator객체를 사용한다면 비지도학습, 지도학습에 관계없이 학습과 예측을 할 수 있다.

6. 훈련 데이터와 테스트 데이터 분리하기

앞서 와인 분류 문제에서 정확도가 100%가 나온 이유는, 훈련에 사용되는 데이터와 예측에 사용되는 데이터에 같은 값을 넣었기 때문이다. 즉, 동일한 데이터로 훈련과 예측을 해서 정확도가 100%가 나온 것이다!

훈련 데이터와 테스트 데이터 직접 분리하기


직접 shape를 계산하여, 8:2로 나눠보자.

from sklearn.datasets import load_wine
data = load_wine()

X_train = data.data[:142]
X_test = data.data[142:]
print(X_train.shape, X_test.shape)

y_train = data.target[:142]
y_test = data.target[142:]
print(y_train.shape, y_test.shape)
(142, 13) (36, 13)
(142,) (36,)

훈련 데이터와 테스트 데이터의 분리가 끝났다. 그럼 다시 훈련과 예측을 해보자.

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

model = RandomForestClassifier()
model.fit(X_train, y_train)

y_pred = model.predict(X_test)

print("정답률=", accuracy_score(y_test, y_pred))
정답률= 0.9722222222222222

train_test_split() 사용해서 분리하기


사이킷런에서는 위와 같은 작업을 API로 제공하고 있다.
바로 model_selectiontrain_test_split()함수이다.

import pandas as pd
from sklearn.ensemble import RandomForestClassifier #분류 문제
from sklearn.metrics import accuracy_score #성능평가
from sklearn.metrics import classification_report #성능평가
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split

# 데이터셋 로드하기
data = load_wine()

# 훈련용 데이터셋 나누기
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=50)

# 훈련하기
model = RandomForestClassifier()
model.fit(X_train, y_train)

# 예측하기
y_pred = model.predict(X_test)

# 정답률 출력하기
print(f"accuracy = {accuracy_score(y_test, y_pred)}" )
accuracy = 0.9166666666666666

7. 마무리

사이킷런에서 핵심이 되는 Estimator를 이용해 모델을 어떻게 훈련하고 예측하는지 알아보았다.
또한, 훈련 데이터와 테스트 데이터를 분리하는 방법에 대해서도 학습했다.

이 외에도 평가와 관련된 항목들은 sklearn.matrics 모듈에 들어가 있고, 여기서 언급하진 않았지만, sklearn.preprocessing모듈 역시 중요한 API 중 하나이다.

사이킷런 주요 모듈을 다시 한번 보고 마무리하자.

profile
Nice to meet you. I would really appreciate your feedbacks. Thank you

0개의 댓글