【发布时间】:2015-09-10 10:03:00
【问题描述】:
在尝试对一些文本内容进行分类时,我经常会得到类似这样的结果:
{"category":"SOME_CATEGORY","confidence":NaN}
除了它不是有效的 JSON(Nan 未授权),我不明白发生了什么。
如有必要,我可以在计算期间通过附加调试器来提供中间值。
【问题讨论】:
标签: predictionio
在尝试对一些文本内容进行分类时,我经常会得到类似这样的结果:
{"category":"SOME_CATEGORY","confidence":NaN}
除了它不是有效的 JSON(Nan 未授权),我不明白发生了什么。
如有必要,我可以在计算期间通过附加调试器来提供中间值。
【问题讨论】:
标签: predictionio
嗯,所以我的想法是问题出在NBAlgorithm.predict 方法中,它的发生原因如下。如果您查看PreparedData,频率向量是使用 Spark MLLib 的HashingTF 类创建的。该向量的默认大小为 1,048,576,每个标记都映射到与其哈希值对应的索引,该哈希值以特征向量的大小为模。鉴于所提供的信息,我的最佳猜测是,在朴素贝叶斯训练中,一些结果向量索引在所有类中产生 0 概率估计(这可以解释获取日志时的不确定值)。
有鉴于此,我只是在 2.3 版本中将参数 numFeatures 添加到 PreparatorParams 以控制特征向量的大小(将默认值设置为 15000,尽管您可以在您的engine.json 文件),并测试了一些查询。让我知道这是否为您解决了问题,否则,请提供有关您的数据以及产生这些值的查询的任何额外信息。
---- 编辑----
好的,所以我建议使用一个小技巧来避免这些 NaN 值。
特别是从文档中可以看出,后验类概率的向量(给定文档中观察到的词)用向量表示:
这意味着在给定从文档中获得的字数的情况下,观察属于 k 类的后验概率可以写成:
现在,我们有了明显的相等性:
这意味着我们可以将后面的概率写成:
那么为什么这一切都很重要?好吧,我们担心概率计算中的 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))
将尽快实施此捕获,感谢您的提醒。
【讨论】: