Примечание
Перейти к концу, чтобы загрузить весь пример кода. или запустить этот пример в вашем браузере через JupyterLite или Binder
Основные моменты выпуска scikit-learn 1.5
Мы рады объявить о выпуске scikit-learn 1.5! Было добавлено множество исправлений ошибок и улучшений, а также некоторые ключевые новые возможности. Ниже мы подробно описываем основные моменты этого выпуска. Для исчерпывающего списка всех изменений, пожалуйста, обратитесь к примечаниям к релизу.
Для установки последней версии (с помощью pip):
pip install --upgrade scikit-learn
или с помощью conda:
conda install -c conda-forge scikit-learn
FixedThresholdClassifier: Установка порога принятия решения для бинарного классификатора
Все бинарные классификаторы scikit-learn используют фиксированный порог принятия решения 0,5 для преобразования оценок вероятности (т.е. выходного значения predict_proba) в прогнозы класса. Однако 0,5 почти никогда не является желаемым порогом для данной задачи. FixedThresholdClassifier позволяет обернуть любой бинарный классификатор и установить пользовательский порог принятия решения.
from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import ConfusionMatrixDisplay X, y = make_classification(n_samples=10_000, weights=[0.9, 0.1], random_state=0) X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) classifier_05 = LogisticRegression(C=1e6, random_state=0).fit(X_train, y_train) _ = ConfusionMatrixDisplay.from_estimator(classifier_05, X_test, y_test)

Понижение порога, то есть разрешение большему количеству выборок классифицироваться как положительный класс, увеличивает количество истинных положительных значений за счет большего количества ложных положительных (как хорошо известно из вогнутости кривой ROC).
from sklearn.model_selection import FixedThresholdClassifier classifier_01 = FixedThresholdClassifier(classifier_05, threshold=0.1) classifier_01.fit(X_train, y_train) _ = ConfusionMatrixDisplay.from_estimator(classifier_01, X_test, y_test)

