我目前正在使用sklearn的Ridge分类器,我希望将这个分类器与sklearn和其他库的分类器集成在一起。为了做到这一点,理想的做法是提取给定输入属于类列表中每个类的概率。目前,我正在用model.decision_function(x)的输出压缩类,但这返回到超平面的距离,而不是直接的概率。这些距离值从-1到1不等。
distances = dict(zip(clf.classes_, clf.decision_function(x)[0]))
我如何将这些距离转换为更具体的概率集(一系列之和为1的正值)?我正在寻找类似于clf.predict_proba()
的东西,它是为sklearn中的SVC实现的。
进一步的探索导致使用softmax函数
d = clf.decision_function(x)[0]
probs = np.exp(d) / np.sum(np.exp(d))
这保证了0-1有界分布的和为1。
稍微看一下predict
的源代码,可以看出decision_function
实际上是实际类概率的logit变换,即如果decision funciton
是f
,那么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
等
这里提供的解决方案对我不起作用。我认为softmax
函数是正确的解决方案,所以我用类似于LogisticRegressionCV的predict_proba
方法扩展了RidgeClassifierCV类
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)