73

liblinear 和 nltk 等机器学习包中的分类器提供了一种方法show_most_informative_features(),这对调试功能非常有帮助:

viagra = None          ok : spam     =      4.5 : 1.0
hello = True           ok : spam     =      4.5 : 1.0
hello = None           spam : ok     =      3.3 : 1.0
viagra = True          spam : ok     =      3.3 : 1.0
casino = True          spam : ok     =      2.0 : 1.0
casino = None          ok : spam     =      1.5 : 1.0

我的问题是是否为 scikit-learn 中的分类器实现了类似的功能。我搜索了文档,但找不到类似的东西。

如果还没有这样的功能,有人知道如何获得这些值的解决方法吗?

4

9 回答 9

66

分类器本身不记录特征名称,它们只看到数字数组。但是,如果您使用Vectorizer/ CountVectorizer/ TfidfVectorizer/提取特征DictVectorizer并且使用线性模型(例如LinearSVC或朴素贝叶斯),那么您可以应用文档分类示例使用的相同技巧。示例(未经测试,可能包含一个或两个错误):

def print_top10(vectorizer, clf, class_labels):
    """Prints features with the highest coefficient values, per class"""
    feature_names = vectorizer.get_feature_names()
    for i, class_label in enumerate(class_labels):
        top10 = np.argsort(clf.coef_[i])[-10:]
        print("%s: %s" % (class_label,
              " ".join(feature_names[j] for j in top10)))

这是用于多类分类;对于二进制情况,我认为你应该clf.coef_[0]只使用。您可能需要对class_labels.

于 2012-06-20T09:51:55.117 回答
54

在 larsmans 代码的帮助下,我为二进制案例提出了以下代码:

def show_most_informative_features(vectorizer, clf, n=20):
    feature_names = vectorizer.get_feature_names()
    coefs_with_fns = sorted(zip(clf.coef_[0], feature_names))
    top = zip(coefs_with_fns[:n], coefs_with_fns[:-(n + 1):-1])
    for (coef_1, fn_1), (coef_2, fn_2) in top:
        print "\t%.4f\t%-15s\t\t%.4f\t%-15s" % (coef_1, fn_1, coef_2, fn_2)
于 2012-06-21T14:55:49.690 回答
16

添加更新,RandomForestClassifier现在支持.feature_importances_属性。该属性告诉您该特征解释了多少观察到的方差。显然,所有这些值的总和必须 <= 1。

我发现这个属性在执行特征工程时非常有用。

感谢 scikit-learn 团队和贡献者的实现!

编辑:这适用于 RandomForest 和 GradientBoosting。所以RandomForestClassifier, RandomForestRegressor,GradientBoostingClassifierGradientBoostingRegressor支持这一点。

于 2016-08-13T07:31:42.823 回答
13

我们最近发布了一个库(https://github.com/TeamHG-Memex/eli5),它允许这样做:它处理来自 scikit-learn、二进制/多类案例的各种分类器,允许根据特征值突出显示文本, 与 IPython 等集成。

于 2016-11-24T17:42:54.873 回答
5

实际上,我必须在我的 NaiveBayes 分类器上找出特征重要性,尽管我使用了上述函数,但我无法根据类获得特征重要性。我浏览了 scikit-learn 的文档并稍微调整了上述功能,以发现它可以解决我的问题。希望对你也有帮助!

def important_features(vectorizer,classifier,n=20):
    class_labels = classifier.classes_
    feature_names =vectorizer.get_feature_names()

    topn_class1 = sorted(zip(classifier.feature_count_[0], feature_names),reverse=True)[:n]
    topn_class2 = sorted(zip(classifier.feature_count_[1], feature_names),reverse=True)[:n]

    print("Important words in negative reviews")

    for coef, feat in topn_class1:
        print(class_labels[0], coef, feat)

    print("-----------------------------------------")
    print("Important words in positive reviews")

    for coef, feat in topn_class2:
        print(class_labels[1], coef, feat)

请注意,您的分类器(在我的情况下是 NaiveBayes)必须具有属性 feature_count_ 才能正常工作。

于 2018-06-12T06:42:28.140 回答
1

您还可以执行以下操作来按顺序创建重要性特征图:

importances = clf.feature_importances_
std = np.std([tree.feature_importances_ for tree in clf.estimators_],
         axis=0)
indices = np.argsort(importances)[::-1]

# Print the feature ranking
#print("Feature ranking:")


# Plot the feature importances of the forest
plt.figure()
plt.title("Feature importances")
plt.bar(range(train[features].shape[1]), importances[indices],
   color="r", yerr=std[indices], align="center")
plt.xticks(range(train[features].shape[1]), indices)
plt.xlim([-1, train[features].shape[1]])
plt.show()
于 2016-08-01T14:55:15.973 回答
0

RandomForestClassifier还没有coef_属性,但我认为它将在 0.17 版本中。但是,请参阅使用 scikit-learn 对随机森林进行递归特征消除中RandomForestClassifierWithCoef的课程。这可能会给您一些解决上述限制的想法。

于 2015-07-28T18:35:13.777 回答
0

不完全是您正在寻找的东西,而是一种快速获取最大幅度系数的方法(假设 pandas 数据框列是您的特征名称):

您对模型进行了如下训练:

lr = LinearRegression()
X_train, X_test, y_train, y_test = train_test_split(df, Y, test_size=0.25)
lr.fit(X_train, y_train)

获取 10 个最大的负系数值(或更改为 reverse=True 以获得最大的正值),例如:

sorted(list(zip(feature_df.columns, lr.coef_)), key=lambda x: x[1], 
reverse=False)[:10]
于 2019-02-28T22:19:40.673 回答
0

首先做一个列表,我给这个列表命名标签。之后提取所有特征名称和列名称,我将其添加到标签列表中。这里我使用朴素贝叶斯模型。在朴素贝叶斯模型中,feature_log_prob_ 给出特征的概率。

def top20(model,label):

  feature_prob=(abs(model.feature_log_prob_))

  for i in range(len(feature_prob)):

    print ('top 20 features for {} class'.format(i))

    clas = feature_prob[i,:]

    dictonary={}

    for count,ele in enumerate(clas,0): 

      dictonary[count]=ele

    dictonary=dict(sorted(dictonary.items(), key=lambda x: x[1], reverse=True)[:20])

    keys=list(dictonary.keys())

    for i in keys:

      print(label[i])

    print('*'*1000)
于 2020-01-09T18:33:24.483 回答