如何获取scikit学习分类器的大多数信息功能?


70

诸如liblinear和nltk之类的机器学习包中的分类器提供了一个method 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中的分类器实施了类似的操作。我搜索了文档,但找不到类似的东西。

如果尚无此类功能,是否有人知道如何解决这些值的解决方法?

非常感谢!


您是说最有区别的参数?
西蒙·贝格

我不确定参数的含义。我的意思是最有区别的功能,例如在垃圾邮件分类的词袋模型中,这些词为每个类别提供了最多的证据。就像学习率等-而不是我所理解的“设置”分类的参数
tobigue

9
@eowl:在机器学习中,参数是学习过程根据您的训练集的功能生成的设置。学习率等都是超参数
Fred Foo

Answers:


66

分类器本身不记录要素名称,它们仅显示数字数组。但是,如果使用Vectorizer/ CountVectorizer/ TfidfVectorizer/提取了特征DictVectorizer并且使用的是线性模型(例如LinearSVC,Naive Bayes或Naive Bayes),则可以应用与文档分类示例相同的技巧。示例(未经测试,可能包含一个或两个错误):

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


是的,在我的情况下,我只有两个类,但是通过您的代码,我得以提出我想要的东西。非常感谢!
tobigue 2012年

1
对于2个类,看起来好像coef_不是coef_[0]
瑞恩·R·罗萨里奥

2
@RyanRosario:正确。在二进制情况下,coef_将其展平以节省空间。
Fred Foo 2013年

4
如何确定class_labels?我想知道类标签的顺序。
刘延东2014年

2
您可以使用class_labels=clf.classes_
wassname 2015年

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)

您如何从main方法调用该函数?f1和f2代表什么?我正在尝试使用scikit-learn从决策树分类器调用该函数。

1
该代码仅适用于具有coef_数组的线性分类器,因此很遗憾,我认为无法将其与sklearn的决策树分类器一起使用。fn_1fn_2代表功能名称。
tobigue

16

要添加更新,RandomForestClassifier现在支持该.feature_importances_属性。此属性告诉您该功能可以解释多少观测到的方差。显然,所有这些值的总和必须小于等于1。

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

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

编辑:这适用于RandomForest和GradientBoosting。因此RandomForestClassifierRandomForestRegressorGradientBoostingClassifierGradientBoostingRegressor所有支持这一点。



4

实际上,我必须在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_属性才能起作用。


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()


0

并不是您要找的东西,而是一种获取最大量值系数的快速方法(假设熊猫数据框列是您的特征名称):

您像这样训练模型:

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]

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.