Apache Spark MLLib:如何为字符串特征构建标记点?

17
我正在尝试使用Spark的MLLib构建一个朴素贝叶斯分类器,其输入为一组文档。 我想将一些内容作为特征(即作者,显式标签,隐含关键字,类别),但是查看文档后,发现LabeledPoint仅包含双精度浮点数,即它看起来像LabeledPoint[Double,List [Pair [Double,Double]]]。 相反,我从我的代码的其他部分得到的输出将是LabeledPoint [Double,List [Pair [String,Double]]]之类的东西。 我可以编写自己的转换,但这似乎很奇怪。我应该如何在MLLib中处理这个问题? 我相信答案在HashingTF类中(即散列特征),但我不理解它的工作原理,它似乎需要一些容量值,但是我的关键字和主题列表实际上没有界限(或更好地说,在开始时未知)。
1个回答

10

HashingTF利用哈希技巧将潜在的无限数量特征映射到有限长度向量中。可能存在特征冲突,但这可以通过在构造函数中选择更多特征来减小。

为了基于特征的内容和元数据(例如具有“cats”标签而不是文档中有单词“cats”)创建特征,您可以将类似“tag:cats”的内容提供给HashingTF类,以便具有单词的标记与仅有单词的标记哈希到不同的插槽中。

如果您使用HashingTF创建特征计数向量,则可以通过将任何大于零的计数设置为1来将其用于创建词袋特征。您还可以使用IDF类创建TF-IDF向量,如下所示:

val tfIdf = new IDF().fit(featureCounts).transform(featureCounts)

在您的情况下,看起来您已经计算了每个文档中单词的数量。这不适用于HashingTF类,因为它旨在为您完成计数。

这篇论文提出了一些关于为什么在语言应用中特征冲突不是太大问题的论据。其基本原因是大多数单词都不常见(由于语言的特性),并且碰撞独立于单词频率(由于哈希属性),因此很不可能将有助于模型的常见单词哈希到同一个槽中。


谢谢,只需要澄清一个问题:如果我理解正确,在HashingTF中的numFeatures基本上是用作mod值,以将特征数量限制在给定的最大值内?如果是这样,它不应该只是Double.MAX_VALUE吗?还是说想法是使用它,以便将不同的特征限制在给定范围内并限制交叉碰撞?(即将某些特征放在1..N中,将其他一些特征放在N..2N中,您将在相同类型之间发生冲突,但不会跨类型) - riffraff
是的,计算看起来像是features[hash(feature) % numFeatures] += 1。创建的向量通常用作某个模型的输入,因此使用Double.MAX_VALUE会意味着一个巨大的模型。哈希技巧的主要动机之一是减少内存占用。您当然可以按照您建议的方式创建特征,但我不确定如何评估这种方法的好处。 - mrmcgreg
当然啦,我之前在想稀疏向量,所以没考虑过数组大小。感谢你的帮助! - riffraff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接