Scikit-Learn unterstützt in der Tat keine schrittweise Regression. Das liegt daran, dass das, was gemeinhin als "schrittweise Regression" bezeichnet wird, ein Algorithmus ist, der auf p-Werten von linearen Regressionskoeffizienten basiert, und das Lernen mit Hilfe von Scikits den inferentiellen Ansatz für das Lernen von Modellen (Signifikanztests usw.) bewusst vermeidet. Darüber hinaus ist reines OLS nur einer von zahlreichen Regressionsalgorithmen und aus der Sicht des Scikit-Learn weder sehr wichtig noch einer der besten.
Es gibt jedoch einige Ratschläge für diejenigen, die noch eine gute Möglichkeit für die Feature-Auswahl mit linearen Modellen benötigen:
- Verwenden Sie von Natur aus spärliche Modelle wie
ElasticNet
oder Lasso
.
- Normalisieren Sie Ihre Funktionen mit
StandardScaler
und ordnen Sie Ihre Funktionen dann einfach nach model.coef_
. Für vollkommen unabhängige Kovariaten entspricht dies der Sortierung nach p-Werten. Die Klasse sklearn.feature_selection.RFE
erledigt dies für Sie und RFECV
bewertet sogar die optimale Anzahl von Funktionen.
- R2
statsmodels
- Führen Sie eine vorwärts- oder rückwärtsgerichtete Brute-Force-Auswahl durch, um Ihre bevorzugte Metrik bei der Kreuzvalidierung zu maximieren (die Anzahl der Kovariaten kann ungefähr quadratisch sein). Ein mit Scikit Learn kompatibles
mlxtend
Paket unterstützt diesen Ansatz für jeden Schätzer und jede Metrik.
- Wenn Sie immer noch eine schrittweise Vanille-Regression wünschen, ist es einfacher, sie zu verwenden
statsmodels
, da dieses Paket p-Werte für Sie berechnet. Eine grundlegende Vorwärts-Rückwärts-Auswahl könnte folgendermaßen aussehen:
`` `
from sklearn.datasets import load_boston
import pandas as pd
import numpy as np
import statsmodels.api as sm
data = load_boston()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target
def stepwise_selection(X, y,
initial_list=[],
threshold_in=0.01,
threshold_out = 0.05,
verbose=True):
""" Perform a forward-backward feature selection
based on p-value from statsmodels.api.OLS
Arguments:
X - pandas.DataFrame with candidate features
y - list-like with the target
initial_list - list of features to start with (column names of X)
threshold_in - include a feature if its p-value < threshold_in
threshold_out - exclude a feature if its p-value > threshold_out
verbose - whether to print the sequence of inclusions and exclusions
Returns: list of selected features
Always set threshold_in < threshold_out to avoid infinite looping.
See https://en.wikipedia.org/wiki/Stepwise_regression for the details
"""
included = list(initial_list)
while True:
changed=False
# forward step
excluded = list(set(X.columns)-set(included))
new_pval = pd.Series(index=excluded)
for new_column in excluded:
model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included+[new_column]]))).fit()
new_pval[new_column] = model.pvalues[new_column]
best_pval = new_pval.min()
if best_pval < threshold_in:
best_feature = new_pval.argmin()
included.append(best_feature)
changed=True
if verbose:
print('Add {:30} with p-value {:.6}'.format(best_feature, best_pval))
# backward step
model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[included]))).fit()
# use all coefs except intercept
pvalues = model.pvalues.iloc[1:]
worst_pval = pvalues.max() # null if pvalues is empty
if worst_pval > threshold_out:
changed=True
worst_feature = pvalues.argmax()
included.remove(worst_feature)
if verbose:
print('Drop {:30} with p-value {:.6}'.format(worst_feature, worst_pval))
if not changed:
break
return included
result = stepwise_selection(X, y)
print('resulting features:')
print(result)
In diesem Beispiel wird die folgende Ausgabe gedruckt:
Add LSTAT with p-value 5.0811e-88
Add RM with p-value 3.47226e-27
Add PTRATIO with p-value 1.64466e-14
Add DIS with p-value 1.66847e-05
Add NOX with p-value 5.48815e-08
Add CHAS with p-value 0.000265473
Add B with p-value 0.000771946
Add ZN with p-value 0.00465162
resulting features:
['LSTAT', 'RM', 'PTRATIO', 'DIS', 'NOX', 'CHAS', 'B', 'ZN']