sklearn:L1特征选择后获取特征名称

5

这个问题和答案展示了当使用scikit-learn的专门特征选择程序之一进行特征选择时,可以按以下方式检索所选特征的名称:

np.asarray(vectorizer.get_feature_names())[featureSelector.get_support()]

例如,在上述代码中,featureSelector 可能是 sklearn.feature_selection.SelectKBestsklearn.feature_selection.SelectPercentile 的实例,因为这些类实现了 get_support 方法,该方法返回所选特征的布尔掩码或整数索引。
当使用 L1 范数惩罚的线性模型进行特征选择时,如何实现不太清楚。 sklearn.svm.LinearSVC 没有 get_support 方法,并且文档没有明确说明如何在使用其 transform 方法消除样本集中的特征后检索特征索引。我是否遗漏了什么?
2个回答

7

对于稀疏估计器,通常可以通过检查系数向量中的非零条目来找到支持(前提是系数向量存在,例如线性模型)。

support = np.flatnonzero(estimator.coef_)

对于使用l1惩罚的LinearSVC,相应的内容如下:

from sklearn.svm import LinearSVC
svc = LinearSVC(C=1., penalty='l1', dual=False)
svc.fit(X, y)
selected_feature_names = np.asarray(vectorizer.get_feature_names())[np.flatnonzero(svc.coef_)]

谢谢!我必须对你的回答进行一次编辑才能使其正常工作(添加了一个调用numpy.flatnonzero的函数)。一旦编辑被接受,我将标记您的答案为已接受(在此期间我不想让任何人感到困惑)。 - Brian D'Astous
感谢您的回复。同样地,您也可以使用np.where(svc.coef_ != 0)[0]代替np.flatnonzero。(因为您的第二次编辑被拒绝了,所以我进行了您建议的补充更正。) - eickenberg

0

我一直在使用sklearn 15.2版本,根据LinearSVC文档,如果n_classes == 2,则coef_是一个数组,形状为[n_features],否则为[n_classes,n_features]。 所以首先,np.flatnonzero不适用于多类。你会遇到索引超出范围的错误。其次,应该使用np.where(svc.coef_ != 0)[1]而不是np.where(svc.coef_ != 0)[0]。0是类别的索引,而不是特征的索引。最终我使用了np.asarray(vectorizer.get_feature_names())[list(set(np.where(svc.coef_ != 0)[1]))]


真的,在多类中这会变得混乱。感谢提醒。提取正确索引的一般方法应该是 np.where(svc.coef_ != 0)[-1],即最后一个索引,这将适用于二元和多类问题。 - eickenberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接