본문 바로가기
ML & DL

[Machine Learning] 사이킷 런(scikit-learn) 시작하기

사이킷 런(scikit-learn)

scikit-learn 특징

다양한 머신러닝 알고리즘을 구현한 파이썬 라이브러리

심플하고 일관성 있는 API, 유용한 온라인 문서, 풍부한 예제

머신러닝을 위한 쉽고 효율적인 개발 라이브러리 제공

다양한 머신러닝 관련 알고리즘 개발을 위한 프레임워크와 API 제공

많은 사람들이 사용하며 다양한 환경에서 검증된 라이브러리

scikit-learn 주요 모듈

예제 데이터

  • sklearn.datasets : 사이킷런에 내장되어 예제로 제공하는 데이터 세트

피처 처리

  • sklearn.preprocessing : 데이터 전처리에 필요한 다양한 가공 기능 제공(문자열을 숫자형 코드 값으로 인코딩, 정규화, 스케일링 등)
  • sklearn.feature_selection : 알고리즘에 큰 영향을 미치는 피처를 우선순위대로 셀렉션 작업을 수행하는 다양한 기능 제공
  • sklearn.feature_extraction : 텍스트 데이터나 이미지 데이터의 벡터화된 피처를 추출하는데 사용됨.예를 들어 텍스트 데이터에서 Count Vectorizer나Tf-Idf Vectorizer 등을 생성하는 기능 제공.텍스트 데이터의 피처 추출은 sklearn.feature_extraction.text 모듈에, 이미지 데이터의 피처 추출은 sklearn.feature_extraction.image 모듈에 지원 API가 있음

차원 축소

  • sklearn.decomposition : 차원 축소와 관련한 알고리즘을 지원하는 모듈이다. PCA, NMF, Truncated SVD 등을 통해 차원 축소 기능을 수행할 수 있다.

데이터 분리, 검증 & 파라미터 튜닝

  • sklearn.model_selection : 교차 검증을 위한 학습용/테스트용 분리, 그리드 서치(Grid Search)로 최적 파라미터 추출 등의 API 제공

평가

  • sklearn.metrics : 분류, 회귀, 클러스터링, 페어와이즈(Pairwise)에 대한 다양한 성능 측정 방법 제공Accuracy, Precision, Recall, ROC-AUC, RMSE 등 제공

ML 알고리즘

  • sklearn.ensemble : 앙상블 알고리즘 제공랜덤 포레스트, 에이다 부스트, 그래디언트 부스팅 등을 제공
  • sklearn.linear_model : 주로 선형 회귀, 릿지(Ridge), 라쏘(Lasso) 및 로지스틱 회귀 등 회귀 관련 알고리즘을 지원. 또한 SGD(Stochastic Gradient Desccent) 관련 알고리즘도 제공
  • sklearn.naïve_bayes : 나이브 베이즈 알고리즘 제공. 가우시안 NB. 다항 분포 NB 등
  • sklearn.neighbors : 최근접 이웃 알고리즘 제공. K-NN(K-Nearest Neighborhood) 등
  • sklearn.svm : 서포트 벡터 머신 알고리즘 제공
  • sklearn.tree : 의사 결정 트리 알고리즘 제공
  • sklearn.cluster : 비지도 클러스터링 알고리즘 제공(K-평균, 계층형, DBSCAN 등)

유틸리티

  • sklearn.pipeline : 피처 처리 등의 변환과 ML 알고리즘 학습, 예측 등을 함께 묶어서 실행할 수 있는 유틸리티 제공

estimator API

일관성 : 모든 객체는 일관된 문서를 갖춘 제한된 메소드 집합에서 비롯된 공통 인터페이스 공유

검사(Inspection) : 모든 지정된 파라미터 값은 공개 속성을 노출

제한된 객체 계층 구조

  • 알고리즘만 파이썬 클래스에 의해 표현
  • 데이터 세트는 표준 포맷(Numpy 배열, Pandas DataFrame, Scipy 희소 행렬)으로 표현
  • 매개변수명은 표준 파이썬 문자열 사용

구성 : 많은 머신러닝 작업은 기본 알고리즘의 시퀀스로 나타낼 수 있으며, Scikit-learn은 가능한 곳이라면 어디서든 이방식을 사용