TunedThresholdClassifierCV: Настройка порога принятия решения для бинарного классификатора
Порог принятия решения бинарного классификатора можно настроить для оптимизации заданного метрики с помощью TunedThresholdClassifierCV.
Это особенно полезно для поиска наилучшего порога принятия решения, когда модель предназначена для развертывания в конкретном контексте приложения, где мы можем назначить различные выгоды или затраты для истинных положительных, истинных отрицательных, ложных положительных и ложных отрицательных.
Давайте проиллюстрируем это, рассмотрев произвольный случай, где:
- каждый истинный положительный случай приносит 1 единицу прибыли, например, евро, год жизни в хорошем здоровье и т. д.;
- истинные отрицательные случаи не приносят и не стоят ничего;
- каждый ложный отрицательный случай стоит 2;
- каждый ложный положительный случай стоит 0,1.
Наша метрика определяет среднюю прибыль на образец, которая определяется следующей функцией Python:
from sklearn.metrics import confusion_matrix
def custom_score(y_observed, y_pred):
tn, fp, fn, tp = confusion_matrix(y_observed, y_pred, normalize="all").ravel()
return tp - 2 * fn - 0.1 * fp
print("Untuned decision threshold: 0.5")
print(f"Custom score: {custom_score(y_test, classifier_05.predict(X_test)):.2f}")
Untuned decision threshold: 0.5 Custom score: -0.12
Интересно наблюдать, что средняя прибыль на предсказание отрицательная, что означает, что эта система принятия решений в среднем приносит убытки.
Настройка порога для оптимизации этой пользовательской метрики дает более низкий порог, который позволяет большему количеству образцов классифицироваться как положительный класс. В результате средняя прибыль на предсказание улучшается.
from sklearn.model_selection import TunedThresholdClassifierCV
from sklearn.metrics import make_scorer
custom_scorer = make_scorer(
custom_score, response_method="predict", greater_is_better=True
)
tuned_classifier = TunedThresholdClassifierCV(
classifier_05, cv=5, scoring=custom_scorer
).fit(X, y)
print(f"Tuned decision threshold: {tuned_classifier.best_threshold_:.3f}")
print(f"Custom score: {custom_score(y_test, tuned_classifier.predict(X_test)):.2f}")
Tuned decision threshold: 0.071 Custom score: 0.04
Мы наблюдаем, что настройка порога принятия решения может превратить основанную на машинном обучении систему, которая в среднем приносит убытки, в выгодную.
На практике определение осмысленной метрики, специфичной для приложения, может включать в себя зависимость стоимости неправильных прогнозов и прибыли от правильных прогнозов от вспомогательных метаданных, специфичных для каждого отдельного элемента данных, таких как сумма транзакции в системе обнаружения мошенничества.
TunedThresholdClassifierCV использует поддержку маршрутизации метаданных (Руководство пользователя по маршрутизации метаданных), что позволяет оптимизировать сложные бизнес-метрики, как подробно описано в Настройка порога принятия решения для обучения с учетом стоимости.
Улучшения производительности в PCA
PCA имеет новый решатель, "covariance_eigh", который вплоть до порядка величины быстрее и эффективнее с точки зрения памяти по сравнению с другими решателями для наборов данных с большим количеством точек данных и небольшим количеством признаков.
from sklearn.datasets import make_low_rank_matrix
from sklearn.decomposition import PCA
X = make_low_rank_matrix(
n_samples=10_000, n_features=100, tail_strength=0.1, random_state=0
)
pca = PCA(n_components=10, svd_solver="covariance_eigh").fit(X)
print(f"Explained variance: {pca.explained_variance_ratio_.sum():.2f}")
Explained variance: 0.88
Новый решатель также принимает разреженные входные данные:
from scipy.sparse import random
X = random(10_000, 100, format="csr", random_state=0)
pca = PCA(n_components=10, svd_solver="covariance_eigh").fit(X)
print(f"Explained variance: {pca.explained_variance_ratio_.sum():.2f}")
Explained variance: 0.13
Решатель "full" также был улучшен для использования меньшего объема памяти и позволяет более быструю трансформацию. По умолчанию svd_solver="auto"` опция использует новый решатель и теперь может выбирать подходящий решатель для разреженных наборов данных.
Аналогично большинству других решателей PCA, новый решатель "covariance_eigh" может использовать вычисления на GPU, если входные данные передаются в виде массива PyTorch или CuPy, включив экспериментальную поддержку Array API.
ColumnTransformer поддерживает индексацию
Трансформеры ColumnTransformer теперь можно напрямую получить, используя индексацию по имени.
import numpy as np
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
X = np.array([[0, 1, 2], [3, 4, 5]])
column_transformer = ColumnTransformer(
[("std_scaler", StandardScaler(), [0]), ("one_hot", OneHotEncoder(), [1, 2])]
)
column_transformer.fit(X)
print(column_transformer["std_scaler"])
print(column_transformer["one_hot"])
StandardScaler() OneHotEncoder()
Пользовательские стратегии импутации для SimpleImputer
SimpleImputer теперь поддерживает пользовательские стратегии импутации, используя вызываемый объект, который вычисляет скалярное значение из значений, отличных от пропусков, вектора столбца.
from sklearn.impute import SimpleImputer
X = np.array(
[
[-1.1, 1.1, 1.1],
[3.9, -1.2, np.nan],
[np.nan, 1.3, np.nan],
[-0.1, -1.4, -1.4],
[-4.9, 1.5, -1.5],
[np.nan, 1.6, 1.6],
]
)
def smallest_abs(arr):
"""Return the smallest absolute value of a 1D array."""
return np.min(np.abs(arr))
imputer = SimpleImputer(strategy=smallest_abs)
imputer.fit_transform(X)
array([[-1.1, 1.1, 1.1],
[ 3.9, -1.2, 1.1],
[ 0.1, 1.3, 1.1],
[-0.1, -1.4, -1.4],
[-4.9, 1.5, -1.5],
[ 0.1, 1.6, 1.6]])
Расстояния попарно с нечисловыми массивами
pairwise_distances теперь может вычислять расстояния между нечисловыми массивами, используя вызываемый метрический объект.
from sklearn.metrics import pairwise_distances
X = ["cat", "dog"]
Y = ["cat", "fox"]
def levenshtein_distance(x, y):
"""Return the Levenshtein distance between two strings."""
if x == "" or y == "":
return max(len(x), len(y))
if x[0] == y[0]:
return levenshtein_distance(x[1:], y[1:])
return 1 + min(
levenshtein_distance(x[1:], y),
levenshtein_distance(x, y[1:]),
levenshtein_distance(x[1:], y[1:]),
)
pairwise_distances(X, Y, metric=levenshtein_distance)
array([[0., 3.],
[3., 2.]])
Общее время выполнения скрипта: (0 минут 0,741 секунды)
Связанные примеры
© 2007–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/auto_examples/release_highlights/plot_release_highlights_1_5_0.html