Java 朴素贝叶斯分类器中缺失属性的处理
我正在编写一个朴素贝叶斯分类器,用于根据WiFi信号强度执行室内定位。到目前为止,它运行良好,但我对缺少的功能有一些疑问。这种情况经常发生,因为我使用WiFi信号,而WiFi接入点并非无处不在 问题1:假设我有两个类,Apple和Banana,我想将测试实例T1分类如下 我完全理解朴素贝叶斯分类器的工作原理。下面是我在分类器上使用的公式。我使用统一的先验概率P(C=C),所以我在实现中省略了它 现在,当我计算等式的右侧,并循环所有类条件特征概率时,我应该使用哪一组特征?测试实例T1使用特性1、3和4,但这两个类没有所有这些特性。因此,当我执行循环来计算概率积时,我看到了几个关于我循环的选项:Java 朴素贝叶斯分类器中缺失属性的处理,java,machine-learning,data-mining,bayesian,classification,Java,Machine Learning,Data Mining,Bayesian,Classification,我正在编写一个朴素贝叶斯分类器,用于根据WiFi信号强度执行室内定位。到目前为止,它运行良好,但我对缺少的功能有一些疑问。这种情况经常发生,因为我使用WiFi信号,而WiFi接入点并非无处不在 问题1:假设我有两个类,Apple和Banana,我想将测试实例T1分类如下 我完全理解朴素贝叶斯分类器的工作原理。下面是我在分类器上使用的公式。我使用统一的先验概率P(C=C),所以我在实现中省略了它 现在,当我计算等式的右侧,并循环所有类条件特征概率时,我应该使用哪一组特征?测试实例T1使用特性1
Double bestLogProbability=-100000;
ClassLabel bestClassLabel=null;
用于(类标签:所有类标签)
{
双对数概率和=0.0;
用于(功能:所有功能)
{
Double logProbability=getLogProbability(类标签、特征);
if(对数概率!=null)
{
对数概率总和+=对数概率;
}
}
if(最佳对数概率<对数概率)
{
bestLogProbability=logProbabilitySum;
bestClassLabel=classLabel;
}
}
问题是,如果没有一个类具有测试实例的特性(示例中的特性5),那么logProbabilitySum将保持0.0,导致bestLogProbability为0.0,或者线性概率为1.0,这显然是错误的。处理这个问题的更好方法是什么?对于朴素贝叶斯分类器,等式的右侧应该迭代所有属性。如果您有稀疏填充的属性,通常的处理方法是使用概率的m估计值,该估计值使用等效样本量来计算您的概率。当训练数据缺少属性值时,这将防止类条件概率变为零。在网上搜索上面的两个粗体词,你会发现许多关于m估计公式的描述。汤姆·米切尔(Tom Mitchell)是一本描述这一点的好参考书。基本公式是 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,它在训练数据中没有属性,结果将是训练数据中最常出现的类。这是有道理的,因为培训数据中没有相关信息,您可以根据这些信息做出更好的决定。我很想简单地忽略培训时所有课程中未发现的任何功能。如果您选择不这样做,您实际上是在对数据产生幻觉,然后将其与分类步骤中真正存在的数据同等对待。因此,我对问题1的简单回答是根据功能3做出决定(你只是没有足够的信息来做其他事情)。这是@bogatron提到的m估计的一部分 对于缺少某些功能的培训课程,有一个更复杂的答案,但这需要做更多的工作。m-估计实际上是给定训练数据的p_i(在你的例子中是mu_i,sigma_i)上后验分布的点估计,它由p_i上的先验(分数n_i/n)和似然函数p(数据| p_i)组成。在没有观察到数据点的情况下,基本上可以恢复到先前的特性预测分布 现在,你如何估计之前的价格?如果问题中的类数少,相对于缺少某个特征值的数目,则可以从具有数据的类中推断先验的参数,并考虑类缺失数据的预测分布,仅仅是这种先验数据。(对于有数据的类,您的预测分布是后验分布)。对于您来说,有用的提示是,因为您似乎假设您的数据是正态分布的(或至少以其平均值和标准偏差为特征),为了求共轭,平均数上的先验也应该是正常的。我可能希望避免对先验进行推断
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;
}
}