为什么在文本语言识别中使用 n-gram 而不是单词?

机器算法验证 机器学习 分类 文本挖掘 自然语言
2022-01-22 20:19:50

在两个流行的语言识别库中,用于 C++ 的 Compact Language Detector 2 和用于 Java 的语言检测器,它们都使用(基于字符的)n-gram 来提取文本特征。为什么不使用词袋(单个词/字典),词袋和n-gram的优缺点是什么?

此外,n-gram 模型在文本分类中还有哪些其他用途?

哦哦哦。似乎这里有一个类似的问题: 关于使用二元组(N-gram)模型为文本文档构建特征向量

但是有人可以给出更全面的答案吗?在语言识别的情况下哪个更好?

(希望我正确理解了 n-gram 和词袋的含义,哈哈,如果不是,请帮助我。)

2个回答

我认为最详细的答案可以在 Mehryar Mohri 关于该主题的大量工作中找到。这是他关于该主题的一张演讲幻灯片的链接:https ://web.archive.org/web/20151125061427/http://www.cims.nyu.edu/~mohri/amls/lecture_3.pdf

语言检测的问题是人类语言(词)是有结构的。例如,在英语中,字母“u”跟随字母“q”是很常见的,而在音译的阿拉伯语中则不然。n-gram 通过捕获这种结构来工作。因此,某些语言中的某些字母组合比其他语言更可能出现。这是n-gram分类的基础。

另一方面,词袋依赖于通过大型词典进行搜索并基本上进行模板匹配。这里有两个主要缺点:1)每种语言都必须有一个庞大的词库文件,这将花费相对较长的时间来搜索,以及 2)如果没有词,那么词袋将失败训练集包含在测试集中。

假设您使用的是二元组 (n=2) 并且您的字母表中有 26 个字母,那么该字母表只有 26^2 = 676 个可能的二元组,其中许多永远不会出现。因此,每种语言的“配置文件”(使用语言检测器的话)需要一个非常小的数据库。另一方面,词袋分类器需要针对每种语言的完整词典,以保证可以根据给出的任何句子检测语言。

所以简而言之 - 每个语言配置文件都可以用相对较小的特征空间快速生成。有趣的是,n-gram 之所以起作用,是因为字母不是以一种语言绘制的独立同分布——这显然是一种杠杆作用。

注意:单词 n-gram 数量的一般等式是 l^n,其中 l 是字母表中的字母数。

使用字母 N-gram 代替单词有以下几个原因:

1) 给定语言所需的单词列表非常大,如果您考虑 fast、fast、fastest、fasted、fasts、fasting ……作为所有不同的单词,可能有 100,000 个。对于 80 种语言,您需要大约 80 倍的单词,占用大量空间—— 50 多兆字节。

2) 26 个字母的字母表的字母三元组数量为 26**3 或约 17,000 个,四元组 (N=4) 约 450,000 个,涵盖使用该字母表的所有语言。对于 30-100 个字符的较大字母表中的 N-gram,数字相似但稍大一些。对于汉文字母超过 4000 个的 CJK 语言,一元组 (N=1) 就足够了。对于某些 Unicode 脚本,每个脚本只有一种语言(希腊语、亚美尼亚语),因此不需要字母组合(所谓的 nil-grams N=0)

3)对于单词,当给定一个不在字典中的单词时,您根本没有任何信息,而对于字母 N-gram,您通常在该单词中至少有一些有用的字母组合。

CLD2 对大多数 Unicode 文字(字母表)使用四元组,包括拉丁文、西里尔文和阿拉伯文,对 CJK 脚本使用一元组,对于其他脚本使用 nilgrams,并且还包括数量有限的非常独特且相当常见的完整单词和单词对用于区分在统计上相似的语言困难组中,例如印度尼西亚语和马来语。字母二元组和三元组可能有助于区分少数语言(大约八种,参见https://docs.google.com/document/d/1NtErs467Ub4yklEfK0C9AYef06G_1_9NHL5dPuKIH7k/edit),但对于区分几十种语言是无用的。因此,CLD2 使用四元组,将每个字母组合与最有可能使用该组合的前三种语言相关联。这允许使用大约 1.5 MB 的表覆盖 80 种语言,以及使用大约 5MB 的表更详细地覆盖 160 种语言。