【问题标题】:It is possible to show label probability in scikit-learn for several models?可以在 scikit-learn 中显示多个模型的标签概率吗?
【发布时间】:2020-11-22 08:29:05
【问题描述】:

我有一个包含以下算法的 VoteClassifier 模型:

  • 贝叶斯分类器
  • SVC
  • 线性SVC
  • NuSVC
  • MNB
  • 伯努利NB
  • 逻辑回归

我已经训练了一些数据来获得所有可能标签的概率和概率,例如,如果我有两个标签:x 和 y,并且特征集的概率方法导致 x,那么我想知道那是x 和 y 标签的结果概率。根据这个answer,我正在使用nltk.clssify模块的ClassifierI方法中的prob_classify(文档here)函数来实现那个东西,想法是在这个计算结束时,得到平均值显示两个标签的最终概率的所有概率,但它不适用于所有模型,特别是支持向量机模型。 我在下面用类似的可重现代码解释了这个场景:

from nltk.classify.scikitlearn import SklearnClassifier
from sklearn.svm import SVC, LinearSVC, NuSVC
from nltk import classify, NaiveBayesClassifier
from sklearn.naive_bayes import MultinomialNB,BernoulliNB
from sklearn.linear_model import LogisticRegression,SGDClassifier
import random

dataset = [
    (dict(a=1,b=1,c=1), 'y'),
    (dict(a=1,b=1,c=1), 'x'),
    (dict(a=1,b=1,c=0), 'y'),
    (dict(a=0,b=1,c=1), 'x'),
    (dict(a=0,b=1,c=1), 'y'),
    (dict(a=0,b=0,c=1), 'y'),
    (dict(a=0,b=1,c=0), 'x'),
    (dict(a=0,b=0,c=0), 'x'),
    (dict(a=0,b=1,c=1), 'y'),
]

random.shuffle(dataset)
slice_size = round(len(dataset)*70/100)
train_data, test_data = dataset[:slice_size], dataset[slice_size:]

#------ This works fine --------------

Bayesian_classifier = NaiveBayesClassifier.train(train_data)
dist = Bayesian_classifier.prob_classify((dict(a=0,b=1,c=1)))
print ("x:"+str(dist.prob('x')),"y:"+str(dist.prob('y')))

MultinomialNB_classifier = SklearnClassifier(MultinomialNB())
MultinomialNB_classifier.train(train_data)
dist = MultinomialNB_classifier.prob_classify((dict(a=0,b=1,c=1)))
print ("x:"+str(dist.prob('x')),"y:"+str(dist.prob('y')))

BernoulliNB_classifier = SklearnClassifier(BernoulliNB())
BernoulliNB_classifier.train(train_data)
dist = BernoulliNB_classifier.prob_classify((dict(a=0,b=1,c=1)))
print ("x:"+str(dist.prob('x')),"y:"+str(dist.prob('y')))

LogisticRegression_classifier = SklearnClassifier(LogisticRegression())
LogisticRegression_classifier.train(train_data)
dist = LogisticRegression_classifier.prob_classify((dict(a=0,b=1,c=1)))
print ("x:"+str(dist.prob('x')),"y:"+str(dist.prob('y')))

#------ But this doesn't work --------------

SVC_classifier = SklearnClassifier(SVC())
SVC_classifier.train(train_data)
SVC_classifier.prob_classify((dict(a=0,b=1,c=1)))

LinearSVC_classifier = SklearnClassifier(LinearSVC())
LinearSVC_classifier.train(train_data)
LinearSVC_classifier.prob_classify((dict(a=0,b=1,c=1)))

NuSVC_classifier = SklearnClassifier(NuSVC())
NuSVC_classifier.train(train_data)
NuSVC_classifier.prob_classify((dict(a=0,b=1,c=1)))

最后三个 SVC 模型出现以下错误:

    raise AttributeError("predict_proba is not available when "
AttributeError: predict_proba is not available when  probability=False

我也尝试过使用 SGDClassifier,但我得到了一个不同的错误:

SGDClassifier_classifier = SklearnClassifier(SGDClassifier())
SGDClassifier_classifier.train(train_data)
SGDClassifier_classifier.prob_classify((dict(a=0,b=1,c=1)))
 line 984, in _check_proba
    " loss=%r" % self.loss)
AttributeError: probability estimates are not available for loss='hinge'

所以我的问题是: 我认为并非所有 sklearn 模型都支持prob_classify() 功能,但如果我这样做:

>>> dir(SVC_classifier)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', '__weakref__', '_clf', '_encoder', '_make_probdist', '_vectorizer', 'classify', 'classify_many', 'labels', 'prob_classify', 'prob_classify_many', 'train', 'unicode_repr']

我将prob_classify() 函数作为一个可能的选项,与SGDClassifier_classifier 相同,所以我缺少什么?有没有可能?请解释一下原因。

目前,我可以得到最终结果,但只能使用贝叶斯、MNB、BernoulliNB 和 LogisticRegression 算法。任何帮助将不胜感激。

【问题讨论】:

    标签: python machine-learning scikit-learn nltk


    【解决方案1】:

    这些模型实现了predic_proba 功能,但它不适用于这些模型的所有可能配置。

    例如,如果您查看 SVM 的数学定义,默认情况下 SVM 不会预测概率。他们只是找到最好的分离超平面并告诉你点在哪一侧(正/负)。

    为了让 sklearn 中的 SVM 输出概率,您需要在实例化 SVC 类时将设置 probability 更改为 True(在内部,这将通过逻辑回归运行 SVC 的输出以获取概率) .

    clf = SVC(probability=True)
    

    SGDClassifier 也是如此,当您使用默认铰链损失时,它不支持 predict_proba

    【讨论】:

    • 它与SVCNuSVC 一起工作得很好,我得到了相同的结果,所以我想我得到了这个结果,因为正如你所说,它们都使用相同的逻辑回归过程,所以我考虑为我的VoteClassifier 模型只使用其中一个(根据classify() 函数最好的)。所以谢谢你的解释。
    猜你喜欢
    • 2015-04-12
    • 2015-12-01
    • 2018-04-10
    • 1970-01-01
    • 2017-07-18
    • 2018-04-05
    • 2018-01-24
    • 2019-12-21
    • 2015-01-10
    相关资源
    最近更新 更多