Работа с библиотекой Scikit-learn: от данных к готовой модели
Библиотека Scikit-learn содержит инструменты для решения задач классификации, регрессии, кластеризации и анализа данных. Основой работы является единый интерфейс оценщиков: fit обучает модель, predict формирует прогноз, transform преобразует данные.
Ниже описан порядок действий, который часто используется в небольшом проекте машинного обучения.
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
data = load_wine()
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=7, stratify=y
)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
clf = RandomForestClassifier(n_estimators=100, random_state=7)
clf.fit(X_train_scaled, y_train)
y_pred = clf.predict(X_test_scaled)
print(accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred, target_names=data.target_names))
библиотеки для машинного обучения python (библиотеки для машинного обучения в python (scikit-learn, tensorflow, pytorch))
0.9777777777777777
precision recall f1-score support
class_0 1.00 1.00 1.00 13
class_1 0.94 1.00 0.97 16
class_2 1.00 0.92 0.96 16
accuracy 0.98 45
macro avg 0.98 0.97 0.98 45
weighted avg 0.98 0.98 0.98 45
Feature names python (имена признаков в python)
Набор данных Wine содержит три класса. Разбиение с stratify=y сохраняет доли классов в обучающей и тестовой частях. Стандартизация выполняется после разделения, поэтому параметры масштабирования вычисляются только по обучающим данным.
Как объединить предобработку и модель в конвейере?
Конвейер позволяет выполнить несколько преобразований подряд и обучить модель одним вызовом fit.
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.ensemble import GradientBoostingRegressor
data = load_diabetes()
X = data.data
y = data.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
numeric_columns = list(range(data.data.shape[1]))
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
preprocessor = ColumnTransformer(
transformers=[('num', numeric_transformer, numeric_columns)]
)
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('regressor', GradientBoostingRegressor(random_state=42))
])
pipeline.fit(X_train, y_train)
score = pipeline.score(X_test, y_test)
print(score)
Python model (модели в python (машинное обучение))
0.43
статистическая библиотека python (статистическая библиотека python (scipy, statsmodels))
В диабетическом наборе все признаки числовые, поэтому ColumnTransformer содержит один блок. В реальном проекте в этот же список добавляются категориальные колонки с OneHotEncoder.
Типичная ошибка: применение StandardScaler до разделения данных. Это приводит к тому, что средние значения и дисперсии вычисляются с учетом тестовых объектов, и оценка качества становится смещенной.
Как перебрать гиперпараметры и выбрать лучший вариант?
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
data = load_breast_cancer()
X, y = data.data, data.target
pipe = Pipeline(steps=[
('scaler', StandardScaler()),
('svc', SVC())
])
param_grid = {
'svc__C': [0.1, 1, 10],
'svc__gamma': ['scale', 0.01, 0.1]
}
search = GridSearchCV(pipe, param_grid, cv=5, scoring='f1', n_jobs=-1)
search.fit(X, y)
print(search.best_params_)
print(search.best_score_)
создание нейросетей на python (создание нейронных сетей на python (tensorflow, pytorch))
{'svc__C': 10, 'svc__gamma': 'scale'}
0.9776
Ai script python (скрипты для искусственного интеллекта на python)
Ключ svc__C состоит из имени шага и имени параметра. Такой подход работает и с конвейерами, и с отдельными моделями.
Важно: при использовании GridSearchCV с конвейером предобработка находится внутри пайплайна, поэтому она применяется отдельно на каждом фолде. Это предотвращает утечку данных.
Как работать с несбалансированными классами?
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
X, y = make_classification(
n_samples=4000, n_features=20,
weights=[0.9, 0.1], random_state=11
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=11
)
rf = RandomForestClassifier(
n_estimators=150, class_weight='balanced', random_state=11
)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)
print(classification_report(y_test, y_pred, target_names=['majority', 'minority']))
Random forest python (random forest в python)
precision recall f1-score support
majority 0.97 0.99 0.98 1080
minority 0.91 0.80 0.85 120
accuracy 0.97 1200
macro avg 0.94 0.90 0.92 1200
weighted avg 0.96 0.97 0.96 1200
нейросеть python (нейросеть на python)
Параметр class_weight='balanced' увеличивает штраф за ошибки на редких классах. Альтернативой становится отдельное взвешивание моделей или изменение порога классификации.
Частая ошибка: использование accuracy как единственной метрики при сильно несбалансированных данных. Точность может оставаться высокой, тогда как модель совсем не распознает редкий класс. Для оценки применяются precision, recall и F1-мера.
Как выполнить кластеризацию и оценить качество разбиения?
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
X, true_labels = make_blobs(
n_samples=800, centers=4, cluster_std=0.9, random_state=3
)
best_k = 1
best_score = -1
for k in range(2, 7):
model = KMeans(n_clusters=k, random_state=3, n_init=10)
labels = model.fit_predict(X)
score = silhouette_score(X, labels)
print(k, score)
if score > best_score:
best_score = score
best_k = k
print('best_k', best_k)
нейросеть с помощью python (нейросети на python)
2 0.667 3 0.746 4 0.792 5 0.758 6 0.734 best_k 4
рекомендательная система python (разработка рекомендательной системы на python)
Метод силуэта возвращает значения от минус единицы до единицы. Чем ближе значение к единице, тем четче разделение кластеров.
Как уменьшить число признаков с помощью PCA?
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
data = load_digits()
X = data.data
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
print(pca.explained_variance_ratio_)
print(X_pca.shape)
библиотеки scikit learn python (библиотека scikit-learn для python)
[0.1208 0.0959] (1797, 2)
Первые две главные компоненты объясняют часть дисперсии. При выборе числа компонент обычно ориентируются на суммарную объясненную дисперсию около 0.8 или 0.9.
Ошибка: применение PCA без стандартизации. Если признаки имеют разный масштаб, компоненты будут определяться в основном признаками с большой дисперсией.
Как сохранить обученную модель и конвейер?
from joblib import dump, load
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(max_iter=200)
model.fit(X_train, y_train)
dump(model, 'logistic_model.joblib')
loaded_model = load('logistic_model.joblib')
new_pred = loaded_model.predict(X_test)
print(loaded_model.score(X_test, y_test))
0.94
Сохранение всего конвейера удобнее, чем сохранение только модели, потому что при загрузке не нужно повторять шаги предобработки.
Типичная проблема: если pipeline содержит кастомный трансформатор, его класс должен быть доступен при загрузке. Файл joblib хранит ссылку на класс, а не код класса.