如何为 scikit-learn 的朴素贝叶斯指定先验概率
Posted
技术标签:
【中文标题】如何为 scikit-learn 的朴素贝叶斯指定先验概率【英文标题】:How to specify the prior probability for scikit-learn's Naive Bayes 【发布时间】:2015-09-02 23:18:00 【问题描述】:我正在将 scikit-learn 机器学习库 (Python) 用于机器学习项目。我正在使用的算法之一是高斯朴素贝叶斯实现。 GaussianNB() 函数的属性之一如下:
class_prior_ : array, shape (n_classes,)
我想手动更改之前的类,因为我使用的数据非常倾斜,并且召回其中一个类非常重要。通过为该类分配高先验概率,召回率应该会增加。
但是,我不知道如何正确设置属性。我已经阅读了以下主题,但它们的答案对我不起作用。
How can the prior probabilities manually set for the Naive Bayes clf in scikit-learn?
How do I know what prior's I'm giving to sci-kit learn? (Naive-bayes classifiers.)
这是我的代码:
gnb = GaussianNB()
gnb.class_prior_ = [0.1, 0.9]
gnb.fit(data.XTrain, yTrain)
yPredicted = gnb.predict(data.XTest)
我认为这是正确的语法,我可以通过处理值找出哪个类属于数组中的哪个位置,但结果保持不变。也没有给出错误。
从 scikit-learn 库中设置 GaussianNB 算法属性的正确方法是什么?
Link to the scikit documentation of GaussianNB
【问题讨论】:
【参考方案1】:@Jianxun Li:其实在 GaussianNB 中有一种设置先验概率的方法。它被称为“先验”,可作为参数使用。请参阅文档: “参数:先验:类数组,形状(n_classes,) 类的先验概率。如果指定,则不会根据数据调整先验。” 那我举个例子吧:
from sklearn.naive_bayes import GaussianNB
# minimal dataset
X = [[1, 0], [1, 0], [0, 1]]
y = [0, 0, 1]
# use empirical prior, learned from y
mn = GaussianNB()
print mn.fit(X,y).predict([1,1])
print mn.class_prior_
>>>[0]
>>>[ 0.66666667 0.33333333]
但是如果你改变了先验概率,它会给出一个不同的答案,我相信这就是你正在寻找的。p>
# use custom prior to make 1 more likely
mn = GaussianNB(priors=[0.1, 0.9])
mn.fit(X,y).predict([1,1])
>>>>array([1])
【讨论】:
好收获。此功能是在提出问题后添加的。 github.com/scikit-learn/scikit-learn/commit/…【参考方案2】:在 scikit-learn 中实现的 GaussianNB() 不允许你设置类先验。如果您阅读在线文档,您会看到 .class_prior_ 是一个属性,而不是参数。一旦适合 GaussianNB(),您就可以访问 class_prior_ 属性。它是通过简单地计算训练样本中不同标签的数量来计算的。
from sklearn.datasets import make_classification
from sklearn.naive_bayes import GaussianNB
# simulate data with unbalanced weights
X, y = make_classification(n_samples=1000, weights=[0.1, 0.9])
# your GNB estimator
gnb = GaussianNB()
gnb.fit(X, y)
gnb.class_prior_
Out[168]: array([ 0.105, 0.895])
gnb.get_params()
Out[169]:
您会发现估算器足够聪明,可以考虑重量不平衡的问题。所以你不必手动指定先验。
【讨论】:
嗯,这确实解释了很多。您是否知道任何方法可以将分类器引导到某个方向?在我的例子中,一个类的召回比另一个类的整体精度和召回更重要。谢谢 @PepijnvanDiepen 在不更改代码的情况下,有一种方法:如果召回第 1 类很重要,则添加标签为第 1 类的每个训练示例的额外副本。这将导致第 1 类具有更高的先验概率,这将使算法更频繁地预测第 1 类。以上是关于如何为 scikit-learn 的朴素贝叶斯指定先验概率的主要内容,如果未能解决你的问题,请参考以下文章
NLTK 和 scikit-learn 中的伯努利朴素贝叶斯结果不同
Scikit-learn 使用朴素贝叶斯进行 10 折交叉验证的多类分类
在 python 中使用 BernoulliNB(朴素贝叶斯分类器)scikit-learn 的简单示例 - 无法解释分类