사전 scikit-learn
구현체

scikit-learn

gabury1고친 사람 github-actions[bot]

scikit-learn 은 파이썬 코드로 머신러닝 모델을 학습시키고 평가하게 해 줍니다. 데이터를 넣어 학습시키는 일과 새 값을 예측하는 일을 메서드 호출 한 줄씩으로 끝냅니다. 알고리즘이 달라도 부르는 방법이 같아서 모델을 바꿔 가며 비교하기 쉽습니다.

쉽고 빠른 이해

scikit-learn 은 데이터로 모델을 학습시키고 예측을 받아 내는 파이썬 도구입니다. 집 면적과 가격을 몇 쌍 주고 새 면적의 가격을 묻는 일이 코드 몇 줄로 끝납니다.

알고리즘마다 쓰는 법이 다르면 다른 알고리즘을 시험할 때마다 코드를 새로 짜야 합니다. scikit-learn 에서는 모든 모델이 같은 메서드 이름을 씁니다. 모델을 만드는 한 줄만 바꾸면 나머지 코드는 손대지 않아도 됩니다.

어떻게 쓰는가:

  1. 데이터를 표로 준비합니다. 행 하나가 예시 하나, 열 하나가 값의 종류 하나입니다
  2. 모델 객체를 만들고 fit 으로 학습시킵니다
  3. predict 로 새 데이터의 답을 받습니다
  4. 데이터를 나눠 돌려 보는 함수로 모델이 처음 보는 데이터에서도 맞히는지 점수를 냅니다

대가도 있습니다. 데이터가 한 컴퓨터의 메모리에 다 올라가야 합니다. 그래픽 카드로 돌리는 큰 신경망은 다루지 않습니다.

상세

scikit-learn 은 파이썬용 머신러닝 라이브러리입니다. 머신러닝은 판단 규칙을 사람이 짜는 대신 예시 데이터에서 그 규칙을 뽑아내는 일입니다. 스팸 메일 수천 통과 정상 메일 수천 통을 주면 둘을 가르는 기준을 프로그램이 스스로 세웁니다.

이렇게 세운 기준을 담은 것이 모델입니다. 새 메일이 오면 모델이 그 기준으로 스팸인지 아닌지 답합니다.

설치는 pip 으로 pip install scikit-learn 을 합니다. 코드에서 불러올 때는 sklearn 이라는 이름을 씁니다. 배열 계산은 NumPy 에, 일부 수학 계산은 SciPy 에 맡깁니다.

이 절은 먼저 scikit-learn 이 데이터를 어떤 모양으로 받는지 봅니다. 그다음 모든 모델이 같은 메서드를 갖는 규약을 작은 예제 둘로 읽습니다. 이어서 여러 단계를 하나로 묶는 파이프라인과 교차 검증을 봅니다. 끝으로 이 라이브러리가 하지 않기로 한 일과 학습한 모델을 저장하는 법을 봅니다.

행은 예시, 열은 특성

scikit-learn 의 모든 모델은 입력을 같은 모양으로 받습니다. 2차원 표 하나와 1차원 목록 하나입니다. 모양이 하나로 정해져 있어서 모델을 바꿔도 데이터를 준비하는 코드는 그대로 둡니다.

표의 행 하나는 예시 하나입니다. 이 예시를 표본이라고 부릅니다.

표의 열 하나는 예시를 설명하는 값 한 종류입니다. 이 값을 특성이라고 부릅니다. 모델은 집 자체를 보지 못합니다. 면적이나 방 수 같은 특성만 봅니다.

1차원 목록에는 예시마다 맞혀야 할 답이 들어갑니다. 이 답을 타깃이라고 부릅니다. 관례로 표는 X, 답 목록은 y 라는 변수에 담습니다.

면적 방 수 가격
집 1 59 2 5억
집 2 84 3 7억
집 3 110 4 9억

위 표에서 면적과 방 수 두 열이 X 가 됩니다. 가격 열이 y 가 됩니다. 집이 셋이므로 X 는 3행 2열, y 는 값 세 개짜리 목록입니다.

X 로는 NumPy 배열을 넘기는 것이 기본입니다. 파이썬 리스트를 넘겨도 안에서 NumPy 배열로 바꿉니다. 표 데이터를 다루는 pandas 의 데이터프레임도 받습니다.

추정기와 fit · predict

scikit-learn 은 데이터에서 무언가를 배우는 객체를 전부 추정기(estimator)라고 부릅니다. 추정기는 모두 fit 이라는 메서드를 갖습니다. fit(X, y) 를 부르면 추정기가 데이터를 보고 규칙을 배웁니다.

