是否有一种方法可以测试所有可能的特征组合,以查看哪种组合为我对scikit-learn感兴趣的一组特征提供最高的系数强度?
例如,如果有10个特征,我想测试所有可能的组合,看看哪一组特征对我感兴趣的三个特征的强度最高。
我尝试使用F回归内置函数,但它并没有给出哪个功能实际上是有用的指示。
这是可能的,但首先我们需要定义powerset可能的特征。(这适应了itertools
文档中的定义,并假设我们对所有集至少两个特性感兴趣。例如:(0, 1)
,(0, 2)
,(0, 3)
,…(0, 1, 2, 3, 4)
)。
from itertools import chain, combinations
def powerset(iterable):
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(2, len(s)+1))
现在我们可以遍历特性的幂集中的每一个集合:
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
# Create a demo set with 10 features and split into train/test
X, y = make_regression(n_features=10, n_informative=4)
X_train, X_test, y_train, y_test = train_test_split(X, y)
reg = LinearRegression()
best_features = None
best_score = -np.inf
# Iterate over all possible sets of variables
for c in powerset(range(X.shape[1])):
reg.fit(X_train[:, c], y_train)
# The "best" score is the one that maximizes the coefficient of determination
if (score := reg.score(X_test[:, c], y_test)) > best_score:
best_score = score
best_features = c
print(f"Best set: {best_features}, best score: {best_score}")
结果如下:
Best set: (1, 3, 5, 9), best score: 1.0
警告: powerset的大小与(2 ** N)
成比例增长,其中N
是特征的数量。(2 ** 10) = 1024
,所以在这种情况下可以测试所有这些。该方法还可以对数据的分裂和使用的回归量敏感。
scikit-learn
内置的启发式方法是"递归特征消除与交叉验证";(参见:RFECV),它尝试使用交叉验证来估计每个特征的重要性,并逐步删除特征。