从递归特征消除(RFE)中提取最优特征

我有一个包含分类和数值数据的数据集,共有124个特征。为了降低其维度,我希望删除不相关的特征。然而,为了在特征选择算法上运行数据集,我使用了get_dummies进行独热编码,这使得特征数量增加到了391个。

In[16]:X_train.columnsOut[16]:Index([u'port_7', u'port_9', u'port_13', u'port_17', u'port_19', u'port_21',   ...   u'os_cpes.1_2', u'os_cpes.1_1'], dtype='object', length=391)

使用生成的数据,我可以运行带有交叉验证的递归特征消除,按照Scikit Learn示例进行操作:

这会产生以下结果:

交叉验证得分与特征图

鉴于确定的最优特征数量为8,我如何识别这些特征的名称?我假设我可以将它们提取到一个新的DataFrame中,用于分类算法中?


[编辑]

我通过以下方式实现了这一点,得到了这篇文章的帮助:

def column_index(df, query_cols):    cols = df.columns.values    sidx = np.argsort(cols)    return sidx[np.searchsorted(cols, query_cols, sorter = sidx)]feature_index = []features = []column_index(X_dev_train, X_dev_train.columns.values)for num, i in enumerate(rfecv.get_support(), start=0):    if i == True:        feature_index.append(str(num))for num, i in enumerate(X_dev_train.columns.values, start=0):    if str(num) in feature_index:        features.append(X_dev_train.columns.values[num])print("Features Selected: {}\n".format(len(feature_index)))print("Features Indexes: \n{}\n".format(feature_index))print("Feature Names: \n{}".format(features))

这会产生以下输出:

Features Selected: 8Features Indexes: ['5', '6', '20', '26', '27', '28', '67', '98']Feature Names: ['port_21', 'port_22', 'port_199', 'port_512', 'port_513', 'port_514', 'port_3306', 'port_32768']

由于独热编码引入了多重共线性,我认为目标列的选择并不理想,因为它选择的特征是未编码的连续数据特征。我尝试重新添加未编码的目标列,但RFE抛出了以下错误,因为数据是分类数据:

ValueError: could not convert string to float: Wireless Access Point

我是否需要将多个独热编码的特征列组合起来作为目标?


[编辑2]

如果我只是对目标列进行标签编码,我可以使用这个目标作为’y’,参见再次查看示例。然而,输出仅确定一个特征(目标列)为最优。我认为这可能是由于独热编码的原因,我是否应该考虑生成一个密集数组,如果是的话,它可以运行在RFE上吗?


回答:

回答我自己的问题,我发现问题出在对数据进行独热编码的方式上。最初,我对所有分类列进行了如下独热编码:

ohe_df = pd.get_dummies(df[df.columns])              # 对所有列进行独热编码

这引入了大量的额外特征。采取不同的方法,在这里得到了一些帮助,我修改了编码方式,以按列/特征为基础对多个列进行编码,如下所示:

cf_df = df.select_dtypes(include=[object])      # 获取分类特征nf_df = df.select_dtypes(exclude=[object])      # 获取数值特征ohe_df = nf_df.copy()for feature in cf_df:    ohe_df[feature] = ohe_df.loc[:,(feature)].str.get_dummies().values.tolist()

生成的结果如下:

ohe_df.head(2)      # 仅显示数据的一部分+---+---------------------------------------------------+-----------------+-----------------+-----------------------------------+---------------------------------------------------+|   |                      os_name                      |    os_family    |     os_type     |             os_vendor             |                     os_cpes.0                     |+---+---------------------------------------------------+-----------------+-----------------+-----------------------------------+---------------------------------------------------+| 0 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... | [0, 1, 0, 0, 0] | [1, 0, 0, 0, 0] | [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0] | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, ... || 1 | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... | [0, 0, 0, 1, 0] | [0, 0, 0, 1, 0] | [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0] | [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... |+---+---------------------------------------------------+-----------------+-----------------+-----------------------------------+---------------------------------------------------+

不幸的是,尽管这是我一直在寻找的,但它无法在RFECV上执行。接下来我想或许我可以取所有新特征的一个切片并将其作为目标传递,但这导致了错误。最后,我意识到我必须遍历所有目标值并从每个目标值中提取最佳输出。代码最终看起来像这样:

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注