🧪 Scikit-learn

Полный справочник: цикл ML, данные и пайплайны, предобработка, модели классификации, регрессии и кластеризации, метрики, кросс-валидация, подбор гиперпараметров, отбор признаков, интерпретация, сохранение и типичные ошибки.

Шпаргалки · ИИ · #scikit-learn #sklearn #python #machine-learning

Установка и общий цикл

pip install scikit-learn pandas
import sklearn; sklearn.__version__

Цикл работы: данные → разделение → предобработка → модель → обучение → оценка → подбор параметров → итоговая проверка → сохранение. Единый API: fit(X, y), predict(X), predict_proba(X), transform(X), fit_transform, score, get_params, set_params. X это матрица (n_samples, n_features), y вектор целевой переменной.

Данные и разделение

from sklearn.datasets import load_iris, make_classification, fetch_openml
from sklearn.model_selection import train_test_split, StratifiedKFold, KFold, cross_val_score, cross_validate, GroupKFold, TimeSeriesSplit

X, y = load_iris(return_X_y=True, as_frame=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)   # stratify сохраняет доли классов

Разделяйте данные до любой предобработки, чтобы не было утечки (data leakage). Для временных рядов TimeSeriesSplit (будущее не должно попадать в обучение), для групп (один пользователь в нескольких строках) GroupKFold.

Пайплайн и предобработка

from sklearn.pipeline import make_pipeline, Pipeline
from sklearn.compose import ColumnTransformer, make_column_selector as selector
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler, OneHotEncoder, OrdinalEncoder, LabelEncoder, PolynomialFeatures, FunctionTransformer
from sklearn.impute import SimpleImputer, KNNImputer

num = make_pipeline(SimpleImputer(strategy="median"), StandardScaler())
cat = make_pipeline(SimpleImputer(strategy="most_frequent"), OneHotEncoder(handle_unknown="ignore"))
pre = ColumnTransformer([
    ("num", num, selector(dtype_include="number")),
    ("cat", cat, selector(dtype_include="object")),
])
model = make_pipeline(pre, RandomForestClassifier(n_estimators=300, random_state=42))
model.fit(X_tr, y_tr)
Класс Что делает
StandardScaler среднее 0, дисперсия 1 (нужен линейным, SVM, kNN, нейросетям)
MinMaxScaler, RobustScaler диапазон 0–1, устойчивый к выбросам
OneHotEncoder, OrdinalEncoder, TargetEncoder категории в числа
SimpleImputer, KNNImputer, IterativeImputer заполнение пропусков
PolynomialFeatures, SplineTransformer нелинейные признаки
PowerTransformer, QuantileTransformer, Binarizer, KBinsDiscretizer выравнивание распределений, бины
TfidfVectorizer, CountVectorizer, HashingVectorizer текст в векторы

Деревья и бустинг не требуют масштабирования. Пайплайн гарантирует, что обучение предобработки идёт только на обучающей выборке и в кросс-валидации.

Модели

Задача Модели
Классификация LogisticRegression, RandomForestClassifier, GradientBoostingClassifier, HistGradientBoostingClassifier (быстрый, пропуски из коробки), SVC, KNeighborsClassifier, DecisionTreeClassifier, GaussianNB, MLPClassifier, ExtraTreesClassifier
Регрессия LinearRegression, Ridge, Lasso, ElasticNet, RandomForestRegressor, HistGradientBoostingRegressor, SVR, KNeighborsRegressor
Кластеризация KMeans, MiniBatchKMeans, DBSCAN, HDBSCAN, AgglomerativeClustering, GaussianMixture
Снижение размерности PCA, TruncatedSVD, TSNE, NMF (UMAP — отдельный пакет)
Аномалии IsolationForest, LocalOutlierFactor, OneClassSVM
Ансамбли VotingClassifier, StackingClassifier, BaggingClassifier, AdaBoost
Мультикласс и мультилейбл OneVsRestClassifier, MultiOutputClassifier

Для табличных данных стабильную базу даёт градиентный бустинг (HistGradientBoosting*, а также XGBoost, LightGBM, CatBoost). Первая линия: LogisticRegression / Ridge как простой бейзлайн, затем деревья.

Метрики

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, average_precision_score, confusion_matrix, classification_report, \
    mean_absolute_error, mean_squared_error, root_mean_squared_error, r2_score, silhouette_score, ConfusionMatrixDisplay, RocCurveDisplay
pred = model.predict(X_te); proba = model.predict_proba(X_te)[:, 1]
print(classification_report(y_te, pred)); confusion_matrix(y_te, pred); roc_auc_score(y_te, proba)
Задача Метрики
Классификация accuracy, precision, recall, F1 (average="macro"/"weighted"), ROC-AUC, PR-AUC, log-loss, MCC
Регрессия MAE, MSE, RMSE, R², MAPE
Кластеризация silhouette, Davies–Bouldin, ARI (при известных метках)

