1

在尝试对一些文本内容进行分类时,我经常会得到类似这样的结果:

{"category":"SOME_CATEGORY","confidence":NaN}

除了它不是有效的 JSON(Nan未经授权)之外,我不明白发生了什么。

如有必要,我可以通过在计算期间附加调试器来提供中间值。

4

1 回答 1

1

嗯,所以我的想法是问题出在NBAlgorithm.predict方法上,它的发生原因如下。如果您查看PreparedData使用 Spark MLLib 的HashingTF类创建的频率向量。该向量的默认大小为 1,048,576,并且每个标记都映射到与其哈希值对应的索引,该哈希值以特征向量的大小为模。鉴于所提供的信息,我最好的猜测是,在朴素贝叶斯训练中,一些结果向量索引在所有类中产生了 0 概率估计(这将解释获取日志时的不确定值)。

鉴于此,我只是在 2.3 版本中添加了一个参数numFeaturesPreparatorParams控制特征向量的大小(将默认值设置为 15000,尽管您可以在engine.json文件中随意修改),并测试了一些查询。让我知道这是否为您解决了问题,否则,请提供有关您的数据以及产生这些值的查询的任何额外信息。

- - 编辑 - -

好的,所以这是我提出的一个避免这些NaN值的小技巧。

特别是,您可以从文档中看到后验类概率的向量(给定文档中观察到的单词)由向量表示:

等式 1

这意味着在给定从文档中获得的字数的情况下,观察属于 k 类的后验概率可以写成:

等式 2

现在,我们有明显的相等性:

等式 3

这尤其意味着我们可以将后一个概率写为:

等式 4

那么为什么这一切都很重要呢?好吧,我们担心概率计算中的 c_k 值是具有大绝对值的负数的情况。后者将其中最大的一个约束为 1,其余的一些值小于 1。也就是说,如果不失一般性,我们假设类 1 与绝对值最小的 c_1 相关联,那么我们有平等:

方程

我认为这些方程的威力最好用一个代码示例来说明:

import scala.math._

val probs = Seq(-13452, -13255, -13345)
// Results in a sequence of 0.0 values.
probs
    .map(k => exp(k)) 
// Same transformation using the latter equalities.
// Note that this yields non-zero values.
probs
    .map(k => (abs(probs.max) - abs(probs(k)))*log10(E))
    .map(x => pow(10, x))

将尽快实施此捕获,谢谢您的提醒。

于 2015-09-10T19:13:45.253 回答