답을 내는 추정기는 predict 메서드도 갖습니다. predict(X) 에 새 데이터를 넣으면 배운 규칙으로 답을 돌려줍니다. 이렇게 답을 내는 추정기가 흔히 말하는 모델입니다.

아래는 직선 하나로 값을 맞히는 선형 회귀 모델에 fit 과 predict 를 쓴 예입니다.

Python
from sklearn.linear_model import LinearRegression

X = [[1], [2], [3]]
y = [3, 5, 7]        # y = 2x + 1

model = LinearRegression()
model.fit(X, y)
model.coef_          # 기울기 약 2
model.intercept_     # 절편 약 1
model.predict([[4]]) # 약 9 하나 든 배열

y 의 세 값은 모두 「2를 곱하고 1을 더한다」를 따릅니다. fit 은 이 규칙을 찾아 기울기와 절편을 객체 안에 남깁니다. predict 는 학습에 없던 4를 받아 그 규칙으로 9를 냅니다.

coef_ 와 intercept_ 처럼 밑줄로 끝나는 이름은 fit 이 데이터에서 배운 값입니다. fit 을 부르기 전에는 이 속성이 없습니다. 이름만 보고 배운 값인지 아닌지 가를 수 있게 정한 관례입니다.

이 규약이 있는 이유는 모델을 바꿔 보기 쉽게 하려는 것입니다. LinearRegression() 을 결정 트리 모델인 DecisionTreeRegressor() 로 바꿔도 fit 과 predict 줄은 그대로입니다. 어느 알고리즘이 이 데이터에 맞는지는 대개 여러 개를 돌려 봐야 압니다.

하이퍼파라미터는 생성자에

추정기를 만들 때 괄호 안에 넘기는 값은 사람이 정하는 설정입니다. 결정 트리를 몇 층까지 키울지 같은 값입니다. 이런 값을 하이퍼파라미터라고 부릅니다.

하이퍼파라미터는 fit 이 배우는 값과 다릅니다. 기울기는 데이터를 보고 정해지지만 트리의 깊이 제한은 학습 전에 사람이 정합니다. scikit-learn 은 하이퍼파라미터를 생성자 인자로, fit 이 배운 값을 밑줄로 끝나는 속성으로 갈라 둡니다.

Python
from sklearn.tree import DecisionTreeRegressor

tree = DecisionTreeRegressor(max_depth=3)

max_depth=3 이 하이퍼파라미터입니다. 트리가 세 층보다 깊어지지 않게 막습니다. 너무 깊은 트리는 학습 데이터를 외워 버려 새 데이터에서 틀리기 쉽습니다. 이렇게 외워 버리는 현상을 과적합이라고 부릅니다.

변환기와 fit · transform

모든 추정기가 답을 내는 것은 아닙니다. 데이터를 다른 모양으로 바꿔 주는 추정기도 있습니다. 이런 추정기를 변환기(transformer)라고 부릅니다. 변환기는 predict 대신 transform 메서드를 갖습니다.

대표적인 변환기가 StandardScaler 입니다. 이 변환기는 표준화를 합니다. 표준화는 열마다 평균을 빼고 그 열의 값이 퍼진 정도로 나누는 일입니다.

퍼진 정도는 표준편차라는 수로 잽니다. 표준편차는 값들이 평균에서 얼마나 넓게 떨어져 있는지를 나타냅니다. 표준화를 거친 열은 평균이 0, 표준편차가 1이 됩니다.

표준화가 필요한 까닭은 열마다 숫자의 크기가 다르기 때문입니다. 면적은 수십에서 수백, 방 수는 한 자릿수입니다. 이대로 넣으면 숫자가 큰 면적 열이 결과를 좌우하기 쉽습니다. 표준화하면 두 열이 비슷한 범위로 들어옵니다.

Python
from sklearn.preprocessing import StandardScaler

X = [[1], [2], [3]]
sc = StandardScaler()
sc.fit(X)
sc.mean_             # 평균 2 하나 든 배열
sc.transform([[2]])  # 0
sc.transform([[3]])  # 약 1.22

fit 은 데이터의 평균과 표준편차를 배워 둡니다. transform 은 배워 둔 두 값으로 새 값을 바꿉니다. 2는 평균과 같아서 0이 됩니다. 3은 평균보다 표준편차 하나 남짓 커서 약 1.22가 됩니다.

