Scikit-learn岭回归分类器:提取类别概率

14

我目前在使用sklearn的Ridge分类器,并希望将此分类器与来自sklearn和其他库的分类器集合起来。为了实现这一点,最好提取一个给定输入属于类别列表中每个类别的概率。目前,我正在使用classes与model.decision_function(x)的输出进行压缩,但这返回超平面距离,而不是直接的概率。这些距离值从大约-1到大约1变化。

distances = dict(zip(clf.classes_, clf.decision_function(x)[0]))  

我该如何将这些距离转换为更具体的概率集合(一系列正值,其总和为1)?我想要像sklearn中SVC的clf.predict_proba()那样的东西。


据我所知,RidgeClassifier上没有predict_proba,因为它不容易被解释为概率模型。可以使用逻辑变换或在[-1, 1]处进行阈值处理,并将其映射到[0, 1],但这两种方法都是hack。 - Fred Foo
是的,我所能做的最好的事情就是对决策函数进行softmax处理,但至少这样做可以a)保持相对顺序和b)使集成更简单。 - Madison May
3个回答

15

进一步探索导致使用softmax函数。

d = clf.decision_function(x)[0]
probs = np.exp(d) / np.sum(np.exp(d))

这保证了一个0-1的有界分布,总和为1。


12

简单查看predict的源代码,可以发现decision_function实际上是实际类别概率的对数变换,即如果decision funcitonf,则class 1的类别概率为exp(f) / (1 + exp(f))。这在sklearn源代码中可以转化为以下检查:

    scores = self.decision_function(X)
    if len(scores.shape) == 1:
        indices = (scores > 0).astype(np.int)
    else:
        indices = scores.argmax(axis=1)
    return self.classes_[indices]
如果你遵循这个检查,它会告诉你,如果决策函数大于零,则预测类1,否则预测类0-一种经典的logit方法。
因此,您需要将决策函数转化为类似于以下内容的东西:
d = clf.decision_function(x)[0]
probs = numpy.exp(d) / (1 + numpy.exp(d))

然后采取适当的zip等操作。


  1. 看起来类似于softmax
  2. 尽管 np.exp(d) / (1 + np.exp(d)) 的输出在0-1范围内受限,但它们并没有被归一化,也似乎不对应于正确的平面距离。换句话说,将决策函数分数的argmax与np.exp(d) / (1 + np.exp(d))的argmax取得的结果不同。有什么想法吗?
- Madison May
2
没关系,我想我已经回答了自己的问题。我相信这个问题的正确解决方案是直接应用softmax函数:np.exp(d) / np.sum(np.exp(d))。虽然如此,您还是指出了我的方向。 - Madison May

3
这里提供的解决方案对我没用。我认为softmax函数是正确的解决方案,因此我扩展了RidgeClassifierCV类,添加了一个类似于LogisticRegressionCVpredict_proba方法。
from sklearn.utils.extmath import softmax
class RidgeClassifierCVwithProba(RidgeClassifierCV):
    def predict_proba(self, X):
        d = self.decision_function(X)
        d_2d = np.c_[-d, d]
        return softmax(d_2d)

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