Примечание
Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.
Рекурсивное исключение признаков с перекрёстной проверкой
Пример рекурсивного исключения признаков (RFE) с автоматическим подбором числа выбранных признаков с помощью перекрёстной проверки.
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause
Генерация данных
Мы создаём задачу классификации с использованием 3 информативных признаков. Добавление 2 дополнительных избыточных (то есть коррелирующих) признаков приводит к тому, что выбранные признаки различаются в зависимости от фолда перекрёстной проверки. Остальные признаки неинформативны, поскольку их значения выбираются случайным образом.
from sklearn.datasets import make_classification
n_features = 15
feat_names = [f"feature_{i}" for i in range(15)]
X, y = make_classification(
n_samples=500,
n_features=n_features,
n_informative=3,
n_redundant=2,
n_repeated=0,
n_classes=8,
n_clusters_per_class=1,
class_sep=0.8,
random_state=0,
)
Обучение и выбор модели
Мы создаём объект RFE и вычисляем оценки с помощью перекрёстной проверки. Стратегия оценки «accuracy» оптимизирует долю правильно классифицированных образцов.
from sklearn.feature_selection import RFECV
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold
min_features_to_select = 1 # Minimum number of features to consider
clf = LogisticRegression()
cv = StratifiedKFold(5)
rfecv = RFECV(
estimator=clf,
step=1,
cv=cv,
scoring="accuracy",
min_features_to_select=min_features_to_select,
n_jobs=2,
)
rfecv.fit(X, y)
print(f"Optimal number of features: {rfecv.n_features_}")
Optimal number of features: 3
В данном случае наиболее оптимальной оказалась модель с 3 признаками (что соответствует истинной порождающей модели).
Зависимость оценок перекрёстной проверки от числа признаков
import matplotlib.pyplot as plt
import pandas as pd
data = {
key: value
for key, value in rfecv.cv_results_.items()
if key in ["n_features", "mean_test_score", "std_test_score"]
}
cv_results = pd.DataFrame(data)
plt.figure()
plt.xlabel("Number of features selected")
plt.ylabel("Mean test accuracy")
plt.errorbar(
x=cv_results["n_features"],
y=cv_results["mean_test_score"],
yerr=cv_results["std_test_score"],
)
plt.title("Recursive Feature Elimination \nwith correlated features")
plt.show()

На приведённом выше графике также можно заметить плато эквивалентных оценок (с близкими средними значениями и перекрывающимися полосами погрешностей) для 3–5 выбранных признаков. Это результат добавления коррелирующих признаков. Действительно, оптимальная модель, выбранная RFE, может находиться в этом диапазоне в зависимости от метода перекрёстной проверки. Точность на тестовой выборке снижается при выборе более 5 признаков: сохранение неинформативных признаков приводит к переобучению и, следовательно, ухудшает статистические характеристики моделей.
import numpy as np
for i in range(cv.n_splits):
mask = rfecv.cv_results_[f"split{i}_support"][
rfecv.n_features_ - 1
] # mask of features selected by the RFE
features_selected = np.ma.compressed(np.ma.masked_array(feat_names, mask=1 - mask))
print(f"Features selected in fold {i}: {features_selected}")
Features selected in fold 0: ['feature_3' 'feature_4' 'feature_8'] Features selected in fold 1: ['feature_3' 'feature_4' 'feature_8'] Features selected in fold 2: ['feature_3' 'feature_4' 'feature_8'] Features selected in fold 3: ['feature_3' 'feature_4' 'feature_8'] Features selected in fold 4: ['feature_3' 'feature_4' 'feature_8']
Во всех пяти фолдах выбранные признаки совпадают. Это хорошая новость: она означает, что выбор стабилен во всех фолдах, и подтверждает, что эти признаки наиболее информативны.
Общее время выполнения скрипта: (0 минут 0.693 секунды)
Связанные примеры
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/feature_selection/plot_rfe_with_cross_validation.html