我在Spark中关于词语分类有一个问题。我正在开发一个简单的分类模型,输入是一个单词(仅一个单词),模型预测该词所指代的虚构宇宙中人物的种族。例如,Gimli -> 矮人,Legolas -> 精灵。
我的问题在于如何处理这些词。我知道Spark包含两种特征向量化方法,tf-idf和word2vec。然而,我对它们的理解有困难,不知道该使用哪一种。
能有人向我解释这些方法并指导我完成这个过程吗?更重要的是,我想知道这两种方法中哪一种最适合这种情况。
谢谢
回答:
首先我们应该明确,正确的方法将取决于数据。*
这项任务被称为语言检测或语言识别。即使对于整句话或整页,来自整个单词的向量并不是正确的处理方法。(它只适用于在训练中实际遇到过的名字,就像一个列表,没有真正的预测。)相反,你需要基于字符的n-gram模型。例如,在二元模型中:
“Gimli” –> “_G Gi im ml li i_”
不幸的是,你不能直接使用pyspark.ml.feature.NGram来做这件事,因为它假设一个gram是一个单词,而不是一个字符。
该怎么办呢?
你必须首先找到或编写一个函数来将字符转换为字符 n-gram,并将其应用于原始名称和进入系统的查询。(如果名字中有空格,也将其视为一个字符。)
然后,在Spark术语中,这些字符n-gram就是你的“词”,包含所有这些的字符串(例如“_G Gi im ml li i_”)就是你的“文档”。
(如果你愿意,你现在可以使用NGram:将单词分割成['G i m l i']
,然后使用n=2的NGram应该相当于分割成['_G', 'Gi', 'im'...]
。)
一旦你以这种方式构建它,它将成为标准文档分类问题的一种(实际上在严格的Spark术语中是“回归”),Spark为此提供了几种选择。需要注意的主要一点是顺序很重要,不要使用将它视为词袋的方法。因此,尽管所有找到的Spark分类示例都使用TF-IDF进行向量化(在你的情况下它不会完全失败),但它将是次优的,因为我假设每个字符n-gram的顺序/上下文实际上是重要的。
为了优化准确性,可以在字母表、特殊字符、大小写敏感性、词干提取等方面进行可能的改进。这取决于你的数据 – 见下文。(如果你能发布整个数据集的链接会很有趣。)
: * 关于数据及其假设:
字符n-gram方法在识别地球上实际的人类语言方面表现良好。即使对于人类语言,对于像名字这样的文本类别也有特殊情况,例如可以使用中文字符,或者像海地语或塔加洛语这样的语言,其中许多名字只是法语或西班牙语,或者波斯语或乌尔都语,其中它们只是阿拉伯语 – 发音不同但拼写相同。)
我们知道主要人类语言的单词的基本问题和技术,但就我们所知,你的数据中的名字:- 可能是随机或混合字母表- 包含通常更可能在URL中看到的特殊字符如’/’或’_’- 是数字
同样有趣的是它们如何与群体成员身份相关联的问题。例如,名字可能是从字母字符中随机生成的,或者只是一个英语名字列表,或者使用任何其他方法生成,然后随机分配给A类或B类。在这种情况下,不可能预测尚未见过的名字是否属于A或B。也可能是A类的人以他们出生的那天命名,而B类的人以他们受孕的那天命名。在这种情况下,这是可能的,但没有更多信息是不行的。
在另一种情况下,同样使用相同的生成器,但名字根据以下内容分配给A或B:- 长度即字符/字节/元音/大写字母的数量(<或>=某个截止值)- 长度即…的数量(偶数或奇数)在这些情况下,必须提取一组完全不同的特征。
在另一种情况下,B类名字总是重复的块,如’johnjohn’。在这种情况下,字符n-gram频率可以比随机猜测更好地工作,但不是最佳方法。
所以你总是需要对问题有一些直觉。对于一个人造世界,我们很难做出假设,从你给出的两个例子来看,我们可能会假设这些名字有点像英语。最后,你必须尝试不同的方法和特征(理想情况下,你选择的分类器会简单地忽略无用的信号)。至少在现实世界中,像词数、字符数和字节数这样的特征实际上对这个问题是有用的 – 它们可以增强字符n-gram方法。