합리적인 기본값 : 모델이 사용자 지정 파라미터를 필요로 할 때 라이브러리가 적절한 기본값을 정의

API 사용 방법

  1. Scikit-learn으로부터 적절한 estimator 클래스를 임포트해서 모델의 클래스 선택
  2. 클래스를 원하는 값으로 인스턴스화해서 모델의 하이퍼파라미터 선택
  3. 데이터를 특징 배열과 대상 벡터로 배치
  4. 모델 인스턴스의 fit() 메소드를 호출해 모델을 데이터에 적합
  5. 모델을 새 데이터에 대해서 적용
    1. 지도 학습 : 대체로 predict() 메소드를 사용해 알려지지 않은 데이터에 대한 레이블 예측
    2. 비지도 학습 : 대체로 transform() 혹은 `predict() 메소드를 사용해 데이터의 속성을 변환하거나 추론

([출처](Choosing the right estimator — scikit-learn 0.24.2 documentation (scikit-learn.org)))

API 사용 예제

import numpy as np
import matplotlib.pyplot as plt
plt.style.use(['seaborn-whitegrid'])

x = 10 * np.random.rand(50)
y = 2 * x + np.random.rand(50)
plt.scatter(x, y);


# 1. Scikit-learn으로부터 적절한 `estimator` 클래스를 임포트해서 모델의 클래스 선택
from sklearn.linear_model import LinearRegression

# 2. 클래스를 원하는 값으로 인스턴스화해서 모델의 하이퍼파라미터 선택
model = LinearRegression(fit_intercept=True)
model

LinearRegression()

# 3. 데이터를 특징 배열과 대상 벡터로 배치
X = x[:, np.newaxis]
X

결과

array([[3.04426651e+00],
       [9.41762838e+00],
       [7.89995748e+00],
       [6.77734766e+00],
       [6.36534795e+00],
       [2.71100529e+00],
       [7.13000629e+00],
       [3.97125309e+00],
       [6.53405217e+00],
       [2.91762487e+00],
       [2.25747516e+00],
       [5.04920275e+00],
       [9.36579711e+00],
       [2.51050052e+00],
       [1.41726963e+00],
       [3.92366304e+00],
       [6.93628514e+00],
       [9.90300120e+00],
       [3.40526335e+00],
       [5.94056074e-01],
       [7.20660030e+00],
       [5.54417242e+00],
       [9.23634627e+00],
       [1.17472758e+00],
       [4.32461449e-01],
       [9.87984259e-01],
       [2.45713299e+00],
       [8.84681351e+00],
       [1.39900393e-01],
       [9.77282690e+00],
       [2.59897942e+00],
       [9.72183458e+00],
       [1.68456488e-01],
       [3.33597827e-03],
       [6.59699395e+00],
       [9.80652165e+00],
       [5.13432031e+00],
       [8.40816805e+00],
       [3.45786329e+00],
       [5.65900440e+00],
       [3.34276428e+00],
       [9.99430818e+00],
       [9.85385919e-01],
       [3.47766568e+00],
       [6.01302724e+00],
       [3.46311949e-01],
       [8.73551537e+00],
       [6.74996773e+00],
       [6.44437220e+00],
       [6.75666063e+00]])
# 4. 모델 인스턴스의 `fit()` 메소드를 호출해 모델을 데이터에 적합
model.fit(X, y)

LinearRegression()

model.coef_

결과

array([1.98795247])
model.intercept_

결과

0.5933236379620546
# 5. 모델을 새 데이터에 대해서 적용
xfit = np.linspace(-1, 11)
Xfit = xfit[:, np.newaxis]
yfit = model.predict(Xfit)

plt.scatter(x, y)
plt.plot(xfit, yfit, '--r');

예제 데이터 세트

분류 또는 회귀용 데이터 세트

API

  • datasets.load_boston() : 미국 보스턴의 집에 대한 특징과 가격 데이터 (회귀용)
  • datasets.load_breast_cancer() : 위스콘신 유방암 특징들과 악성/음성 레이블 데이터 (분류용)
  • datasets.diabetes() : 당뇨 데이터 (회귀용)
  • datasets.load_digits() : 0~9까지의 숫자 이미지 픽셀 데이터 (분류용)
  • datasets.load_iris() : 붓꽃에 대한 특징을 가진 데이터 (분류용)

온라인 데이터 세트

데이터 크기가 커서 온라인에서 데이터를 다운로드 한 후에 불러오는 예제 데이터 세트

API

  • fetch_california_housing() : 캘리포니아 주택 가격 데이터
  • fetch_covtype() : 회귀 분석용 토지 조사 데이터
  • fetch_20newsgroups() : 뉴스 그룹 텍스트 데이터
  • fetch_olivetti_faces() : 얼굴 이미지 데이터
  • fetch_lfw_people() : 얼굴 이미지 데이터
  • fetch_lfw_paris() : 얼굴 이미지 데이터
  • fetch_rcv1() : 로이터 뉴스 말뭉치 데이터
  • fetch_mldata(): ML 웹사이트에서 다운로드

분류와 클러스터링을 위한 표본 데이터 생성

API

  • datasets.make_classifications() : 분류를 위한 데이터 세트 생성. 높은 상관도, 불필요한 속성 등의 노이즈를 고려한 데이터를 무작위로 생성
  • datasets.make_blobs() : 클러스터링을 위한 데이터 세트 생성. 쿤집 지정 개수에 따라 여러 가지 클러스터링을 위한 데이터 세트를 무작위로 생성

예제 데이터 세트 구조

일반적으로 딕셔너리 형태로 구성

data : 특징 데이터 세트

target : 분류용은 레이블 값, 회귀용은 숫자 결과값 데이터

target_names : 개별 레이블의 이름 (분류용)

feature_names : 특징 이름

DESCR : 데이터 세트에 대한 설명과 각 특징 설명

model_selection 모듈

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

교차 검증 분할 및 평가

Esimator의 하이퍼 파라미터 튜닝을 위한 다양한 함수와 클래스 제공

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

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_diabetes

diabetes = load_diabetes()
# 메트릭스에 대한 데이터는 대문자로 표현, 벡터는 소문자로 표현
X_train, X_test, y_train, y_test = train_test_split(diabetes.data, diabetes.target, test_size=0.3)

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

print("학습 데이터 점수 : {}".format(model.score(X_train, y_train)))
print("평가 데이터 점수 : {}".format(model.score(X_test, y_test)))

결과

학습 데이터 점수 : 0.5325326045333665
평가 데이터 점수 : 0.46545015788526456
import matplotlib.pyplot as plt

predicted = model.predict(X_test)
expected = y_test
plt.figure(figsize=(8,4))
plt.scatter(expected, predicted)
plt.plot([30, 350], [30, 350], '--r')
plt.tight_layout()

cross_val_score() : 교차 검증

from sklearn.model_selection import cross_val_score, cross_validate
import numpy as np

scores = cross_val_score(model, diabetes.data, diabetes.target, cv=5) # cross_validate를 위해 몇개로 나눌지 cv로 결정
print("교차 검증 정확도 : {}".format(scores))
print("교차 검증 정확도 : {} +/- {}".format(np.mean(scores), np.std(scores)))

교차 검증 정확도 : [0.42955643 0.52259828 0.4826784  0.42650827 0.55024923]
교차 검증 정확도 : 0.48231812211149394 +/- 0.049266197765632194

GridSearchCV : 교차 검증과 최적 하이퍼 파라미터 찾기

훈련 단계에서 학습한 파라미터에 영향을 받아 최상의 파라미터를 찾는 것은 어려움

다양한 모델의 훈련 과정을 자동화하고, 교차 검사를 사용해 최적 값을 제공

데이터가 적을 때는 유용하나 데이터가 많을 때는 시간이 너무 많이 필요해 부적절

from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import Ridge
import pandas as pd

alpha = [0.001, 0.01, 0.1, 1, 10, 100, 1000]
param_grid = dict(alpha=alpha)

gs = GridSearchCV(estimator=Ridge(), param_grid=param_grid, cv=10)
result = gs.fit(diabetes.data, diabetes.target)

print("최적 점수 : {}".format(result.best_score_))
print("최적 파라미터 : {}".format(result.best_params_))
print(gs.best_estimator_)
pd.DataFrame(result.cv_results_)

결과

최적 점수 : 0.4633240541517593
최적 파라미터 : {'alpha': 0.1}
Ridge(alpha=0.1)

mean_fit_time std_fit_time mean_score_time std_score_time param_alpha params split0_test_score split1_test_score split2_test_score split3_test_score split4_test_score split5_test_score split6_test_score split7_test_score split8_test_score split9_test_score mean_test_score std_test_score rank_test_score
0 0.000836 0.000205 0.000529 0.000057 0.001 {'alpha': 0.001} 0.554415 0.233686 0.356799 0.620259 0.267033 0.619397 0.419907 0.433019 0.433431 0.684984 0.462293 0.145848 3
1 0.000713 0.000033 0.000490 0.000006 0.01 {'alpha': 0.01} 0.546297 0.244132 0.368901 0.613732 0.271717 0.623089 0.426074 0.424759 0.429484 0.680912 0.462910 0.141446 2
2 0.000700 0.000006 0.000490 0.000006 0.1 {'alpha': 0.1} 0.526550 0.244987 0.383530 0.606594 0.286094 0.618033 0.431230 0.441788 0.431968 0.662466 0.463324 0.132681 1
3 0.000695 0.000003 0.000489 0.000004 1 {'alpha': 1} 0.421593 0.168442 0.358004 0.512608 0.284928 0.514264 0.388246 0.484448 0.396502 0.525132 0.405417 0.108385 4
4 0.000707 0.000025 0.000493 0.000005 10 {'alpha': 10} 0.159386 -0.081177 0.152190 0.165690 0.119349 0.186933 0.158147 0.203748 0.153627 0.189440 0.140733 0.077298 5
5 0.000696 0.000003 0.000501 0.000039 100 {'alpha': 100} 0.012468 -0.234480 0.013522 -0.012820 0.004838 0.022647 0.022028 -0.009908 0.015589 0.026427 -0.013969 0.074561 6
6 0.000695 0.000005 0.000488 0.000004 1000 {'alpha': 1000} -0.009602 -0.258118 -0.007849 -0.038479 -0.012933 -0.000932 0.001768 -0.042679 -0.004652 0.002744 -0.037073 0.075191 7

multiprocessing을 이용한 GridSearchCV

import multiprocessing
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression

iris = load_iris()

param_grid = [ {
        'penalty' : ['l1', 'l2'],
        'C' : [1.0, 1.5, 1.8, 2.0, 2.5, 3.0, 3.5] }]

gs = GridSearchCV(estimator=LogisticRegression(), param_grid=param_grid, 
                  scoring='accuracy', cv=10, n_jobs=multiprocessing.cpu_count())
result = gs.fit(iris.data, iris.target)

print("최적 점수 : {}".format(result.best_score_))
print("최적 파라미터 : {}".format(result.best_params_))
print(gs.best_estimator_)
pd.DataFrame(result.cv_results_)

결과

최적 점수 : 0.9800000000000001
최적 파라미터 : {'C': 2.5, 'penalty': 'l2'}
LogisticRegression(C=2.5)

mean_fit_time std_fit_time mean_score_time std_score_time param_C param_penalty params split0_test_score split1_test_score split2_test_score split3_test_score split4_test_score split5_test_score split6_test_score split7_test_score split8_test_score split9_test_score mean_test_score std_test_score rank_test_score
0 0.000073 0.000013 0.000000 0.000000 1 l1 {'C': 1.0, 'penalty': 'l1'} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 8
1 0.065687 0.002607 0.000751 0.000098 1 l2 {'C': 1.0, 'penalty': 'l2'} 1.0 0.933333 1.0 1.0 0.933333 0.933333 0.933333 1.0 1.0 1.0 0.973333 0.032660 4
2 0.000106 0.000012 0.000000 0.000000 1.5 l1 {'C': 1.5, 'penalty': 'l1'} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 9
3 0.069938 0.004614 0.000634 0.000088 1.5 l2 {'C': 1.5, 'penalty': 'l2'} 1.0 0.933333 1.0 1.0 0.933333 0.933333 0.933333 1.0 1.0 1.0 0.973333 0.032660 4
4 0.000107 0.000010 0.000000 0.000000 1.8 l1 {'C': 1.8, 'penalty': 'l1'} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 10
5 0.072654 0.011410 0.001093 0.000902 1.8 l2 {'C': 1.8, 'penalty': 'l2'} 1.0 0.933333 1.0 1.0 0.933333 0.933333 0.933333 1.0 1.0 1.0 0.973333 0.032660 4
6 0.000086 0.000016 0.000000 0.000000 2 l1 {'C': 2.0, 'penalty': 'l1'} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 11
7 0.074082 0.007912 0.000731 0.000134 2 l2 {'C': 2.0, 'penalty': 'l2'} 1.0 0.933333 1.0 1.0 0.933333 0.933333 0.933333 1.0 1.0 1.0 0.973333 0.032660 4
8 0.000098 0.000007 0.000000 0.000000 2.5 l1 {'C': 2.5, 'penalty': 'l1'} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 12
9 0.079781 0.010397 0.000714 0.000139 2.5 l2 {'C': 2.5, 'penalty': 'l2'} 1.0 0.933333 1.0 1.0 0.933333 1.000000 0.933333 1.0 1.0 1.0 0.980000 0.030551 1
10 0.000114 0.000042 0.000000 0.000000 3 l1 {'C': 3.0, 'penalty': 'l1'} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 13
11 0.077625 0.003907 0.000818 0.000388 3 l2 {'C': 3.0, 'penalty': 'l2'} 1.0 0.933333 1.0 1.0 0.933333 1.000000 0.933333 1.0 1.0 1.0 0.980000 0.030551 1
12 0.000109 0.000015 0.000000 0.000000 3.5 l1 {'C': 3.5, 'penalty': 'l1'} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 14
13 0.064777 0.006244 0.000505 0.000130 3.5 l2 {'C': 3.5, 'penalty': 'l2'} 1.0 0.933333 1.0 1.0 0.933333 1.000000 0.933333 1.0 1.0 1.0 0.980000 0.030551 1

prepocessing (데이터 전처리 모듈)

데이터의 특징 스케일링(feature scaling)을 위한 방법으로 표준화(Standardization)와 정규화(Normalization) 사용

표준화 방법 (StandardScaler)

정규화 방법 (MinMaxScaler)

Scikit-learn 에서는 개별 벡터 크기를 맞추는 형태로 정규화

성능 평가 지표

정확도(Accuracy)

정확도는 전체 예측 데이터 건수 중 예측 결과가 동일한 데이터 건수로 계산

Scikit-learn에서는 accuracy_score 함수를 제공

오차 행렬(Confusion Matrix)

True Negative : 예측값을 Negative 값 0으로 예측했고, 실제 값도 Negative 값 0

True Positive : 예측값을 Positive 값 1로 예측했고, 실제 값도 Positive 값 1

False Positive : 예측값을 Positive 값 1로 예측했고, 실제 값은 Negative 값 0

False Negative : 예측값을 Negative 값 0으로 예측했고, 실제 값은 Positive 값 1

정밀도(Precision)와 재현율(Recall)

정밀도 = TP / (FP + TP)

재현율 = TP / (FN + TP)

정확도 = (TN + TP) / (TN + FP + FN + TP)

오류율 = (FN + FP) / (TN + FP + FN + TP)

F1 Score(F-measure)

정밀도와 재현율을 결합한 지표

정밀도와 재현율이 어느 한쪽으로 치우치지 않을 때 높은 값을 가짐

ROC 곡선과 AUC

ROC 곡선은 FPR(False Positive Rate)이 변할 때 TPR(True Positive Rate)이 어떻게 변하는지 나타내는 곡선

  • TPR(True Positive Rate) : TP / (FN + TP), 재현율
  • TNR(True Negative Rate) : TN / (FP + TN)
  • FPR(False Positive Rate) : FP / (FP + TN), 1 - TNR, Sensitivity

AUC(Area Under Curve) 값은 ROC 곡선 밑에 면적을 구한 값 (1에 가까울수록 좋은 값)



References


🏋🏻 개인적으로 공부한 내용을 기록하고 있습니다.
잘못된 부분이 있다면 과감하게 지적해주세요!! 🏋

'ML & DL' 카테고리의 다른 글

[DACON] 물류 유통량 예측 경진대회  (0) 2021.12.23
[Machine Learning] Machine Learning 개념  (0) 2021.11.23

댓글