如何在Java中识别文本文档的语言?

时间:2009-01-10 15:48:48

标签: java text dictionary text-processing

是否有现有的Java库可以告诉我String是否包含英语语言文本(例如我需要能够区分法语或意大利语文本 - 该函数需要为法语和意大利语返回false,并且为true对于英语)?

6 个答案:

答案 0 :(得分:10)

有各种技术,强大的方法可以结合各种技术:

  • 查看文字中 字母组的组频率(例如,3个字母组或三字母组),看看它们是否有效类似于您正在测试的语言的频率
  • 查看给定语言中的频繁单词的实例是否与文本中找到的频率相匹配(这对较长的文本更有效)
  • 文本是否包含字符,这会将其强制缩小为特定语言? (例如,如果文本中包含一个颠倒的问号,则很有可能是西班牙语)
  • 你可以“松散地解析”文本中指明特定语言的某些功能,例如:如果它包含与以下正则表达式的匹配,您可以将此作为语言为法语的强有力线索:

    \ bvous \ S + \ p {L} + EZ \ B'/ p>

为了让你开始,这里有英语,法语和意大利语的频繁三字和字数统计(从一些代码复制和粘贴 - 我将把它作为练习来解析它们):

  Locale.ENGLISH,
      "he_=38426;the=38122;nd_=20901;ed_=20519;and=18417;ing=16248;to_=15295;ng_=15281;er_=15192;at_=14219",
      "the=11209;and=6631;to=5763;of=5561;a=5487;in=3421;was=3214;his=2313;that=2311;he=2115",
  Locale.FRENCH,
      "es_=38676;de_=28820;ent=21451;nt_=21072;e_d=18764;le_=17051;ion=15803;s_d=15491;e_l=14888;la_=14260",
      "de=10726;la=5581;le=3954;" + ((char)224) + "=3930;et=3563;des=3295;les=3277;du=2667;en=2505;un=1588",
  Locale.ITALIAN,
      "re_=7275;la_=7251;to_=7208;_di=7170;_e_=7031;_co=5919;che=5876;he_=5622;no_=5546;di_=5460",
      "di=7014;e=4045;il=3313;che=3006;la=2943;a=2541;in=2434;per=2165;del=2013;un=1945",

(Trigram计数是每百万字符;字数是每百万字。'_'字符代表字边界。)

我记得,这些数字在牛津计算语言学家手册中引用,并以报纸文章样本为基础。如果你有这些语言的文本语料库,那么很容易自己得出类似的数据。

如果你想要一种非常快速和肮脏的方式来应用上述方法,请尝试:

  • 考虑文本中三个字符的每个序列(用'_'替换字边界)
  • 对于与给定语言的频繁匹配的每个三元组,将该语言的“分数”增加1(更复杂的是,您可以根据列表中的位置加权)
  • 最后,假设语言是得分最高的
  • 可选地,对常用词(组合分数)
  • 执行相同操作

显然,这可以改进,但你可能会发现这个简单的解决方案足以满足你的需求,因为你对“英语与否”基本感兴趣。

答案 1 :(得分:2)

你尝试过Apache Tika吗?它具有良好的API来检测语言,它还可以通过加载相应的配置文件来支持不同的语言。

答案 2 :(得分:1)

您可以尝试将每个单词与英语,法语或意大利语词典进行比较。请记住,虽然某些词可能出现在多个词典中。

答案 3 :(得分:1)

这是一个讨论这个概念的interesting blog post。示例在Scala中,但您应该能够将相同的一般概念应用于Java。

答案 4 :(得分:1)

如果您正在查看单个字符或单词,这是一个棘手的问题。但是,由于您正在使用整个文档,因此可能会有一些希望。不幸的是,我不知道现有的库可以做到这一点。

一般来说,每种语言都需要一个相当全面的单词列表。然后检查文档中的每个单词。如果它出现在语言词典中,请给该语言“投票”。有些单词会出现在多种语言中,有时一种语言的文档会使用另一种语言的外来词,但在看到一种语言非常清晰的趋势之前,文档不需要很长时间。

一些最好的英语单词列表是Scrabble玩家使用的单词列表。这些列表也可能存在于其他语言中。原始列表很难通过Google找到,但它们就在那里。

答案 5 :(得分:0)

这种imo没有“好”的方式。关于这个主题,所有答案都非常复杂。显而易见的部分是检查法语+意大利语中的字符,而不是英文字符,然后返回false。

但是,如果单词是法语但没有特殊字符怎么办?玩这个想法你有一个完整的权力。您可以匹配字典中的每个单词,如果发送的法语点数多于英语点数,则不是英语。这将阻止法语,意大利语和英语的常见词汇。

祝你好运。