【问题标题】:sklearn MultinomialNB only predicts class priorssklearn MultinomialNB 只预测类先验
【发布时间】:2018-09-12 03:14:43
【问题描述】:

我目前正在尝试为分类特征推出自己的朴素贝叶斯分类器,以确保我理解它们。现在我想将它们与 sklearns MultinomialNB 进行比较。但由于某种原因,我无法让 searn 版本正确运行。 我认为最容易比较的是 kaggle Titanic 数据集。所以它做到了(这很简单,对吧?):

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。最奇怪的是,它显然只是给出了 class prior P(y) 的概率(我用我的自制算法检查;))每个预测。所以它显然不会将它与可能性 P(X|y) 相乘。

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

编辑:

我想我现在明白了。如果我将输入数据集转换为列联表,并对输入特征进行 one-hot 编码,它会给出相同的预测概率。我使用了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]...

【问题讨论】:

  • 您只训练一项功能。也许该特征与标签高度相关,因此 P(X|y) 接近 1。您可以尝试使用其他特征吗?
  • 嘿 Selçuk,我也尝试了其他功能,但它仍然只给了我之前的课程。我还尝试了两个功能。然后发生的有趣的事情是,它没有给我先验类,except 当所有功能都为 0 时。但是,我仍然不相信两个功能的结果。我的算法给了我完全不同的结果(这当然可能是我的算法的错;)。但由于 1 功能案例在 sklearn 中不起作用...)

标签: python machine-learning scikit-learn


【解决方案1】:

多项朴素贝叶斯模型的工作方式与给定单一特征的预期完全相同。如果你看一下formula for P(X|y),当特征数n=1时它等于1。这就是原因。

朴素贝叶斯模型的不同之处在于它们对条件分布 P(X | y) 所做的假设。多项朴素贝叶斯假设这是一个多项分布。多项分布对滚动(可能有偏差的)k 面骰子 n 次的计数概率进行建模。

例如,假设给您一个由 FairDice 和 Crooks&Co 两家公司生产的骰子派对。 FairDice 以生产公平骰子而闻名,而 Crooks&Co 生产的装载骰子绝大多数以 6 点在顶部。您被要求通过多次投掷骰子并查看结果来学习预测骰子的生产者。您将每个骰子掷几次,并将结果记录在具有 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     

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

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

单面死。它们存在!

例如如果您的功能具有值 [3,2,1],则意味着您掷第一个骰子 3 次,每次得到 1,掷第二个骰子两次,两次都得到 1,掷第三个骰子一次,得到 1。这没有提供有关骰子生产者的信息,因此您可以预测的最好的是先验类别,这正是算法所做的。

【讨论】:

  • 感谢您的回答!显然,问题在于输入的格式不正确。我用一个可行的解决方案更新了我的原始帖子。我想我对 sklearn 的文档感到困惑,该文档指出,输入的形状必须是 [n_samples, n_features],而它显然必须是 [n_classes, n_features]。现在唯一令人困惑的是,为什么 sklearn 不会在新算法中自动计算类先验。另外,感谢您让我知道单面骰子。他们可能有一天会派上用场,你永远不会知道;)
猜你喜欢
  • 2018-11-04
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 2016-08-10
  • 2017-08-22
  • 2020-01-18
  • 2018-04-19
  • 1970-01-01
相关资源
最近更新 更多