75

我在 Python 中使用 scikit-learn 开发一种分类算法来预测某些客户的性别。其中,我想使用朴素贝叶斯分类器,但我的问题是我混合了分类数据(例如:“在线注册”、“接受电子邮件通知”等)和连续数据(例如:“年龄”、“长度”会员资格”等)。我以前没怎么用过 scikit,但我认为高斯朴素贝叶斯适用于连续数据,而伯努利朴素贝叶斯可用于分类数据。但是,由于我想在我的模型中同时包含分类数据和连续数据,我真的不知道如何处理这个问题。任何想法将不胜感激!

4

6 回答 6

73

你至少有两个选择:

  • 通过计算每个连续变量的百分位数,然后使用百分位数作为分箱边界对连续变量进行分箱,将所有数据转换为分类表示。例如,对于一个人的身高,创建以下箱:“非常小”、“小”、“常规”、“大”、“非常大”,确保每个箱包含大约 20% 的训练集人口。我们没有任何实用程序可以在 scikit-learn 中自动执行此操作,但您自己做应该不会太复杂。然后在您的数据的这些分类表示上拟合一个唯一的多项式 NB。

  • 在数据的连续部分独立拟合高斯 NB 模型,在分类部分独立拟合多项式 NB 模型。然后通过将类分配概率(使用predict_proba方法)作为新特征来转换所有数据集:np.hstack((multinomial_probas, gaussian_probas))然后在新特征上重新拟合一个新模型(例如一个新的高斯 NB)。

于 2013-01-10T10:07:55.673 回答
15

希望我不会太晚。我最近用 NumPy 编写了一个名为 Mixed Naive Bayes 的库。它可以假设训练数据特征上混合了高斯和分类(multinoulli)分布。

https://github.com/remykarem/mixed-naive-bayes

该库的编写使得 API 类似于scikit-learn的。

在下面的示例中,假设前 2 个特征来自分类分布,后 2 个特征是高斯分布。在fit()方法中,只需指定categorical_features=[0,1],表示第 0 列和第 1 列服从分类分布。

from mixed_naive_bayes import MixedNB
X = [[0, 0, 180.9, 75.0],
     [1, 1, 165.2, 61.5],
     [2, 1, 166.3, 60.3],
     [1, 1, 173.0, 68.2],
     [0, 2, 178.4, 71.0]]
y = [0, 0, 1, 1, 0]
clf = MixedNB(categorical_features=[0,1])
clf.fit(X,y)
clf.predict(X)

Pip 可通过pip install mixed-naive-bayes. 有关 README.md 文件中的用法的更多信息。非常感谢拉取请求:)

于 2019-10-17T08:22:44.563 回答
14

简单的答案:乘以结果!一样的。

朴素贝叶斯基于应用贝叶斯定理和每对特征之间独立性的“朴素”假设——这意味着你计算贝叶斯概率取决于特定特征而不保留其他特征——这意味着算法将来自一个特征的每个概率乘以第二个特征的概率(我们完全忽略了分母——因为它只是一个归一化器)。

所以正确的答案是:

  1. 从分类变量计算概率。
  2. 从连续变量计算概率。
  3. 乘以 1 和 2。
于 2015-12-02T06:28:46.527 回答
1

@Yaron 的方法需要一个额外的步骤(下面的 4.):

  1. 根据分类变量计算概率。
  2. 从连续变量计算概率。
  3. 乘以 1. 和 2. AND
  4. 将 3. 除以 1. 和 2 的乘积之和。编辑:我的实际意思是分母应该是(给定低血压的事件概率为)+(给定低血压的证据概率为)(假设一个二元问题,不失一般性)。因此,给定证据的假设()的概率总和为 1。

步骤 4. 是标准化步骤。以@remykaremmixed-naive-bayes为例(第 268-278 行):

        if self.gaussian_features.size != 0 and self.categorical_features.size != 0:
            finals = t * p * self.priors
        elif self.gaussian_features.size != 0:
            finals = t * self.priors
        elif self.categorical_features.size != 0:
            finals = p * self.priors

        normalised = finals.T/(np.sum(finals, axis=1) + 1e-6)
        normalised = np.moveaxis(normalised, [0, 1], [1, 0])

        return normalised

高斯和分类模型的概率(tp分别)在第 269 行(上面摘录中的第 2 行)中相乘,然后在第 275 行(上面摘录中从底部的第四行)中的 4. 中进行归一化。

于 2021-06-03T09:29:50.477 回答
1

对于混合功能,您可以检查实现。

作者在他的Quora 回答中提出了数学证明,您可能想检查一下。

于 2021-10-07T13:31:45.430 回答
1

您将需要以下步骤:

  1. 从分类变量计算概率(使用predict_proba方法 from BernoulliNB
  2. 从连续变量计算概率(使用predict_proba方法 from GaussianNB
  3. 乘以 1. 和 2. AND
  4. 除以先验(来自BernoulliNB或来自,GaussianNB因为它们相同)然后
  5. 将 4 除以 4 的总和(在类上)。这是标准化步骤。

应该很容易看出如何添加自己的先验而不是使用从数据中学到的先验。

于 2021-11-11T13:35:27.350 回答