管道中的python特征选择:如何确定特征名称?

Posted

技术标签:

【中文标题】管道中的python特征选择:如何确定特征名称?【英文标题】:python feature selection in pipeline: how determine feature names? 【发布时间】:2016-01-27 08:13:26 【问题描述】:

我使用 pipeline 和 grid_search 来选择最佳参数,然后使用这些参数来拟合最佳管道 ('best_pipe')。然而,由于 feature_selection (SelectKBest) 在管道中,因此没有适用于 SelectKBest。

我需要知道“k”个选定特征的特征名称。任何想法如何检索它们?提前谢谢你

from sklearn import (cross_validation, feature_selection, pipeline,
                     preprocessing, linear_model, grid_search)
folds = 5
split = cross_validation.StratifiedKFold(target, n_folds=folds, shuffle = False, random_state = 0)

scores = []
for k, (train, test) in enumerate(split):

    X_train, X_test, y_train, y_test = X.ix[train], X.ix[test], y.ix[train], y.ix[test]

    top_feat = feature_selection.SelectKBest()

    pipe = pipeline.Pipeline([('scaler', preprocessing.StandardScaler()),
                                 ('feat', top_feat),
                                 ('clf', linear_model.LogisticRegression())])

    K = [40, 60, 80, 100]
    C = [1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001]
    penalty = ['l1', 'l2']

    param_grid = ['feat__k': K,
                  'clf__C': C,
                  'clf__penalty': penalty]

    scoring = 'precision'

    gs = grid_search.GridSearchCV(estimator=pipe, param_grid = param_grid, scoring = scoring)
    gs.fit(X_train, y_train)

    best_score = gs.best_score_
    scores.append(best_score)

    print "Fold:   :.4f".format(k+1, scoring, best_score)
    print gs.best_params_

best_pipe = pipeline.Pipeline([('scale', preprocessing.StandardScaler()),
                          ('feat', feature_selection.SelectKBest(k=80)),
                          ('clf', linear_model.LogisticRegression(C=.0001, penalty='l2'))])

best_pipe.fit(X_train, y_train)
best_pipe.predict(X_test)

【问题讨论】:

【参考方案1】:

您可以通过best_pipe 中的名称访问功能选择器:

features = best_pipe.named_steps['feat']

然后你可以在一个索引数组上调用transform()来获取选中列的名称:

X.columns[features.transform(np.arange(len(X.columns)))]

这里的输出将是管道中选择的八十个列名。

【讨论】:

从你那里得到解决方案的真正享受 Jake,你实际上通过你的 pycon 教程视频帮助我学习了 python。但是,我收到错误“无法将字符串转换为浮点数:score_575-600”(score_575-600 是其中一列的名称)如何解决? 啊——我忘记了特征选择器不适用于字符串。试试上面的更新版本。很高兴听到这些视频很有帮助! 仍然不确定如何避免上述错误,但这个双步解决方案至少让我得到了 k 个最佳特征的列名: features = best_pipe.named_steps['feat'].get_support() x_cols = X.columns.values[features==True] x_cols 太好了,更新的版本有效!!!虽然不完全清楚如何或为什么......在刷新之前发表了我的评论,所以之前没有看到更新的版本。【参考方案2】:

这可能是一个有益的选择:我遇到了与 OP 提出的类似需求。如果想直接从GridSearchCV 获取 k 个最佳特征的索引:

finalFeatureIndices = gs.best_estimator_.named_steps["feat"].get_support(indices=True)

通过index manipulation,可以得到你的finalFeatureList

finalFeatureList = [initialFeatureList[i] for i in finalFeatureIndices]

【讨论】:

【参考方案3】:

杰克的回答完全有效。但是根据您使用的功能选择器,我认为还有另一个更简洁的选项。这个对我有用:

X.columns[features.get_support()]

它给了我与 Jake 的答案相同的答案。您可以在the docs 中看到更多关于它的信息,但get_support 返回一个真/假值数组,以确定是否使用了该列。此外,值得注意的是X 必须与特征选择器上使用的训练数据具有相同的形状。

【讨论】:

绝对喜欢这个答案,features.transform(np.arange(len(X.columns))) 基本上是features.get_support() 的简写。

以上是关于管道中的python特征选择:如何确定特征名称?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 sklearn 管道中获取通过特征消除选择的特征名称?

情感分析管道,使用特征选择时获取正确特征名称的问题

从 Sklearn 管道中提取具有特征名称的特征重要性

从 Scikit (Python) 中的管道中检索中间特征

使用管道和网格搜索执行特征选择

如何将从逻辑回归模型获得的系数映射到pyspark中的特征名称