scikit-learn (sklearn) 치트시트
마지막 업데이트
데이터 불러오기와 분할
무엇보다 먼저 테스트 세트를 떼어 두고, 맨 마지막에만 확인하세요.
| 작업 | 코드 |
|---|---|
| 분할 함수 임포트 | from sklearn.model_selection import train_test_split |
| DataFrame에서 특성과 타깃 분리 | X = df.drop(columns="target")
y = df["target"] |
| 내장 데이터셋을 pandas로 | from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True, as_frame=True) |
| 실험용 합성 데이터 | from sklearn.datasets import make_classification
X, y = make_classification(n_samples=500, n_features=8, random_state=0) |
| 80/20 학습/테스트 분할 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) |
| 양쪽에 클래스 비율 유지 | train_test_split(X, y, test_size=0.2, stratify=y, random_state=42) |
| 학습, 검증, 테스트 (60/20/20) | X_tmp, X_test, y_tmp, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
X_train, X_val, y_train, y_val = train_test_split(X_tmp, y_tmp, test_size=0.25, random_state=0) |
특성 전처리
변환기는 학습 데이터로만 fit하고, 두 세트 모두 transform하세요. 테스트 데이터로 fit하면 정보가 누수돼요.
| 작업 | 코드 |
|---|---|
| 임포트 | from sklearn.preprocessing import StandardScaler, MinMaxScaler, OneHotEncoder, OrdinalEncoder |
| 평균 0, 표준편차 1로 스케일링 | scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train[["age", "income"]])
X_test_s = scaler.transform(X_test[["age", "income"]]) |
| 0에서 1 범위로 스케일링 | MinMaxScaler().fit_transform(X_train[["age", "income"]]) |
| 범주 원-핫 인코딩 | enc = OneHotEncoder(handle_unknown="ignore", sparse_output=False)
enc.fit_transform(X_train[["city"]]) |
| 순서형 범주를 숫자로 인코딩 | OrdinalEncoder(categories=[["low", "mid", "high"]]).fit_transform([["mid"], ["high"]]) |
| 결측값 채우기 | from sklearn.impute import SimpleImputer
SimpleImputer(strategy="median").fit_transform(X_train[["age", "income"]]) |
| 다항식과 상호작용 특성 | from sklearn.preprocessing import PolynomialFeatures
PolynomialFeatures(degree=2, include_bias=False).fit_transform(X_train[["age", "income"]]) |
| 배열 대신 DataFrame으로 받기 | scaler.set_output(transform="pandas") |
| 텍스트 레이블을 정수로 | from sklearn.preprocessing import LabelEncoder
LabelEncoder().fit_transform(["cat", "dog", "cat"]) |
모델 선택
단순하게 시작하고, 단순한 모델의 점수를 넘어야 할 기준으로 삼으세요.
| 문제 | 먼저 시도 | 다음으로 시도 |
|---|---|---|
| 숫자 예측 (회귀) | LinearRegression(), Ridge(alpha=1.0) | RandomForestRegressor(), HistGradientBoostingRegressor() |
| 클래스 예측 (분류) | LogisticRegression(max_iter=1000) | RandomForestClassifier(), HistGradientBoostingClassifier() |
| 데이터가 적고, 비슷한 점끼리 레이블이 같음 | KNeighborsClassifier(n_neighbors=5) | SVC(kernel="rbf") |
| 사람이 읽을 수 있는 규칙 | DecisionTreeClassifier(max_depth=3) | RandomForestClassifier() |
| 레이블 없이 행 그룹화 | KMeans(n_clusters=3) | DBSCAN(eps=0.5) |
| 시각화나 속도를 위해 특성 줄이기 | PCA(n_components=2) | TSNE(n_components=2) |
| 이상한 행 찾기 | IsolationForest(random_state=0) | LocalOutlierFactor() |
모델 학습
모든 추정기는 같은 패턴을 따라요. 설정과 함께 만들고 fit을 호출하세요.
| 작업 | 코드 |
|---|---|
| 모든 모델의 공통 패턴 | model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train) |
| 선형 회귀 | from sklearn.linear_model import LinearRegression
LinearRegression() |
| 규제가 있는 선형 회귀 | from sklearn.linear_model import Ridge, Lasso
Ridge(alpha=1.0), Lasso(alpha=0.1) |
| 로지스틱 회귀 (분류) | from sklearn.linear_model import LogisticRegression
LogisticRegression(C=1.0, max_iter=1000) |
| k-최근접 이웃 | from sklearn.neighbors import KNeighborsClassifier
KNeighborsClassifier(n_neighbors=5) |
| 결정 트리 | from sklearn.tree import DecisionTreeClassifier
DecisionTreeClassifier(max_depth=3, random_state=0) |
| 랜덤 포레스트 | from sklearn.ensemble import RandomForestClassifier
RandomForestClassifier(n_estimators=200, random_state=0) |
| 그레이디언트 부스팅 (대용량에서 빠름) | from sklearn.ensemble import HistGradientBoostingClassifier
HistGradientBoostingClassifier(random_state=0) |
| 서포트 벡터 머신 | from sklearn.svm import SVC
SVC(kernel="rbf", C=1.0) |
| 나이브 베이즈 | from sklearn.naive_bayes import GaussianNB
GaussianNB() |
| 항상 다수 클래스를 고르는 기준 모델 | from sklearn.dummy import DummyClassifier
DummyClassifier(strategy="most_frequent") |
예측과 확인
| 작업 | 코드 |
|---|---|
| 클래스 또는 값 예측 | y_pred = model.predict(X_test) |
| 양성 클래스 확률 | model.predict_proba(X_test)[:, 1] |
| 빠른 점수: 정확도 또는 R² | model.score(X_test, y_test) |
| 선형 모델의 계수 | model.coef_, model.intercept_ |
| 트리 모델의 특성 중요도 | pd.Series(forest.feature_importances_, index=X_train.columns).sort_values() |
| 특성을 섞어 보는 순열 중요도 | from sklearn.inspection import permutation_importance
permutation_importance(model, X_test, y_test, random_state=0).importances_mean |
| 모델이 아는 클래스 레이블 | model.classes_ |
| 설정 확인과 변경 | model.get_params(), model.set_params(C=0.5) |
| 결정 트리 그리기 | from sklearn.tree import plot_tree
plot_tree(tree, filled=True, feature_names=list(X_train.columns)) |
분류 평가 지표
정확도만 보면 드문 클래스의 오류가 가려져요. 정밀도, 재현율, 혼동 행렬도 함께 확인하세요.
| 작업 | 코드 |
|---|---|
| 임포트 | from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score |
| 정확도 | accuracy_score(y_test, y_pred) |
| 정밀도, 재현율, F1 | precision_score(y_test, y_pred), recall_score(y_test, y_pred), f1_score(y_test, y_pred) |
| 다중 클래스 F1 | f1_score(y_test, y_pred, average="macro") |
| 클래스별 전체 지표 | from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred)) |
| 혼동 행렬 | from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_pred) |
| 혼동 행렬 시각화 | from sklearn.metrics import ConfusionMatrixDisplay
ConfusionMatrixDisplay.from_estimator(model, X_test, y_test) |
| 확률로 ROC AUC 계산 | from sklearn.metrics import roc_auc_score
roc_auc_score(y_test, model.predict_proba(X_test)[:, 1]) |
| ROC 곡선 그리기 | from sklearn.metrics import RocCurveDisplay
RocCurveDisplay.from_estimator(model, X_test, y_test) |
| 불균형 클래스용 정확도 | from sklearn.metrics import balanced_accuracy_score
balanced_accuracy_score(y_test, y_pred) |
| 직접 정하는 결정 임곗값 | y_pred = (model.predict_proba(X_test)[:, 1] >= 0.3).astype(int) |
회귀 평가 지표
오차 지표는 타깃과 같은 단위예요(낮을수록 좋음). R²는 설명된 분산의 비율이에요(1이면 완벽).
| 작업 | 코드 |
|---|---|
| 임포트 | from sklearn.metrics import mean_absolute_error, mean_squared_error, root_mean_squared_error, r2_score |
| 평균 절대 오차 | mean_absolute_error(y_test, y_pred) |
| 평균 제곱 오차와 그 제곱근 | mean_squared_error(y_test, y_pred), root_mean_squared_error(y_test, y_pred) |
| R² 점수 | r2_score(y_test, y_pred) |
| 평균 절대 백분율 오차 | from sklearn.metrics import mean_absolute_percentage_error
mean_absolute_percentage_error(y_test, y_pred) |
| 예측값과 실제값 비교 그래프 | from sklearn.metrics import PredictionErrorDisplay
PredictionErrorDisplay.from_predictions(y_test, y_pred, kind="actual_vs_predicted") |
파이프라인
파이프라인은 전처리와 모델을 하나의 추정기로 연결해요. 그래서 교차 검증과 그리드 서치가 모든 단계를 학습 폴드에서만 fit해요.
| 작업 | 코드 |
|---|---|
| 임포트 | from sklearn.pipeline import make_pipeline, Pipeline |
| 스케일링 후 모델 학습 | pipe = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000))
pipe.fit(X_train, y_train) |
| 단계에 직접 이름 붙이기 | pipe = Pipeline([("scale", StandardScaler()), ("model", LogisticRegression(max_iter=1000))]) |
| 내부 단계에 접근 | pipe.named_steps["model"], pipe[-1] |
| 열마다 다른 단계 적용 | from sklearn.compose import ColumnTransformer
pre = ColumnTransformer([
("num", StandardScaler(), ["age", "income"]),
("cat", OneHotEncoder(handle_unknown="ignore"), ["city"]),
]) |
| 전처리와 모델을 한 객체로 | model = make_pipeline(pre, RandomForestClassifier(random_state=0))
model.fit(X_train, y_train)
model.score(X_test, y_test) |
| 타입으로 열 선택 | from sklearn.compose import make_column_selector
make_column_selector(dtype_include="number")(X_train) |
| 결측값 대체 후 스케일링 | make_pipeline(SimpleImputer(strategy="median"), StandardScaler()) |
| 출력 특성 이름 | pre.get_feature_names_out() |
교차 검증
교차 검증은 여러 분할에서 모델을 학습하고 평가하므로, 테스트 세트 하나보다 안정적인 추정치를 줘요.
| 작업 | 코드 |
|---|---|
| 임포트 | from sklearn.model_selection import cross_val_score, cross_validate, KFold, StratifiedKFold |
| 5개 폴드로 평가 | scores = cross_val_score(pipe, X, y, cv=5)
scores.mean(), scores.std() |
| 평가 지표 선택 | cross_val_score(pipe, X, y, cv=5, scoring="f1_macro") |
| 섞은 폴드 | cv = KFold(n_splits=5, shuffle=True, random_state=0) |
| 폴드마다 같은 클래스 비율 | cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0) |
| 여러 지표와 학습 점수 | cross_validate(pipe, X, y, cv=cv, scoring=["accuracy", "f1"], return_train_score=True) |
| 모든 행에 대한 폴드 외 예측 | from sklearn.model_selection import cross_val_predict
cross_val_predict(pipe, X, y, cv=5) |
| 그룹별 폴드, 시간순 폴드 | from sklearn.model_selection import GroupKFold, TimeSeriesSplit
GroupKFold(n_splits=5), TimeSeriesSplit(n_splits=5) |
| 사용 가능한 scoring 이름 전체 | from sklearn.metrics import get_scorer_names
get_scorer_names() |
그리드 서치와 튜닝
서치는 설정마다 교차 검증으로 모델을 학습하고, 가장 좋은 설정을 골라 전체 학습 데이터로 다시 학습해요.
| 작업 | 코드 |
|---|---|
| 임포트 | from sklearn.model_selection import GridSearchCV, RandomizedSearchCV |
| 모든 조합 시도 | grid = GridSearchCV(RandomForestClassifier(random_state=0), {"n_estimators": [50, 100], "max_depth": [None, 5]}, cv=5)
grid.fit(X_train, y_train) |
| 최적 설정과 점수 | grid.best_params_, grid.best_score_ |
| 최적 모델 사용 | grid.best_estimator_.predict(X_test), grid.score(X_test, y_test) |
| 파이프라인 내부 단계 튜닝 | GridSearchCV(pipe, {"logisticregression__C": [0.1, 1, 10]}, cv=5).fit(X_train, y_train) |
| 분포에서 무작위로 설정 뽑기 | from scipy.stats import randint
search = RandomizedSearchCV(RandomForestClassifier(random_state=0), {"n_estimators": randint(50, 150)}, n_iter=5, cv=3, random_state=0)
search.fit(X_train, y_train) |
| 모든 CPU 코어 사용 | GridSearchCV(pipe, {"logisticregression__C": [0.1, 1]}, cv=5, n_jobs=-1) |
| 전체 결과를 표로 | pd.DataFrame(grid.cv_results_).sort_values("rank_test_score") |
군집화와 차원 축소
비지도 모델은 X만으로 학습해요. 둘 다 거리를 사용하므로 먼저 특성을 스케일링하세요.
| 작업 | 코드 |
|---|---|
| k-평균 군집 | from sklearn.cluster import KMeans
km = KMeans(n_clusters=3, random_state=0)
labels = km.fit_predict(X) |
| 군집 중심과 관성 | km.cluster_centers_, km.inertia_ |
| 군집이 얼마나 잘 분리됐는지 | from sklearn.metrics import silhouette_score
silhouette_score(X, labels) |
| 밀도 기반 군집 (노이즈는 -1) | from sklearn.cluster import DBSCAN
DBSCAN(eps=0.5, min_samples=5).fit_predict(X) |
| 2개 주성분으로 투영 | from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_2d = pca.fit_transform(X) |
| 주성분별 설명된 분산 | pca.explained_variance_ratio_ |
| 분산의 95% 유지 | PCA(n_components=0.95).fit_transform(X) |
scikit-learn 1.9: 예전 방식과 지금 쓰는 방식
예전 튜토리얼에서 복사한 코드는 scikit-learn 1.9에서 오류나 경고가 날 수 있어요. 대신 scikit-learn 1.9 열의 방식으로 작성하세요.
| 작업 | scikit-learn 1.9 | 예전 방식 |
|---|---|---|
| 평균 제곱근 오차 | root_mean_squared_error(y_test, y_pred) | mean_squared_error(y_test, y_pred, squared=False) |
| 밀집 원-핫 출력 | OneHotEncoder(sparse_output=False) | OneHotEncoder(sparse=False) |
| L1(라쏘) 로지스틱 회귀 | LogisticRegression(l1_ratio=1, solver="liblinear") | LogisticRegression(penalty="l1", solver="liblinear") |
| 규제 없는 로지스틱 회귀 | LogisticRegression(C=np.inf) | LogisticRegression(penalty=None) |
저장, 불러오기, 재현성
| 작업 | 코드 |
|---|---|
| 학습된 모델이나 파이프라인 저장 | import joblib
joblib.dump(model, "model.joblib") |
| 다시 불러오기 | model = joblib.load("model.joblib") |
| 실행할 때마다 같은 결과 | random_state=0 |
| 설치된 버전 확인 | import sklearn
sklearn.__version__ |
실제 머신러닝 작업 흐름에 쓰는 scikit-learn 코드를 작성하는 순서대로 모았어요. 데이터 불러오기와 분할, 전처리, 모델 선택, 학습과 예측, 결과 평가, 단계를 파이프라인으로 연결하기, 교차 검증, 그리드 서치로 튜닝하기까지 담았어요. 각 행에는 바로 붙여 넣을 수 있는 짧은 코드와 무엇을 하는지 설명하는 한 줄이 있어요.
scikit-learn의 모든 모델은 같은 API를 공유해요. fit은 학습 데이터로 학습하고, predict와 transform은 학습한 내용을 적용해요. 모든 내용은 Coddy에서 실행하는 버전인 scikit-learn 1.9 기준이며, 특성은 X, 타깃은 y로 표기해요. scikit-learn은 NumPy 배열과 pandas DataFrame을 다루고, 그래프는 Matplotlib 치트시트에서 다뤄요. Python 자체가 처음이라면 Python 치트시트부터 시작하세요.
scikit-learn 치트시트 자주 묻는 질문
이 scikit-learn 치트시트는 무료인가요?
sklearn과 scikit-learn은 같은 건가요?
pip install scikit-learn), sklearn은 코드에서 임포트할 때 쓰는 이름이에요(from sklearn.linear_model import LinearRegression). sklearn 치트시트와 scikit-learn 치트시트는 같은 내용을 다뤄요.fit, transform, fit_transform의 차이는 무엇인가요?
fit은 데이터로부터 학습해요. 스케일러는 각 열의 평균을, 모델은 가중치를 학습하죠. transform은 학습한 내용을 적용하고, fit_transform은 둘을 한 번에 해요. 학습 세트에는 fit_transform을, 테스트 세트에는 transform만 쓰세요. 그렇지 않으면 테스트 데이터가 학습에 새어 들어가요. 파이프라인을 쓰면 이 과정을 알아서 처리해 줘요.특성을 꼭 스케일링해야 하나요?
어떤 scikit-learn 모델로 시작해야 하나요?
LinearRegression, 클래스를 예측할 때는 LogisticRegression을 써요. 그다음 RandomForestClassifier나 HistGradientBoostingClassifier(또는 각각의 회귀 버전)를 시도해 교차 검증으로 비교하고, 가장 좋은 모델을 GridSearchCV로 튜닝하세요.이 치트시트는 어떤 scikit-learn 버전을 다루나요?
mean_squared_error의 squared=False, OneHotEncoder의 sparse=False, LogisticRegression의 penalty 인자처럼 이제 오류나 경고가 나는 예전 호출은 예전 방식 표에 대신 쓸 코드와 함께 정리했어요.