사이킷 런(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 사용 방법
- Scikit-learn으로부터 적절한
estimator
클래스를 임포트해서 모델의 클래스 선택 - 클래스를 원하는 값으로 인스턴스화해서 모델의 하이퍼파라미터 선택
- 데이터를 특징 배열과 대상 벡터로 배치
- 모델 인스턴스의
fit()
메소드를 호출해 모델을 데이터에 적합 - 모델을 새 데이터에 대해서 적용
- 지도 학습 : 대체로
predict()
메소드를 사용해 알려지지 않은 데이터에 대한 레이블 예측 - 비지도 학습 : 대체로
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 |
댓글