Я пытаюсь понять, как использовать RFE для решения проблем регрессии, и я читал несколько руководств.
Я нашел пример того, как использовать RFECV для автоматического выбора идеального количества функций, и он выглядит примерно так:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold
from sklearn.feature_selection import RFECV
rfecv = RFECV(estimator=RandomForestClassifier(random_state=101), step=1, cv=StratifiedKFold(10), scoring='accuracy')
rfecv.fit(X, target)
print(np.where(rfecv.support_ == False)[0])
что я нахожу довольно простым.
Однако я проверял, как сделать то же самое с помощью объекта RFE, но для включения перекрестной проверки я нашел только решения, связанные с использованием конвейеров, например:
X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, random_state=1)
# create pipeline
rfe = RFE(estimator=DecisionTreeRegressor(), n_features_to_select=5)
model = DecisionTreeRegressor()
pipeline = Pipeline(steps=[('s',rfe),('m',model)])
# evaluate model
cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
n_scores = cross_val_score(pipeline, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1, error_score='raise')
# report performance
print(f'MAE: {mean(n_scores):.3f}')
Я не уверен, что именно здесь происходит. Конвейер используется для постановки в очередь алгоритма RFE и второго DecisionTreeRegressor (модели). Если я не ошибаюсь, идея состоит в том, что для каждой итерации перекрестной проверки выполняется RFE, выбирается желаемое количество лучших функций, а затем запускается вторая модель, используя только эти функции. Но как и когда RFE передал информацию о том, какие функции были выбраны, в DecisionTreeRegressor? Это вообще произошло, или в коде отсутствует эта часть?
Ну, во-первых, давайте отметим, что RFECV и RFE выполняют в вашем скрипте две отдельные задачи: первая выбирает оптимальное количество функций, а вторая выбирает пять наиболее важных функций (или наилучшую комбинацию из 5 функций). , учитывая их важность для DecisionTreeRegressor).
Вернемся к вашему вопросу: «Когда RFE передал информацию о том, какие функции были выбраны, в дерево решений?» Стоит отметить, что RFE явно не сообщает дереву решений, какие функции выбраны. Проще говоря, он берет матрицу в качестве входных данных (обучающий набор) и преобразует ее в матрицу из N столбцов на основе параметра n_features_to_select=N
.
Эта матрица (то есть преобразованный обучающий набор) передается в качестве входных данных в дерево решений вместе с целевой переменной, которая возвращает подобранную модель, которую можно использовать для прогнозирования невидимых случаев.
Давайте погрузимся в пример для классификации:
""" Import dependencies and load data """
import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.feature_selection import RFE
from sklearn.metrics import precision_score
from sklearn.tree import DecisionTreeClassifier
X, y = load_breast_cancer(return_X_y=True)
rfe = RFE(estimator=DecisionTreeClassifier(), n_features_to_select=2)
Теперь мы загрузили набор данных breast_cancer и создали экземпляр объекта RFE (я использовал DecisionTreeClassifier, но можно использовать и другие алгоритмы).
Чтобы увидеть, как обучающие данные обрабатываются в конвейере, давайте начнем с ручного примера, который показывает, как конвейер будет работать, если его разложить на «основные шаги»:
from sklearn.model_selection import train_test_split
def test_and_train(X, y, random_state):
# For simplicity, let's use 80%-20% splitting
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=random_state)
# Fit and transform the training data by applying Recursive Feature Elimination
X_train_transformed = rfe.fit_transform(X_train, y_train)
# Transform the testing data to select the same features
X_test_transformed = rfe.transform(X_test)
print(X_train[0:3])
print(X_train_transformed[0:3])
print(X_test_transformed[0:3])
# Train on the transformed trained data
fitted_model = DecisionTreeClassifier().fit(X_train_transformed, y_train)
# Predict on the transformed testing data
y_pred = fitted_model.predict(X_test_transformed)
print('True labels: ', y_test)
print('Predicted labels:', y_pred)
return y_test, y_pred
precisions = list() # to store the precision scores (can be replaced by any other evaluation measure)
y_test, y_pred = test_and_train(X, y, 42)
precisions.append(precision_score(y_test, y_pred))
y_test, y_pred = test_and_train(X, y, 84)
precisions.append(precision_score(y_test, y_pred))
y_test, y_pred = test_and_train(X, y, 168)
precisions.append(precision_score(y_test, y_pred))
print('Average precision:', np.mean(precisions))
"""
Average precision: 0.92
"""
В приведенном выше скрипте мы создали функцию, которая с учетом набора данных X
и целевой переменной y
fit_transform
на RFE он запускает рекурсивное устранение признаков и сохраняет информацию о выбранных признаках в состоянии своего объекта. Чтобы узнать, какие функции выбраны, звоните rfe.support_
.
Примечание. В тестовом наборе выполняется только преобразование, поэтому функции в rfe.support_
используются для фильтрации других функций из тестового набора.y_test
и y_pred
можно использовать для анализа производительности модели, например, ее точности.
Точность сохраняется в массиве, и процедура повторяется 3 раза.
Наконец, мы печатаем среднюю точность.
Мы смоделировали процедуру перекрестной проверки, разделив исходные данные 3 раза в соответствующих наборах для обучения и тестирования, подогнали модель, вычислили и усреднили ее производительность (то есть точность) по трем кратностям. Этот процесс можно упростить с помощью проверки RepeatedKFold:
from sklearn.model_selection import RepeatedKFold
precisions = list()
rkf = RepeatedKFold(n_splits=2, n_repeats=3, random_state=1)
for train_index, test_index in rkf.split(X, y):
# print("TRAIN:", train_index, "TEST:", test_index)
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
X_train_transformed = rfe.fit_transform(X_train, y_train)
X_test_transformed = rfe.transform(X_test)
fitted_model = DecisionTreeClassifier().fit(X_train_transformed, y_train)
y_pred = fitted_model.predict(X_test_transformed)
precisions.append(precision_score(y_test, y_pred))
print('Average precision:', np.mean(precisions))
"""
Average precision: 0.93
"""
и даже дальше с Pipeline:
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_score
rkf = RepeatedKFold(n_splits=2, n_repeats=3, random_state=1)
pipeline = Pipeline(steps=[('s',rfe),('m',DecisionTreeClassifier())])
precisions = cross_val_score(pipeline, X, y, scoring='precision', cv=rkf)
print('Average precision:', np.mean(precisions))
"""
Average precision: 0.93
"""
Таким образом, когда исходные данные передаются в конвейер, последний:
RFE.fit_transform()
данные обучения;RFE.transform()
к данным тестирования, чтобы они состояли из одних и тех же функций;estimator.fit()
данные обучения, чтобы подогнать (т. е. обучить) модель;estimator.predict()
данные тестирования, чтобы предсказать их.scoring
) внутри.В конце процедуры кто-то может получить доступ к результатам производительности и усреднить их по складкам.
@s.dallapalma Пожалуйста, не могли бы вы помочь мне с этим вопросом? stackoverflow.com/questions/71279499/…
«Мы смоделировали процедуру перекрестной проверки, разделив исходные данные 3 раза в соответствующем наборе для обучения и тестирования». Мне кажется, что исходные данные разделяются два раза, и каждый повторяется 3 раза, что дает в общей сложности 6 результатов. .
Вау, большое спасибо, вы действительно не могли бы быть более исчерпывающим, чем это! Я полностью пропустил часть, где конвейер использует fit_transform для обучающих данных... теперь, когда вы объяснили эту часть, все стало понятно. Грэйзи Милле!