При несбалансированных классах accuracy обманчива: смотрите precision, recall, F1, PR-AUC, используйте class_weight="balanced", stratify, подбор порога по precision_recall_curve, imbalanced-learn (SMOTE).

Кросс-валидация

cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(model, X, y, cv=cv, scoring="f1_macro", n_jobs=-1)
print(scores.mean(), scores.std())
res = cross_validate(model, X, y, cv=cv, scoring=["accuracy", "roc_auc"], return_train_score=True)

scoring принимает строки (accuracy, f1, roc_auc, neg_mean_squared_error, r2): для ошибок знак отрицательный.

Подбор гиперпараметров

from sklearn.model_selection import GridSearchCV, RandomizedSearchCV, HalvingRandomSearchCV
param_grid = {"randomforestclassifier__n_estimators": [200, 500], "randomforestclassifier__max_depth": [None, 8, 16], "randomforestclassifier__min_samples_leaf": [1, 3]}
grid = GridSearchCV(model, param_grid, cv=cv, scoring="f1_macro", n_jobs=-1, refit=True)
grid.fit(X_tr, y_tr)
grid.best_params_; grid.best_score_; grid.best_estimator_; pd.DataFrame(grid.cv_results_)

Имена параметров в пайплайне: шаг__параметр. Для больших пространств RandomizedSearchCV или Optuna. Итоговую оценку делайте на отложенной тестовой выборке, не на той, по которой подбирали.

Отбор признаков и важность

from sklearn.feature_selection import SelectKBest, f_classif, mutual_info_classif, RFE, SelectFromModel, VarianceThreshold
from sklearn.inspection import permutation_importance, PartialDependenceDisplay
model.named_steps["randomforestclassifier"].feature_importances_
r = permutation_importance(model, X_te, y_te, n_repeats=10, random_state=0, n_jobs=-1)          # надёжнее, чем feature_importances_

Интерпретация: коэффициенты линейных моделей (на масштабированных данных), permutation importance, PDP, SHAP (отдельный пакет).

Кластеризация и снижение размерности

from sklearn.cluster import KMeans; from sklearn.decomposition import PCA
Xs = StandardScaler().fit_transform(X)
km = KMeans(n_clusters=4, n_init="auto", random_state=0).fit(Xs); km.labels_; km.inertia_; silhouette_score(Xs, km.labels_)
pca = PCA(n_components=0.95).fit(Xs); pca.explained_variance_ratio_.cumsum(); Z = pca.transform(Xs)         # 95% дисперсии

Число кластеров выбирайте по silhouette, «локтю» (inertia), смыслу бизнеса. KMeans чувствителен к масштабу и предполагает шарообразные кластеры, DBSCAN находит произвольные формы и выбросы.

Регуляризация и линейные модели

from sklearn.linear_model import LogisticRegression, Ridge, Lasso, ElasticNet, LinearRegression
LogisticRegression(C=1.0, penalty="l2", max_iter=1000, class_weight="balanced")        # C: обратная сила регуляризации
Ridge(alpha=1.0); Lasso(alpha=0.01)       # L1 зануляет признаки (отбор)

SGDClassifier и partial_fit для онлайн-обучения на больших данных.

Сохранение и использование

import joblib
joblib.dump(model, "model.joblib", compress=3); model = joblib.load("model.joblib")
model.predict(pd.DataFrame([{"age": 30, "city": "Москва"}]))

Файлы joblib / pickle выполняют код при загрузке: загружайте только доверенные. Фиксируйте версии библиотек (scikit-learn==1.x), сохраняйте вместе с пайплайном. Для переносимости: ONNX (skl2onnx).

Диагностика качества

Симптом Причина и действия
Train высоко, test низко переобучение: больше данных, регуляризация, упростить модель, ранняя остановка, max_depth, min_samples_leaf
И train, и test низко недообучение: сложнее модель, новые признаки, меньше регуляризации
Метрика «слишком хороша» утечка данных: целевая информация в признаках, предобработка до разделения
Нестабильные результаты задайте random_state, больше фолдов, повторная CV
Дисбаланс классов веса классов, пересэмплирование, метрики по классам, порог
Не сходится масштабируйте признаки, увеличьте max_iter, другой solver
Долго n_jobs=-1, HistGradientBoosting, подвыборка, MiniBatch*, меньше признаков

Кривые обучения: learning_curve, validation_curve.

Практика

  • Начинайте с простого бейзлайна (DummyClassifier, линейная модель) и сравнивайте с ним.
  • Всё в Pipeline: нет утечек, один объект для обучения и продакшена.
  • Проверяйте метрику на отложенной выборке, один раз в конце.
  • Пишите воспроизводимо: random_state, версии, фиксированное разделение.
  • Данные: чистка выбросов, обработка пропусков, проверка распределений до и после (drift).
  • Расширения: XGBoost, LightGBM, CatBoost (бустинг), imbalanced-learn, category_encoders, SHAP, Optuna, MLflow (учёт экспериментов), Evidently (дрейф данных), Yellowbrick.