【问题标题】:Find the most import features for a SVM classification查找 SVM 分类的最重要特征
【发布时间】:2018-03-16 11:43:46
【问题描述】:

我正在使用python 和流行的scikit-learn 模块的SVM 类训练一个二元分类器。训练后,我使用predict 方法进行分类,如sci-kit's SVC documentation 中所述。

我想更多地了解我的样本特征对训练有素的decision_function(支持向量)进行的分类结果的重要性。欢迎使用此类模型进行预测时评估特征重要性的任何策略。

谢谢! 安德烈

【问题讨论】:

    标签: python machine-learning scikit-learn statistics svm


    【解决方案1】:

    那么,我们如何解释给定样本分类的特征重要性?

    我认为使用线性内核是最直接的方法来解决这个问题,因为训练模型的svc.coef_ 属性的重要性/相对简单性。 check out Bitwise's answer.

    下面我将使用scikit 训练数据训练一个线性核 SVM。然后我们将查看coef_ 属性。我将包含一个简单的图表,显示分类器系数和训练特征数据的点积如何划分结果类。

    from sklearn import svm
    from sklearn.datasets import load_breast_cancer
    import numpy as np
    import matplotlib.pyplot as plt
    
    data = load_breast_cancer()
    X = data.data                # training features
    y = data.target              # training labels
    lin_clf = svm.SVC(kernel='linear')
    lin_clf.fit(X,y)
    
    scores = np.dot(X, lin_clf.coef_.T)
    
    b0 = y==0 # boolean or "mask" index arrays
    b1 = y==1
    malignant_scores = scores[b1]
    benign_scores = scores[b1]
    
    fig  = plt.figure()
    fig.suptitle("score breakdown by classification", fontsize=14, fontweight='bold')
    score_box_plt = ply.boxplot(
        [malignant_scores, benign_scores],
        notch=True,
        labels=list(data.target_names),
        vert=False
    )
    plt.show(score_box_plt)        
    

    如您所见,我们似乎确实访问了适当的截距和系数值。当我们的决策边界徘徊在 0 左右时,班级分数有明显的分离。

    现在我们有了一个基于线性系数的评分系统,我们可以轻松地研究每个特征对最终分类的贡献。在这里,我们展示了每个特征对该样本最终得分的影响。

    ## sample we're using X[2] --> classified benign, lin_clf score~(-20)
    lin_clf.predict(X[2].reshape(1,30))
    
    contributions = np.multiply(X[2], lin_clf.coef_.reshape((30,)))
    feature_number = np.arange(len(contributions)) +1
    
    plt.bar(feature_number, contributions, align='center')
    plt.xlabel('feature index')
    plt.ylabel('score contribution')
    plt.title('contribution to classification outcome by feature index')
    plt.show(feature_contrib_bar)
    

    我们还可以简单地对相同的数据进行排序,以获得给定分类的特征贡献排名列表,以查看哪个特征对我们正在评估其组成的 score 贡献最大。

    abs_contributions = np.flip(np.sort(np.absolute(contributions)), axis=0)
    feat_and_contrib = []
    for contrib in abs_contributions:
       if contrib not in contributions:
           contrib = -contrib
           feat = np.where(contributions == contrib)
           feat_and_contrib.append((feat[0][0], contrib))
       else:
           feat = np.where(contributions == contrib)
           feat_and_contrib.append((feat[0][0], contrib))
    
    # sorted by max abs value. each row a tuple:;(feature index, contrib)
    feat_and_contrib 
    

    从该排名列表中,我们可以看到对最终得分(大约 -20 以及分类“良性”)做出贡献的前五个特征指数是[0, 22, 13, 2, 21],它们对应于我们数据集中的特征名称; ['mean radius', 'worst perimeter', 'area error', 'mean perimeter', 'worst texture'].

    【讨论】:

      【解决方案2】:

      假设你有词袋特征化并且你想知道哪些词是重要的 用于分类,然后将此代码用于线性 svm

      weights = np.abs(lr_svm.coef_[0])
      sorted_index = np.argsort(wt)[::-1]
      top_10 = sorted_index[:10]
      terms = text_vectorizer.get_feature_names()
      for ind in top_10:
          print(terms[ind])
      

      【讨论】:

        【解决方案3】:

        您可以使用SelectFromModel in sklearn 来获取与您的模型最相关的特征的名称。 Here is an example 为 LassoCV 提取特征。

        您还可以查看this example,它利用 SVM 中的 coef_ 属性来可视化最重要的功能。

        【讨论】:

          猜你喜欢
          • 2013-03-25
          • 2019-09-25
          • 2018-11-29
          • 2016-06-29
          • 2012-03-13
          • 2017-09-19
          • 2015-12-07
          • 2019-11-26
          • 2017-05-26
          相关资源
          最近更新 更多