Scikit-learn: шпаргалка по машинному обучению на Python
О чём эта статья
Машинное обучение (Machine Learning, ML) — это подход, при котором программа не выполняет жёстко заданные инструкции, а учится находить закономерности в данных. Вы даёте алгоритму примеры (что было на входе → какой должен быть ответ), он строит модель, и затем эта модель способна предсказывать ответ для новых, незнакомых данных.
Scikit-learn (sklearn) — главная Python-библиотека для машинного обучения. Все её алгоритмы работают через три универсальных метода:
| Метод | Что делает | Аналогия |
|---|---|---|
.fit(X, y) |
Обучает модель на примерах | «Посмотри на эти задачи с ответами и найди закономерность» |
.predict(X) |
Выдаёт предсказание для новых данных | «Какой ответ будет для этого нового случая?» |
.transform(X) |
Преобразует данные (нормализация, кодирование, понижение размерности) | «Приведи данные к удобному для анализа виду» |
Благодаря единому API вы можете заменить RandomForestClassifier на LogisticRegression — и код .fit()/.predict() останется тем же. Все модели sklearn «говорят на одном языке».
Для кого эта статья: Python-разработчики, которые уже знакомы с NumPy и Pandas и хотят начать применять машинное обучение на практике.
Что вы узнаете: как создавать модели классификации и регрессии, оценивать их качество, строить пайплайны обработки данных и подбирать гиперпараметры. Каждый раздел содержит полный работающий пример с выводом результатов — код можно копировать и запускать.
Установка и импорт
pip install scikit-learn
import numpy as np
from sklearn import datasets, model_selection, metrics, preprocessing
from sklearn import linear_model, ensemble, cluster, decomposition
from sklearn import pipeline, compose
Ключевые модули — под каждую задачу свой:
| Модуль | Назначение | Примеры классов |
|---|---|---|
sklearn.linear_model |
Линейные модели | LinearRegression, LogisticRegression, Ridge, Lasso |
sklearn.ensemble |
Ансамбли | RandomForestClassifier, GradientBoostingRegressor |
sklearn.cluster |
Кластеризация | KMeans, DBSCAN, AgglomerativeClustering |
sklearn.decomposition |
Снижение размерности | PCA, TruncatedSVD, NMF |
sklearn.preprocessing |
Предобработка | StandardScaler, OneHotEncoder, LabelEncoder |
sklearn.model_selection |
Подбор, валидация | train_test_split, GridSearchCV, cross_val_score |
sklearn.metrics |
Метрики | accuracy_score, r2_score, classification_report |
sklearn.pipeline |
Пайплайны | Pipeline, make_pipeline |
sklearn.compose |
Композиция трансформеров | ColumnTransformer, make_column_transformer |
API Scikit-learn: fit, predict, transform
Главная сила sklearn — единый интерфейс. Все модели реализуют три метода, семантика которых не меняется от алгоритма к алгоритму:
| Тип объекта | fit(X, y) |
predict(X) |
transform(X) |
fit_transform(X, y) |
|---|---|---|---|---|
| Estimator (модель) | Обучает модель | Делает предсказание | — | — |
| Transformer (преобразователь) | Вычисляет параметры (среднее, std) | — | Применяет преобразование | fit + transform за один проход |
| Pipeline | Обучает цепочку | Предсказывает итоговой моделью | — | — |
# Estimator (классификатор): fit → predict
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(random_state=42)
model.fit(X_train, y_train) # обучение
y_pred = model.predict(X_test) # предсказание классов
y_proba = model.predict_proba(X_test) # вероятности классов
# Transformer (масштабирование): fit → transform
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train) # вычислил mean и std
X_train_scaled = scaler.transform(X_train) # применил к train
X_test_scaled = scaler.transform(X_test) # применил к test (те же mean/std!)
# fit_transform — shortcut для train (НЕ для test!)
X_train_scaled = scaler.fit_transform(X_train)
Золотое правило: fit (или fit_transform) только на train. На test — только transform. Иначе утечка данных (data leakage): модель «подсмотрит» статистики test-выборки.
Линейные модели
LinearRegression — регрессия
Обычный метод наименьших квадратов. Минимизирует ∑(y_true - y_pred)². Идеален как baseline: быстро, интерпретируемо, но чувствителен к выбросам и мультиколлинеарности.
from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score, mean_squared_error
# Данные: diabetes — 442 пациента, 10 признаков, целевая переменная (прогресс болезни)
X, y = load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Модель
lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)
# Коэффициенты
print(f"Коэффициенты: {lr.coef_}")
print(f"Intercept: {lr.intercept_:.2f}")
# Коэффициенты: [ 37.9 -241.9 542.4 347.2 -792.9 471.9 103.5
# -32.8 779.8 119.2]
# Intercept: 151.35
# Оценка качества
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print(f"R² = {r2:.4f}") # R² = 0.4526
print(f"MSE = {mse:.2f}") # MSE = 2900.19
LogisticRegression — классификация
Несмотря на название, это классификатор (не регрессия). Предсказывает вероятность принадлежности к классу через сигмоиду: P(y=1) = 1/(1 + e^(-w·x)). По умолчанию — L2-регуляризация.
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# Данные: iris — 150 образцов, 3 класса ирисов, 4 признака
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42, stratify=y
)
# Модель
logreg = LogisticRegression(max_iter=200, random_state=42)
logreg.fit(X_train, y_train)
y_pred = logreg.predict(X_test)
# Оценка
print(f"Accuracy = {accuracy_score(y_test, y_pred):.4f}")
# Accuracy = 0.9556
print("\nClassification report:")
print(classification_report(y_test, y_pred, target_names=load_iris().target_names))
# precision recall f1-score support
# setosa 1.00 1.00 1.00 15
# versicolor 0.94 0.94 0.94 16
# virginica 0.93 0.93 0.93 14
# accuracy 0.96 45
print("Confusion matrix:")
print(confusion_matrix(y_test, y_pred))
# [[15 0 0]
# [ 0 15 1]
# [ 0 1 13]]
Деревья и ансамбли
RandomForestClassifier
Ансамбль решающих деревьев: каждое дерево обучается на случайной подвыборке данных и признаков (bagging). Итоговый ответ — голосование большинством. Устойчив к переобучению, не требует масштабирования.
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
# Синтетические данные: 1000 образцов, 10 признаков, 2 класса
X, y = make_classification(
n_samples=1000, n_features=10, n_informative=5,
n_redundant=2, random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
rf = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)
print(f"RandomForest accuracy = {accuracy_score(y_test, y_pred):.4f}")
# RandomForest accuracy = 0.9200
# Важность признаков
for i, importance in enumerate(rf.feature_importances_):
print(f" Признак {i}: {importance:.4f}")
# Признак 0: 0.0985
# Признак 1: 0.0836
# Признак 2: 0.1578
# Признак 3: 0.0867
# ...
Сравнение классификаторов на одном датасете
Сравним LogisticRegression и RandomForestClassifier на одних и тех же данных — это стандартный приём при выборе модели:
from sklearn.linear_model import LogisticRegression
models = {
"LogisticRegression": LogisticRegression(max_iter=1000, random_state=42),
"RandomForest": RandomForestClassifier(n_estimators=100, random_state=42),
}
print(f"{'Модель':<25} {'Accuracy':>10} {'Время (мс)':>12}")
print("-" * 47)
for name, model in models.items():
import time
t0 = time.time()
model.fit(X_train, y_train)
acc = model.score(X_test, y_test)
elapsed = (time.time() - t0) * 1000
print(f"{name:<25} {acc:>10.4f} {elapsed:>12.1f}")
# Модель Accuracy Время (мс)
# -----------------------------------------------
# LogisticRegression 0.8600 7.2
# RandomForest 0.9200 158.3
RandomForestRegressor
Тот же принцип ансамбля, но для регрессии: усреднение предсказаний деревьев. Хорошо работает «из коробки» без настройки гиперпараметров.
from sklearn.ensemble import RandomForestRegressor
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
# Данные для регрессии: 500 образцов, 8 признаков
X, y = make_regression(n_samples=500, n_features=8, noise=20, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Сравнение LinearRegression vs RandomForestRegressor
models = {
"LinearRegression": LinearRegression(),
"RandomForest": RandomForestRegressor(n_estimators=100, random_state=42),
}
print(f"{'Модель':<25} {'R²':>8} {'MSE':>12}")
print("-" * 47)
for name, model in models.items():
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
print(f"{name:<25} {r2:>8.4f} {mse:>12.1f}")
# Модель R² MSE
# -----------------------------------------------
# LinearRegression 0.9982 356.2
# RandomForest 0.9188 16120.0
На синтетических данных линейная модель выигрывает — данные сгенерированы линейно. На реальных данных RandomForest обычно показывает лучший R².
GradientBoostingClassifier
Последовательное построение деревьев: каждое новое дерево исправляет ошибки предыдущих. Медленнее Random Forest, но часто точнее. Ключевой гиперпараметр — learning_rate (темп обучения).
from sklearn.ensemble import GradientBoostingClassifier
gb = GradientBoostingClassifier(
n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42
)
gb.fit(X_train, y_train)
print(f"GradientBoosting accuracy = {gb.score(X_test, y_test):.4f}")
# GradientBoosting accuracy = 0.9250
RandomForest vs GradientBoosting:
| Характеристика | RandomForest | GradientBoosting |
|---|---|---|
| Построение | Параллельное (деревья независимы) | Последовательное (каждое исправляет ошибки) |
| Скорость | Быстрее | Медленнее |
| Переобучение | Устойчив (bagging) | Склонен при большом n_estimators |
| Точность | Хорошая | Часто выше |
| Настройка | Мало гиперпараметров | Критичен learning_rate и max_depth |
Кластеризация
KMeans
Разбивает данные на K кластеров, минимизируя сумму квадратов расстояний до центроидов. Требует задания числа кластеров заранее. Ключевая метрика — inertia (сумма квадратов расстояний до центров).
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score
# Генерация: 300 точек, 3 кластера
X, y_true = make_blobs(n_samples=300, centers=3, cluster_std=0.8, random_state=42)
# KMeans
kmeans = KMeans(n_clusters=3, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
print(f"Inertia = {kmeans.inertia_:.2f}")
# Inertia = 549.33
print(f"Silhouette score = {silhouette_score(X, labels):.4f}")
# Silhouette score = 0.7513
print(f"Центроиды:\n{kmeans.cluster_centers_}")
# Центроиды:
# [[-9.04 -3.80]
# [-3.70 7.00]
# [-6.84 -8.12]]
Подбор числа кластеров: метод локтя (elbow)
inertias = []
K_range = range(1, 10)
for k in K_range:
km = KMeans(n_clusters=k, random_state=42, n_init=10)
km.fit(X)
inertias.append(km.inertia_)
for k, inertia in zip(K_range, inertias):
marker = " ◀ изгиб" if k == 3 else ""
print(f" k={k}: inertia={inertia:.1f}{marker}")
# k=1: inertia=6967.5
# k=2: inertia=1994.1
# k=3: inertia=549.3 ◀ изгиб
# k=4: inertia=393.4
# k=5: inertia=290.2
# ...
«Локоть» — точка, после которой уменьшение inertia замедляется. Здесь это k=3, что совпадает с истинным числом кластеров.
Уменьшение размерности
PCA (Principal Component Analysis)
Находит направления максимальной дисперсии в данных и проецирует на них. Позволяет сжать данные, убрать шум, визуализировать многомерные данные в 2D.
from sklearn.decomposition import PCA
# Данные: iris — 4 признака → 2 главные компоненты
X, y = load_iris(return_X_y=True)
pca = PCA(n_components=2, random_state=42)
X_pca = pca.fit_transform(X)
print(f"Исходная размерность: {X.shape[1]} признаков")
print(f"После PCA: {X_pca.shape[1]} компоненты")
print(f"Explained variance ratio: {pca.explained_variance_ratio_}")
# Explained variance ratio: [0.9246 0.0530]
print(f"Суммарно объяснено дисперсии: {pca.explained_variance_ratio_.sum():.2%}")
# Суммарно объяснено дисперсии: 97.76%
Две первые компоненты сохранили 97.8% информации — можно смело визуализировать в 2D вместо 4D.
Пайплайны (Pipeline)
Пайплайн — цепочка шагов предобработки и модели. Гарантирует, что fit/transform вызываются в правильном порядке, исключает утечку данных при кросс-валидации.
make_pipeline — простой пайплайн
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
# Пайплайн: масштабирование → классификатор
pipe = make_pipeline(StandardScaler(), LogisticRegression(random_state=42))
pipe.fit(X_train, y_train)
print(f"Pipeline accuracy = {pipe.score(X_test, y_test):.4f}")
# Pipeline accuracy = 0.9556
# Доступ к шагам по имени
print(f"Коэффициенты: {pipe.named_steps['logisticregression'].coef_}")
ColumnTransformer — разные преобразования для разных колонок
import pandas as pd
from sklearn.compose import make_column_transformer
from sklearn.preprocessing import OneHotEncoder
# Данные с числовыми и категориальными признаками
df = pd.DataFrame({
'age': [25, 32, 28, 45, 33],
'city': ['Moscow', 'SPb', 'Kazan', 'Moscow', 'SPb'],
'salary': [80_000, 120_000, 90_000, 150_000, 110_000],
'target': [0, 1, 0, 1, 0],
})
X = df[['age', 'city', 'salary']]
y = df['target']
# ColumnTransformer: числовые → масштабирование, категориальные → OneHot
preprocessor = make_column_transformer(
(StandardScaler(), ['age', 'salary']),
(OneHotEncoder(drop='first'), ['city']),
)
# Полный пайплайн
pipe = make_pipeline(preprocessor, LogisticRegression(random_state=42))
pipe.fit(X, y)
print(f"ColumnTransformer pipeline accuracy = {pipe.score(X, y):.4f}")
# ColumnTransformer pipeline accuracy = 1.0000
На реальных данных вместо имён колонок можно использовать
make_column_selector(dtype_include='object')для авто-выбора категориальных колонок.
Подбор гиперпараметров
GridSearchCV — полный перебор
Перебирает ВСЕ комбинации из сетки параметров. Подходит, когда параметров мало и сетка невелика.
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [3, 5, 10, None],
}
rf = RandomForestClassifier(random_state=42)
grid = GridSearchCV(rf, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
grid.fit(X_train, y_train)
print(f"Best params: {grid.best_params_}")
# Best params: {'max_depth': 5, 'n_estimators': 50}
print(f"Best CV score: {grid.best_score_:.4f}")
# Best CV score: 0.9200
print(f"Test score: {grid.score(X_test, y_test):.4f}")
# Test score: 0.9200
RandomizedSearchCV — случайный поиск
Случайно выбирает N комбинаций из распределений. Быстрее GridSearchCV при большом пространстве параметров.
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform
param_dist = {
'n_estimators': randint(50, 300),
'max_depth': randint(3, 20),
'learning_rate': uniform(0.01, 0.3),
'subsample': uniform(0.6, 0.4),
}
gb = GradientBoostingClassifier(random_state=42)
random_search = RandomizedSearchCV(
gb, param_dist, n_iter=20, cv=3, scoring='accuracy',
random_state=42, n_jobs=-1
)
random_search.fit(X_train, y_train)
print(f"Best params: {random_search.best_params_}")
# Best params: {'learning_rate': 0.22, 'max_depth': 7,
# 'n_estimators': 161, 'subsample': 0.98}
print(f"Best score: {random_search.best_score_:.4f}")
# Best score: 0.9175
cross_val_score — быстрая кросс-валидация
Оценка модели без подбора параметров — просто понять, насколько стабильно качество:
from sklearn.model_selection import cross_val_score
rf = RandomForestClassifier(n_estimators=100, random_state=42)
scores = cross_val_score(rf, X, y, cv=5, scoring='accuracy')
print(f"Scores per fold: {scores}")
# Scores per fold: [0.95 0.95 0.90 0.95 0.90]
print(f"Mean ± std: {scores.mean():.4f} ± {scores.std():.4f}")
# Mean ± std: 0.9300 ± 0.0245
Метрики качества
Сводная таблица: какую метрику использовать для какой задачи.
Классификация
| Метрика | Функция sklearn | Что измеряет | Когда использовать |
|---|---|---|---|
| Accuracy | accuracy_score |
Доля правильных ответов | Сбалансированные классы |
| Precision | precision_score |
Точность положительных предсказаний | Важно не допустить ложных срабатываний (спам-фильтр) |
| Recall | recall_score |
Полнота — сколько positives найдено | Важно не пропустить positives (поиск болезней) |
| F1-score | f1_score |
Гармоническое среднее precision и recall | Несбалансированные классы |
| ROC-AUC | roc_auc_score |
Качество разделения классов | Бинарная классификация, нужны вероятности |
| Confusion matrix | confusion_matrix |
Полная картина ошибок | Детальный анализ ошибок |
| Classification report | classification_report |
Precision/Recall/F1 по классам | Отчёт «всё сразу» |
from sklearn.metrics import (
accuracy_score, precision_score, recall_score, f1_score,
roc_auc_score, confusion_matrix, classification_report
)
# Бинарная классификация
y_true = [0, 1, 0, 1, 0, 1, 0, 0, 1, 1]
y_pred = [0, 0, 0, 1, 0, 1, 1, 0, 1, 1]
print(f"Accuracy: {accuracy_score(y_true, y_pred):.3f}") # 0.800
print(f"Precision: {precision_score(y_true, y_pred):.3f}") # 0.800
print(f"Recall: {recall_score(y_true, y_pred):.3f}") # 0.800
print(f"F1: {f1_score(y_true, y_pred):.3f}") # 0.800
Регрессия
| Метрика | Функция sklearn | Что измеряет | Примечание |
|---|---|---|---|
| R² | r2_score |
Доля объяснённой дисперсии (0..1, 1 = идеально) | Основная метрика |
| MSE | mean_squared_error |
Средний квадрат ошибки | Штрафует выбросы квадратично |
| MAE | mean_absolute_error |
Средний модуль ошибки | Устойчив к выбросам |
| RMSE | root_mean_squared_error |
Корень из MSE (в единицах y) | Интерпретируема: «в среднем ошибаемся на N единиц» |
from sklearn.metrics import mean_absolute_error, root_mean_squared_error
y_true = [100, 200, 300, 400, 500]
y_pred = [110, 190, 310, 380, 520]
print(f"R²: {r2_score(y_true, y_pred):.4f}") # 0.9880
print(f"MSE: {mean_squared_error(y_true, y_pred):.1f}") # 240.0
print(f"MAE: {mean_absolute_error(y_true, y_pred):.1f}") # 14.0
print(f"RMSE: {root_mean_squared_error(y_true, y_pred):.1f}") # 15.5
Кластеризация
| Метрика | Функция sklearn | Что измеряет |
|---|---|---|
| Silhouette | silhouette_score |
Качество разделения кластеров (-1..1, чем ближе к 1, тем лучше) |
| Inertia | kmeans.inertia_ |
Сумма квадратов расстояний до центроидов (чем меньше, тем плотнее кластеры) |
Предобработка данных
Масштабирование (scaling)
Многие модели (SVM, логистическая регрессия, нейросети, KMeans, PCA) требуют масштабирования. Деревья и случайный лес — не требуют.
from sklearn.preprocessing import StandardScaler, MinMaxScaler
X = np.array([[1, -1], [2, 0], [3, 1], [4, 2]], dtype=float)
# StandardScaler: z-нормализация → mean=0, std=1
scaler = StandardScaler()
X_std = scaler.fit_transform(X)
print(f"StandardScaler:\n{X_std}")
# [[-1.34 -1.34]
# [-0.45 -0.45]
# [ 0.45 0.45]
# [ 1.34 1.34]]
# MinMaxScaler: в диапазон [0, 1]
mms = MinMaxScaler()
X_mms = mms.fit_transform(X)
print(f"MinMaxScaler:\n{X_mms}")
# [[0. 0. ]
# [0.33 0.33]
# [0.67 0.67]
# [1. 1. ]]
Кодирование категориальных признаков
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
# LabelEncoder: строки → числа (для целевой переменной!)
le = LabelEncoder()
cities = ['Moscow', 'SPb', 'Kazan', 'Moscow', 'SPb']
print(f"LabelEncoder: {le.fit_transform(cities)}")
# LabelEncoder: [1 2 0 1 2]
# OneHotEncoder: строки → бинарные столбцы (для признаков!)
ohe = OneHotEncoder(sparse_output=False)
cities_2d = np.array(cities).reshape(-1, 1)
print(f"OneHotEncoder:\n{ohe.fit_transform(cities_2d)}")
# [[0. 1. 0.]
# [0. 0. 1.]
# [1. 0. 0.]
# [0. 1. 0.]
# [0. 0. 1.]]
Разделение на train/test
from sklearn.model_selection import train_test_split
# Базовое: 80% train, 20% test
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Со стратификацией (сохраняет пропорции классов — важно для несбалансированных!)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
Частые ошибки
| Ошибка | ❌ Неправильно | ✅ Правильно |
|---|---|---|
| Утечка данных: fit на всём датасете | scaler.fit(X) → X_train, X_test = ... |
scaler.fit(X_train) → scaler.transform(X_test) |
fit_transform на test |
X_test_scaled = scaler.fit_transform(X_test) |
X_test_scaled = scaler.transform(X_test) |
Нет random_state |
train_test_split(X, y) |
train_test_split(X, y, random_state=42) |
Несбалансированные классы без class_weight |
LogisticRegression() |
LogisticRegression(class_weight='balanced') |
Масштабирование после train_test_split |
см. пункт 1 | Масштабировать train и test одним scaler'ом |
| OneHotEncoder для новых категорий | Падает ValueError на test |
OneHotEncoder(handle_unknown='ignore') |
| Перекрёстная проверка без пайплайна | cross_val_score(model, scaler.fit_transform(X), y) |
cross_val_score(make_pipeline(scaler, model), X, y) |
| Метрики регрессии для классификации | r2_score(y_true, y_pred_classes) |
accuracy_score / f1_score |
KMeans без n_init |
KMeans(n_clusters=3) — предупреждение |
KMeans(n_clusters=3, n_init=10, random_state=42) |
Ресурсы
- Официальная документация Scikit-learn — полное описание API, примеры, руководства
- Scikit-learn на GitHub — исходный код, issues, обсуждения
- Scipy Lecture Notes — Scikit-learn — введение в sklearn в составе экосистемы SciPy
- Kaggle: курсы по ML — практические туториалы с использованием sklearn
Что дальше
- Шпаргалка по Pandas: DataFrame, groupby, временные ряды
- Шпаргалка по NumPy: массивы, операции, линейная алгебра
- Шпаргалка по Matplotlib: графики от простых до публикационных
- Шпаргалка по Seaborn: статистическая визуализация
- Инструменты Data Science: обзор экосистемы Python для анализа данных
Связанные шпаргалки: Pandas, NumPy, Matplotlib, Seaborn