모델을 평가할 때는 데이터를 학습에 쓰는 학습용 데이터와 점수를 매길 때만 쓰는 평가용 데이터로 나눠 둡니다. 평가용을 따로 떼어 두는 까닭은 모델이 처음 보는 데이터에서도 맞히는지 재려는 것입니다. 학습에 쓴 데이터로 점수를 내면 외운 답을 다시 맞힌 것인지 가릴 수 없습니다.

배우는 일과 바꾸는 일을 두 메서드로 가른 데는 이유가 있습니다. 평가용 데이터까지 넣어 평균을 구하면 모델이 평가용 데이터의 정보를 미리 본 셈이 됩니다. 그러면 점수가 실제보다 좋게 나옵니다. 이런 고장을 데이터 누수라고 부릅니다.

그래서 fit 은 학습용 데이터에만 부릅니다. transform 은 학습용과 평가용 양쪽에 부릅니다. 학습용 데이터에는 두 일을 한 번에 하는 fit_transform 을 써도 됩니다.

단계를 잇는 파이프라인

실무에서는 변환기 몇 개를 거친 뒤 모델에 넣는 일이 흔합니다. 이때 단계마다 fit 과 transform 을 손으로 부르면 순서를 틀리기 쉽습니다. 평가용 데이터에 fit 을 부르는 실수 하나로 데이터 누수가 생깁니다.

scikit-learn 의 Pipeline 은 여러 단계를 추정기 하나로 묶습니다. 파이프라인은 처리를 여러 단계로 나눠 차례로 흘려보내는 구조입니다. 묶인 파이프라인도 추정기라서 fit 과 predict 를 그대로 씁니다.

아래 코드부터는 X 와 y 를 앞의 세 줄짜리 예보다 큰, 행이 수백 개인 데이터라고 봅니다. 먼저 데이터를 학습용과 평가용으로 나눠야 합니다. train_test_split 함수가 이 일을 합니다. 행을 섞은 뒤 정해진 비율로 두 묶음을 돌려줍니다.

Python
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline

X_train, X_test, y_train, y_test = train_test_split(X, y)
pipe = make_pipeline(StandardScaler(), LinearRegression())
pipe.fit(X_train, y_train)
pipe.predict(X_test)

pipe.fit 을 부르면 앞 단계가 fit_transform 으로 학습용 데이터를 바꿉니다. 마지막 모델은 바뀐 데이터로 fit 합니다.

pipe.predict 를 부르면 앞 단계는 transform 만 합니다. 마지막 모델은 predict 합니다. 평가용 데이터에는 fit 이 한 번도 불리지 않습니다.

flowchart TD
    subgraph 학습["pipe.fit · 학습용 데이터"]
        A["X_train"] --> B["StandardScaler · fit_transform"]
        B --> C["LinearRegression · fit"]
    end
    subgraph 예측["pipe.predict · 평가용 데이터"]
        D["X_test"] --> E["StandardScaler · transform"]
        E --> F["LinearRegression · predict"]
    end
    C -. 배운 값을 넘긴다 .-> F
    B -. 배운 평균과 표준편차 .-> E

두 묶음은 같은 객체를 지나지만 부르는 메서드가 다릅니다. 위 묶음에서 배운 평균과 기울기가 아래 묶음에서 쓰입니다.

교차 검증과 하이퍼파라미터 탐색

학습용과 평가용을 한 번만 나누면 점수가 그 나눔에 따라 흔들립니다. 운 좋게 쉬운 데이터가 평가용에 몰릴 수도 있습니다. 교차 검증은 데이터를 여러 조각으로 나눠 조각마다 돌아가며 평가용으로 쓰는 방법입니다. 그래서 점수를 여럿 얻습니다.

교차 검증은 cross_val_score 함수로 돌립니다. 추정기와 데이터, 조각 수를 넘기면 조각마다 학습과 평가를 합니다. 점수는 배열로 돌려줍니다.

Python
from sklearn.model_selection import cross_val_score

scores = cross_val_score(pipe, X, y, cv=5)
scores.shape   # (5,)
scores.mean()  # 다섯 점수의 평균

cv=5 는 다섯 조각으로 나누라는 뜻이라 점수도 다섯 개입니다. 여기에 파이프라인을 넘기면 차례마다 그때 평가용으로 쓰는 조각을 뺀 나머지로만 표준화를 fit 합니다. 평가용 조각의 평균은 그 차례의 학습에 섞이지 않습니다. 그래서 교차 검증 안에서도 데이터 누수가 생기지 않습니다.

하이퍼파라미터를 고를 때도 같은 방법을 씁니다. GridSearchCV 는 후보 값 목록을 받아 조합마다 교차 검증을 돌립니다. 그리고 점수가 가장 높은 조합을 고릅니다. 이렇게 후보를 빠짐없이 돌려 보는 방법을 그리드 서치라고 부릅니다.

