java - 处理朴素贝叶斯分类器中缺失的属性

标签 java machine-learning data-mining bayesian classification

我正在编写一个朴素贝叶斯分类器,用于根据 WiFi 信号强度执行室内房间定位。到目前为止它运行良好,但我对缺少的功能有一些疑问。这种情况经常发生,因为我使用 WiFi 信号,而 WiFi 接入点并不是随处可用。

问题 1:假设我有两个类,Apple 和 Banana,我想按如下方式对测试实例 T1 进行分类。

enter image description here

我完全理解朴素贝叶斯分类器的工作原理。下面是我在 Wikipedia's article 中使用的公式在分类器上。我使用的是统一先验概率 P(C=c),因此我在实现中省略了它。

enter image description here

现在,当我计算等式的右侧并遍历所有类条件特征概率时,我使用哪一组特征?测试实例 T1 使用特征 1、3 和 4,但这两个类并不具备所有这些特征。因此,当我执行循环来计算概率乘积时,我看到了关于循环内容的几个选择:

  1. 遍历训练中所有特征的并集,即特征 1、2、3、4。由于测试实例 T1 没有特征 2,因此使用人为的微小概率。
  2. 仅循环测试实例的特征,即 1、3 和 4。
  3. 遍历每个类可用的功能。要计算“Apple”的类条件概率,我会使用特征 1、2 和 3,而对于“Banana”,我会使用 2、3 和 4。

我应该使用以上哪一个?

问题 2:假设我想对测试实例 T2 进行分类,其中 T2 具有两个类中都没有的特征。我正在使用对数概率来帮助消除下溢,但我不确定循环的细节。我正在做这样的事情(用类似 Java 的伪代码):

Double bestLogProbability = -100000;
ClassLabel bestClassLabel = null;

for (ClassLabel classLabel : allClassLabels)
{
    Double logProbabilitySum = 0.0;

    for (Feature feature : allFeatures)
    {
        Double logProbability = getLogProbability(classLabel, feature);

        if (logProbability != null)
        {
            logProbabilitySum += logProbability;
        }
    }

    if (bestLogProbability < logProbability)
    {
        bestLogProbability = logProbabilitySum;
        bestClassLabel = classLabel;
    }
}

问题是,如果没有任何类具有测试实例的特征(示例中的特征 5),则 logProbabilitySum 将保持为 0.0,导致 bestLogProbability 为 0.0,或线性概率为 1.0,这显然是错误的。有什么更好的方法来处理这个问题?

最佳答案

对于朴素贝叶斯分类器,等式右侧应遍历所有属性。如果您有稀疏填充的属性,通常的处理方法是使用概率的m 估计,它使用等效样本大小 来计算您的概率。当您的训练数据缺少属性值时,这将防止类条件概率变为零。在网络上搜索上面两个粗体字词,您会发现大量关于 m 估计公式的描述。描述这一点的一个很好的引用文本是 Machine Learning由汤姆米切尔。基本公式是

P_i = (n_i + m*p_i)/(n + m)

n_i 是属性值为 f_i 的训练实例数,n 是训练实例数(使用当前分类),m 是等效样本大小,p_i 是 f_i 的先验概率。如果您设置 m=0,这将恢复为标准概率值(可能为零,因为缺少属性值)。随着 m 变得非常大,P_i 接近 p_i(即概率受先验概率支配)。如果你没有先验概率使用,就把它设为 1/k,其中 k 是属性值的个数。

如果您使用这种方法,那么对于您的实例 T2,它在训练数据中没有属性,结果将是训练数据中最常出现的类别。这是有道理的,因为训练数据中没有相关信息可以让您做出更好的决定。

关于java - 处理朴素贝叶斯分类器中缺失的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13459935/

相关文章:

java - 如何将数据从 Java 传递到 FXML?

java - 使用 Eclipse 开发 Web 应用程序

python - scikit-learn GMM 产生正对数概率

machine-learning - 用于命名实体识别的 NLTK

machine-learning - 使用 mcl 可以使用哪些参数?

java - 无法写入文件 - 为什么?

java - gradle 5 - windows java.io.IOException : CreateProcess error=206, 文件名太长

tensorflow - Swift 中 Vision/CoreML 对象识别器的精度

data-mining - 在 Rapidminer 中,一旦我导入数据集,我该如何更改列的类型?