朴素贝叶斯概率始终为1

8
我开始使用 sklearn.naive_bayes.GaussianNB 进行文本分类,并获得了良好的初始结果。我希望使用分类器返回的概率作为置信度的衡量标准,但是 predict_proba() 方法总是返回所选类别的"1.0",而其余所有类别的值均为"0.0"。
我知道(来自此处)"...从 predict_proba 输出的概率不应该被过分重视",但是到这种程度?!分类器可能会将finance-investingchords-strings弄混,但predict_proba()输出没有任何犹豫的迹象...
一些背景信息:
- 我一直在使用sklearn.feature_extraction.text.TfidfVectorizer进行特征提取,起初并没有使用stop_wordsmin/max_df来限制词汇表,因此我得到的向量非常大。
- 我一直在使用层次分类树(浅层:不超过3层深度),每个类别有7个文本(手动分类)。目前,它是flat训练:我没有考虑层次结构。

生成的GaussianNB对象非常大(约300MB),预测速度相对较慢:一个文本需要大约1秒钟。
这可能相关吗?这些巨大的向量是问题的根源吗?
我如何获得有意义的预测?我需要使用不同的分类器吗?

这是我正在使用的代码:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import GaussianNB
import numpy as np
from sklearn.externals import joblib

Vectorizer = TfidfVectorizer(input = 'content')
vecs = Vectorizer.fit_transform(TextsList) # ~2000 strings
joblib.dump(Vectorizer, 'Vectorizer.pkl') 
gnb = GaussianNB()
Y = np.array(TargetList) # ~2000 categories 
gnb.fit(vecs.toarray(), Y)
joblib.dump(gnb, 'Classifier.pkl') 
...

#In a different function:
Vectorizer = joblib.load('Vectorizer.pkl')
Classifier = joblib.load('Classifier.pkl')
InputList = [Text] # One string
Vec = Vectorizer.transform(InputList)
Probs = Classifier.predict_proba([Vec.toarray()[0]])[0]
MaxProb = max(Probs)
MaxProbIndex = np.where(Probs==MaxProb)[0][0]
Category = Classifier.classes_[MaxProbIndex]
result = (Category, MaxProb)  

更新:
根据以下建议,我尝试了MultinomialNBLogisticRegression。它们都返回不同的概率,并且在我的任务中更好:分类更准确,内存占用更小,速度更快(MultinomialNB非常快!)。

现在我有一个新问题:返回的概率非常小-通常在0.004-0.012的范围内。这是预测/获胜类别的情况(分类是准确的)。

1个回答

15
“...从predict_proba得到的概率输出不应该被过于认真地对待。”
我是写下这句话的人。意思是朴素贝叶斯倾向于预测几乎总是非常接近于零或非常接近于一的概率;这正是你观察到的行为。逻辑回归(sklearn.linear_model.LogisticRegressionsklearn.linear_model.SGDClassifier(loss="log"))会产生更现实的概率。
“由此产生的GaussianNB对象非常大(〜300MB),预测相当缓慢:一个文本需要约1秒钟时间。”
那是因为GaussianNB是非线性模型,不支持稀疏矩阵(你已经发现了这一点,因为你正在使用toarray)。使用MultinomialNBBernoulliNB或逻辑回归,它们在预测时更快,并且更小。它们对输入的假设也更符合关于术语特征的现实情况。GaussianNB真的不是文本分类的好估计器。

我会重新表述为一个问题:我对我得到的非常低的概率值(在 MultinomialNBLogisticRegression 中)应该怎么处理?我可以认真对待它们吗?是因为我的分类太接近了吗?注意:分类结果相当准确。 - AviM
@AviM:他们怎么可能太接近呢?极端概率更表明你的样本远离决策边界。 - Fred Foo
太靠近了,我的意思是。你认为 max(Classifier.predict_proba(Vec)[0]) 给出像 0.001 这样的值有什么意义吗?(Classifier = MultinomialNB() / LogisticRegression() ) - AviM
@AviM:你的问题可能很简单,或者你没有正则化到位。尝试调整alpha(NB)或C(LR)。 - Fred Foo
谢谢,我会尝试的。顺便说一下,我引用的数字错了:大约是0.01,而不是0.001。 - AviM
显示剩余4条评论

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