【问题标题】:使用 scikit-learn 在朴素贝叶斯分类器中混合分类和连续数据
【发布时间】:2012-12-24 14:54:03
【问题描述】:

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

【问题讨论】:

  • 您好,您能说出哪种解决方案最适合您吗?

标签: python machine-learning data-mining classification scikit-learn


【解决方案1】:

您至少有两个选择:

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

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

【讨论】:

  • @ogrisel:我是否认为第二种方法可能会丢失连续数据和分类数据之间的相关性?例如,假设在线注册的年轻人通常是男性,但未在线注册的年轻人通常是女性。但为了具体起见,进一步假设高斯 NB 模型预测的年轻人(不知道分类数据)通常是男性。由于只有这个概率被传递到第二阶段的高斯 NB,它会错过相关性。
  • @unutbu:朴素贝叶斯分类器假定给定类的特征是独立的。上面列出的第一种方法将独立学习P(age|gender)P(registration_type|gender)。对于给定的性别,年龄和registration_type 之间的相关性不会被捕获。
  • @ogrisel 我们可以使用 one-hot-encoding 将分类变量转换为 n 类的 0 和 n-1 之间的值,并保持 GaussianNB() 的连续变量吗?基于这篇文章:dataaspirant.com/2017/02/20/…
  • @jai,不!首先,one-hot 编码与转换为 0 到 n-1 之间的值不同。其次,将分类变量转换为 0 到 n-1 之间的值,然后将它们视为连续变量是没有意义的。第三,单热分类变量是so非高斯的,以我的经验,将它们视为高斯(GaussianNB 假设)不会产生好的结果。
  • @ogrisel,我认为predict_proba 将用于预测“测试”数据的概率。例如。我在训练数据上创建了 2 个单独的分类器,然后我可以使用它来预测我剩余的 test 数据的概率。如果我然后在来自test 数据的predict_proba 结果上训练另一个高斯模型,那不是没有什么可测试的了吗?我看对了吗?干杯
【解决方案2】:

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

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

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

在下面的示例中,我们假设前 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 install mixed-naive-bayes 安装 Pip。有关 README.md 文件中的用法的更多信息。非常感谢拉取请求:)

【讨论】:

    【解决方案3】:

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

    朴素贝叶斯基于应用贝叶斯定理和每对特征之间独立的“朴素”假设 - 这意味着您根据特定特征计算贝叶斯概率而不保留其他特征 - 这意味着算法将每个概率相乘一个特征与第二个特征的概率(我们完全忽略了分母 - 因为它只是一个规范化器)。

    所以正确答案是:

    1. 根据分类变量计算概率。
    2. 根据连续变量计算概率。
    3. 乘以 1. 和 2.

    【讨论】:

    • Gaussian NB 给出了先验的密度估计。我不确定你对第二部分的意思。
    • @Davis,我不确定你的意思,但高斯 NB 意味着假设特征的可能性是高斯的,这就是 P(x|y) 的计算方式。
    • 我的意思是不再有 Pr(x_i | y),但是这个先验被替换为 Norm(mu_i, sig_i) 这是一个密度估计,因为 Pr(X_i = x | y) 的概率为 0,因为 RV X_i 是连续的。
    • 我认为您的问题与主题无关,但您可以通过以下方式获得答案:stats.stackexchange.com/questions/26624/…
    • Yaron ,当你说calculate the probabilities 时,这是在测试数据还是训练数据上,你会使用什么函数来做到这一点?您是否在火车数据上使用predict-proba 并在火车数据上进行拟合?我正在努力弄清楚我应该增加什么......干杯
    【解决方案4】:

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

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

    步骤 4. 是标准化步骤。以@remykarem 的mixed-naive-bayes 为例(lines 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. 进行归一化在上面的摘录中)。

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        【解决方案6】:

        您将需要以下步骤:

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

        应该很容易了解如何添加自己的先验知识,而不是使用从数据中学到的知识。

        【讨论】:

          猜你喜欢
          • 2017-06-21
          • 2013-03-22
          • 2018-06-19
          • 2014-10-09
          • 2017-01-10
          • 2013-12-24
          • 2013-06-24
          • 2013-08-07
          相关资源
          最近更新 更多