조합을 고른 뒤에는 그 조합으로 넘겨받은 학습용 데이터 전체에 다시 fit 합니다. 그래서 GridSearchCV 객체에 바로 predict 를 부르면 고른 조합으로 학습한 모델이 답합니다.

하지 않기로 한 일

scikit-learn 은 데이터를 메모리 위에 올린 배열 하나로 받습니다. 입력 모양이 이것 하나뿐이라 알고리즘마다 데이터를 받는 방식이 갈리지 않습니다. 대신 한 컴퓨터의 메모리를 넘는 데이터는 다루지 못합니다. 여러 컴퓨터에 나눠 학습시키려면 Apache Spark 같은 분산 처리 도구를 씁니다.

큰 신경망도 다루지 않습니다. 간단한 신경망 모델 몇 가지는 들어 있지만 GPU(Graphics Processing Unit, 그래픽 처리 장치)로 학습시키지는 못합니다. 이미지나 음성처럼 층이 깊은 신경망이 필요한 일은 PyTorch 나 TensorFlow 같은 딥러닝 도구가 맡습니다.

이 선택 덕분에 scikit-learn 이 잘 맞는 곳도 또렷합니다. 회원 정보나 주문 기록 집계처럼 행과 열로 정리되는 데이터를 다루는 일입니다.

그런 데이터로 정해진 몇 가지 답 중 하나를 고르는 일을 분류라고 합니다. 앞에서 본 스팸 메일 가르기가 분류입니다.

집값처럼 숫자 값을 맞히는 일은 회귀라고 합니다. 앞에서 본 선형 회귀가 여기에 속합니다. 답이 정해지지 않은 데이터를 비슷한 것끼리 묶는 군집화도 같은 규약으로 합니다.

scikit-learn 바깥의 라이브러리도 이 규약을 따르곤 합니다. XGBoost 나 LightGBM 은 자기 모델에 fit 과 predict 를 붙여 둡니다. 그래서 scikit-learn 의 파이프라인과 교차 검증에 그대로 끼워 넣을 수 있습니다.

학습한 모델 저장하기

학습한 추정기는 파이썬 객체라서 직렬화해 파일로 저장합니다. 직렬화는 메모리 위의 객체를 바이트로 바꿔 파일에 쓰는 일입니다. 보통 파이썬 표준 모듈인 pickle 이나 이를 큰 배열에 맞게 다듬은 joblib 을 씁니다.

저장한 파일은 객체 안의 구조를 바이트로 옮긴 것입니다. 그래서 다른 판의 scikit-learn 에서 불러오면 안 열리거나 다르게 동작할 수 있습니다. 모델을 학습시킨 환경과 예측을 내는 서버의 scikit-learn 판을 같게 맞춰 두는 것이 이 때문입니다.

관련 항목

scikit-learn 이 기대는 파이썬 라이브러리

Python · NumPy · SciPy · pandas · joblib · Jupyter

scikit-learn 이 정한 객체 규약

추정기 · 변환기 · 파이프라인 · 하이퍼파라미터 · 특성 · 타깃 변수 · 표본

scikit-learn 으로 푸는 문제의 종류

분류 · 회귀 · 군집화 · 차원 축소 · 이상 탐지

scikit-learn 에 든 알고리즘

선형 회귀 · 로지스틱 회귀 · 결정 트리 · 랜덤 포레스트 · 서포트 벡터 머신 · k-평균 군집화 · 주성분 분석 · k-최근접 이웃

scikit-learn 으로 모델을 평가하는 방법

교차 검증 · k-겹 교차 검증 · 훈련 데이터 · 테스트 데이터 · 그리드 서치 · 정확도 · 평가 지표 · 과적합 · 데이터 누수

scikit-learn 이 데이터를 다듬는 전처리

전처리 · 표준화 · 정규화 · 원-핫 인코딩 · 결측치 · 표준편차

scikit-learn 과 같은 인터페이스를 따르는 라이브러리

XGBoost · LightGBM · CatBoost · imbalanced-learn

scikit-learn 이 맡지 않는 일을 맡는 도구

PyTorch · TensorFlow · 딥러닝 · GPU · Apache Spark

학습한 모델을 저장하는 방법

직렬화 · pickle · joblib · 모델 서빙

scikit-learn 이 속하는 상위 분류

머신러닝 · 데이터 과학 · 지도학습 · 비지도학습 · 라이브러리

다른 이름: sklearn · 사이킷런 · 사이킷 런