sklearn MultinomialNB仅预测班级先验

时间:2018-04-02 21:35:34

标签: python machine-learning scikit-learn

我目前正尝试将自己的朴素贝叶斯分类器用于分类功能,以确保我理解它们。现在我想将它们与sklearns MultinomialNB进行比较。但由于某些原因,我无法正确运行该版本。 最简单的比较我认为是摇摆泰坦尼克号数据集。所以它做到了这一点(这很简单,对吧?):

import numpy as np
import pandas as pd
from sklearn.naive_bayes import MultinomialNB

train = pd.read_csv('data/in/train.csv')

X = np.asarray(train[['Pclass']])
y = np.asarray(train['Survived'])

clf = MultinomialNB()
clf.fit(X, y)
clf.predict_proba(X)

但它实际上预测(或者不是,在这种情况下......)是泰坦尼克号上的每个人都死了。或者换句话说,当要预测的类标签是[0, 1]时,它预测为0.最奇怪的是,它显然只是给出了类先验 P(y)的概率(我用我的homebrewn算法检查;))每个预测。所以它显然不会与可能性P(X | y)相乘。

有没有人遇到过这个?我在这里犯了一些明显的错误吗?

修改

我想我现在明白了。如果我将输入数据集转换为列联表,并对输入要素进行单热编码,则会给出相同的预测概率。我使用alpha=0的平滑来与我自己的算法进行比较:

import numpy as np
import pandas as pd
from sklearn.naive_bayes import MultinomialNB

train = pd.read_csv('data/in/train.csv')

X_test = np.asarray(pd.get_dummies(train['Pclass']))

X = np.array(pd.crosstab(train[y_column], train['Pclass']))
y = np.array([0,1])

clf = MultinomialNB(alpha=0.0000000001, class_prior=np.array(class_prior))
clf.fit(X, y)
clf.predict_proba(X_test)

仍然,我想知道的一件事是,为什么我现在必须先手动指定类。如果我不能这样做,那么sklearn现在使用了一个不知情的先验,[0.5, 0.5] ...

1 个答案:

答案 0 :(得分:0)

多项式朴素贝叶斯模型的工作原理完全符合一个特征。如果你看一下formula for P(X|y),当特征数n = 1时它等于1。这就是原因。

朴素贝叶斯模型通过它们对条件分布P(X | y)的假设而彼此不同。 Multinomial Naive Bayes假设这是一个多项分布。多项分布模拟滚动(可能有偏差的)k侧模具n次的计数概率。

例如,假设您有两家公司制作的骰子派对:FairDice和Crooks& Co.众所周知,FairDice可以生产出合理的骰子,而Crooks& Co生产的骰子绝对是最重要的骰子。你被要求学习如何预测骰子的生产者多次投掷它并查看结果。您将每个骰子抛出几次,并将结果记录在具有6个特征的数据集中。每个特征表示投掷骰子时相应值的发生次数。

count_1 count_2 count_3 count_4 count_5 count_6 fair_dice
5       6       4       7       6       5       1
3       2       1       2       1       13      0     

现在,这是用于训练多项式朴素贝叶斯分类器的适当数据集。

在单个特征上训练多项式朴素贝叶斯分类器相当于尝试在顶部对具有相同数字的单侧骰子进行分类。

A one-sided die. They are real! 单面死亡。它们存在!

E.g。如果你的特征有值[3,2,1],那就意味着你扔掉了第一个骰子三次并且每次都得到1次,把第二次骰子扔了两次并且两次得到1次,扔掉第三个骰子一次得到1。没有给出关于骰子制作者的信息,所以你可以预测的最好是类先验,这正是算法所做的。