【问题标题】:How do I identify language of a text document in Java?如何在 Java 中识别文本文档的语言?
【发布时间】:2010-09-30 16:15:19
【问题描述】:

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

【问题讨论】:

标签: java text dictionary text-processing


【解决方案1】:

您是否尝试过 Apache Tika。它有很好的API来检测语言,它还可以通过加载相应的配置文件来支持不同的语言。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      • 查看文本中n 个字母组(例如,3 个字母组或三元组)的频率,看看它们是否与您正在测试的语言的频率相似
      • 查看给定语言中的常用词实例是否与您的文本中发现的频率相匹配(这往往更适合较长的文本
      • 文本是否包含字符,这些字符会强烈地将其缩小到特定语言? (例如,如果文本包含一个倒置的问号,则很有可能是西班牙语)
      • 你能“松散地解析”文本中的某些特征,这些特征会指示一种特定的语言,例如如果它包含与以下正则表达式的匹配项,您可以将此作为语言是法语的有力线索:

        \bvous\s+\p{L}+ez\b

      为了帮助您入门,以下是英语、法语和意大利语的常用三元组和字数统计(从一些代码中复制和粘贴——我将把它作为一个练习来解析它们):

        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(更复杂的是,您可以根据列表中的位置加权)
      • 最后,假设语言是得分最高的语言
      • (可选)对常用词执行相同操作(组合分数)

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

            但是,如果单词是法语但没有特殊字符怎么办?想一想你有一个完整的句子。您可以匹配字典中的每个单词,如果句子的法语分数多于英语分数,则它不是英语。这将阻止法语、意大利语和英语的常用词。

            祝你好运。

            【讨论】:

            • “祝你好运。”对于这个问题,这是最好的,可悲的是也是最准确的建议。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-19
            • 1970-01-01
            • 1970-01-01
            • 2021-09-28
            相关资源
            最近更新 更多