【问题标题】:How to compute letter frequency similarity?如何计算字母频率相似度?
【发布时间】:2013-03-20 13:41:37
【问题描述】:

鉴于此数据(两种语言的相对字母频率):

spanish => 'e' => 13.72, 'a' => 11.72, 'o' => 8.44, 's' => 7.20, 'n' => 6.83,
english => 'e' => 12.60, 't' => 9.37, 'a' => 8.34, 'o' => 7.70, 'n' => 6.80,

然后计算字符串“这是一个测试”的字母频率给我:

"t"=>21.43, "s"=>14.29, "i"=>7.14, "r"=>7.14, "y"=>7.14, "'"=>7.14, "h"=>7.14, "e"=>7.14, "l"=>7.14

那么,将给定的字符串字母频率与语言匹配(并尝试检测语言)的好方法是什么?我已经看到(并测试过)一些使用 levenshtein distance 的示例,在您添加更多语言之前,它似乎可以正常工作。

"this is a test" gives (shortest distance:) [:english, 13] ...
"esto es una prueba" gives (shortest distance:) [:spanish, 13] ...

【问题讨论】:

  • 我见过的例子并不关心字母频率的实际百分比,它们只是将所有字母减少到一个字符串中,所以“英文字母频率”将是:“eaosn” , 和 "西班牙字母频率: "etaon"。然后他们计算给定字符串的字母频率,并做同样的事情,然后计算这些字符串之间的 levenshtein 距离。

标签: text nlp levenshtein-distance letter


【解决方案1】:

您是否考虑过使用cosine similarity 来确定两个向量之间的相似度?

第一个向量是从测试字符串中提取的字母频率(待分类),第二个向量是针对特定语言的。

您目前正在提取单字母频率(unigrams)。我建议提取更高阶的n-grams,例如二元组或三元组(如果你有足够的训练数据,甚至更大)。例如,对于二元组,您将计算“aa”、“ab”、“ac”...“zz”的频率,这将允许您提取比仅考虑单个字符频率的更多信息。

但要小心,因为当您使用高阶 n-gram 时需要更多训练数据,否则您将获得许多以前从未见过的字符组合的 0 值。

另外,第二种可能性是使用tf-idf(词频逆文档频率)权重,而不是纯字母(词)频率。

研究

这是language identification for (very) short texts 上的一个很好的幻灯片,它使用机器学习分类器(但也有一些其他有用的信息)。

这是一篇简短的论文 A Comparison of Language Identification Approaches on Short, Query-Style Texts,您可能也会觉得有用。

【讨论】:

    【解决方案2】:

    您提供的示例均由一个简短的句子组成。统计数据表明,如果您的输入较长(例如一个段落,则唯一频率应该更容易识别。

    如果您不能依赖用户提供更长的输入,那么如果字母频率匹配,也许还要寻找语言中的常用词(例如 is、as、and、but ...)?

    【讨论】:

    • 对,我正在考虑实现首字母频率和二合字母/三合字母频率以获得更准确的结果
    【解决方案3】:

    n-graphs 肯定会对短文本有所帮助,而且帮助很大。对于任何合理长度的文本(一段?),简单的字母频率都可以很好地工作。例如,我写了一个简短的演示,您可以在http://georgeflanagin.com/free.code.php下载源代码

    这是页面上的最后一个示例。

    【讨论】: