Можно ли в scikit-learn показать вероятность метки для нескольких моделей? - PullRequest
0 голосов
/ 01 августа 2020

У меня есть модель VoteClassifier, которая состоит из следующих алгоритмов:

  • байесовский классификатор
  • SV C
  • LinearSV C
  • NuSV C
  • MNB
  • BernoulliNB
  • LogisticRegression

Я обучил некоторые данные, чтобы получить вероятность и вероятность для всех возможных метки, например, если у меня есть две метки: x и y, а метод вероятности набора функций дает x, тогда я хочу знать, что это была вероятность результата для меток x и y. В соответствии с этим ответом я использую функцию prob_classify (документация здесь ) из метода ClassifierI модуля nltk.clssify для достижения этой цели, и идея состоит в том, что В конце этого расчета получите среднее значение всех вероятностей, чтобы показать окончательную вероятность для двух меток, но это не работает для всех моделей, особенно для моделей машин опорных векторов. Ниже я объясню сценарий с аналогичным воспроизводимым кодом:

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)))

Я получил следующую ошибку с последними тремя моделями SV C:

    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. Любая помощь будет оценена по достоинству.

1 Ответ

2 голосов
/ 02 августа 2020

Эти модели реализуют функцию predic_proba, но она доступна не для всех возможных конфигураций этих моделей.

Например, SVM по умолчанию не предсказывают вероятности, если вы посмотрите на их математическое определение. Они просто находят лучшую разделяющую гиперплоскость и сообщают вам, с какой стороны находится точка (положительная / отрицательная).

Чтобы разрешить SVM в sklearn выводить вероятности, вам нужно изменить настройку probability на True когда вы создаете экземпляр класса SV C (внутренне это запустит вывод SV C через логистическую c регрессию, чтобы получить вероятность).

clf = SVC(probability=True)

То же самое SGDClassifier, который не поддерживает predict_proba при использовании потери петель по умолчанию.

...