【问题标题】:Plot ROC curve for Nearest Centroid绘制最近质心的 ROC 曲线
【发布时间】:2018-05-14 07:39:06
【问题描述】:

我想绘制一条 ROC 曲线来评估经过训练的最近质心分类器。 我的代码适用于朴素贝叶斯、SVM、kNN 和 DT,但每当我尝试绘制最近质心的曲线时都会出现异常,因为估计器没有 .predict_proba() 方法:

AttributeError: 'NearestCentroid' object has no attribute 'predict_proba'

绘制曲线的代码是

def plot_roc(self):
    plt.clf()
        
    for label, estimator in self.roc_estimators.items():
        estimator.fit(self.data_train, self.target_train)
        proba_for_each_class = estimator.predict_proba(self.data_test)

        fpr, tpr, thresholds = roc_curve(self.target_test, proba_for_each_class[:, 1])

        plt.plot(fpr, tpr, label=label)

    plt.plot([0, 1], [0, 1], linestyle='--', lw=2, color='r', label='Luck', alpha=.8)

    plt.ylabel('True Positive Rate')
    plt.xlabel('False Positive Rate')
    plt.legend()
    plt.show()

self.roc_estimators 是一个字典,我在其中存储训练有素的估计器和分类器的标签,如下所示

cl_label = "kNN"
knn_estimator = KNeighborsClassifier(algorithm='ball_tree', p=2, n_neighbors=5)
knn_estimator.fit(self.data_train, self.target_train)
self.roc_estimators[cl_label] = knn_estimator

和最近的质心分别

cl_label = "Nearest Centroid"
nc_estimator = NearestCentroid(metric='euclidean', shrink_threshold=6)
nc_estimator.fit(self.data_train, self.target_train)
self.roc_estimators[cl_label] = nc_estimator

所以它适用于我尝试过的所有分类器,但不适用于最近的质心。关于我缺少的最近质心分类器的性质是否有具体原因,这解释了为什么无法绘制 ROC 曲线(更具体地说,为什么估计器没有.predict_proba() 方法?)提前谢谢你!

【问题讨论】:

    标签: python matplotlib plot scikit-learn


    【解决方案1】:

    每个预测都需要一个“分数”来制作 ROC 曲线。这可能是属于一个类别的预测概率。

    参见例如https://en.wikipedia.org/wiki/Receiver_operating_characteristic#Curves_in_ROC_space

    只寻找最近的质心会给你预测的类,而不是概率。

    编辑:对于 NearestCentroid,无法计算分数。这只是模型的限制。它为每个样本分配一个类别,但不是该类别的概率。我想如果你需要使用最近的质心并且你想要一个概率,你可以使用一些集成方法。训练一堆训练数据子集的模型,并在测试集上平均它们的预测。这可以给你一个分数。见 scikit-learn.org/stable/modules/ensemble.html#bagging

    【讨论】:

    • 感谢您的回答,虽然我的proba_for_each_class[:, 1] 是您建议的分数,我猜?问题不在于 roc corve 本身的情节,也许那是一个误导性的短语。我无法计算最近质心的分数。
    • 是的,NearestCentroid 无法计算分数。这只是模型的限制。它为每个样本分配一个类别,但不是该类别的概率。我想如果你需要使用最近的质心并且你想要一个概率,你可以使用一些集成方法。训练一堆训练数据子集的模型,并在测试集上平均它们的预测。这可以给你一个分数。见scikit-learn.org/stable/modules/ensemble.html#bagging
    • 好的,谢谢!您可以在回答中插入您的评论,我接受。
    • @ncw NearestCentroid 根据最小距离分配类。您可以获取所有类的距离,然后将它们转换为某种概率。
    • @ncw 当然,我在答案中添加了评论
    【解决方案2】:

    要获得类概率,您可以执行以下操作(未经测试的代码):

    from sklearn.utils.extmath import softmax
    from sklearn.metrics.pairwise import pairwise_distances
    
    def predict_proba(self, X):
        distances = pairwise_distances(X, self.centroids_, metric=self.metric)
        probs = softmax(distances)
        return probs
    
    clf = NearestCentroid()
    clf.fit(X_train, y_train)
    predict_proba(clf, X_test)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-04
      • 2019-02-27
      • 2021-03-03
      • 2013-08-10
      • 2012-01-01
      • 2017-09-11
      • 2020-08-15
      • 2019-02-05
      相关资源
      最近更新 更多