如何缩放 SelectKBest 以进行特征选择

机器算法验证 特征选择 scikit-学习
2022-04-18 01:41:22

我正在尝试SelectKBest选择最重要的功能:

# SelectKBest: 
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
sel = SelectKBest(chi2, k='all')

# Load Dataset: 
from sklearn import datasets
iris = datasets.load_iris() 

# Run SelectKBest on scaled_iris.data
newx = sel.fit_transform(iris.data, iris.target)
print(newx[0:5])

它工作正常,输出为:

[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]]

但是,当我尝试SelectKBest在缩放数据上使用时,出现错误:

# Scale iris.data
from sklearn.preprocessing import StandardScaler    
scaler = StandardScaler()
X = scaler.fit_transform(iris.data) 

# Run SelectKBest on scaled_iris.data
newx = sel.fit_transform(X, iris.target)

输出错误:

ValueError: Input X must be non-negative.

如何缩放数据以便为此目的没有负值?还是在从数据集中选择特征时完全不需要缩放?

2个回答

我认为问题在于您使用的是 chi2 评分功能。如果您改为使用 f_classif 评分函数,则不会因为数据集中有负值而出现任何错误。因此,如果您想使用 chi2,那么您需要以某种方式转换您的数据以消除负数(您可以对其进行标准化,使所有值都介于 0 和 1 之间,或者您可以将最小值设置为 0,或者执行无数的东西可以消除负面影响)。如果您已经在使用某种归一化值,例如 z 分数,因此不想再进行归一化,那么您应该考虑使用 ANOVA (f_classif) 评分函数来进行特征选择。

所以本质上,为了直接回答这个问题,从数据集中选择特征可能不需要额外的缩放来消除负面影响。如果您使用 z-score 归一化或其他使用负数的归一化(可能您的数据介于 -1 和 +1 之间),您可以只使用 f_classif 评分函数,它不仅需要正数。

作为如何使数据缩放以使用 chi2 的一个示例:当我在 sklearn 中使用 chi2 评分函数时,我从根本没有标准化的数据开始。然后,我通过执行以下操作对数据进行标准化,使其介于 0 和 1 之间:

normed_data= (data - data.min(0)) / data.ptp(0)

这里,data.min(0)返回每个数据列的最小值,并data.ptp(0)返回每个数据列的范围。所以normed_data最终成为一个矩阵,其中每一列都被独立归一化以落在 [0, 1] 的范围内。

您可以使用MinMaxScaler默认情况下,它将缩放范围内的数据[0,1]

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(X)
scaler.transform(X)