【问题标题】:How do I tell what language is a plain-text file written in? [closed]如何判断纯文本文件是用什么语言编写的? [关闭]
【发布时间】:2010-02-24 12:51:43
【问题描述】:

假设我们有一个包含以下内容的文本文件: “Je suis un beau homme ...”

另一个: “我是个勇敢的人”

第三个带有德语文本: “Guten morgen. Wie geht 的?”

我们如何编写一个函数来告诉我们:以这样的概率,第一个文本 文件是英文的,第二个我们有法语等?

欢迎提供指向书籍/开箱即用解决方案的链接。我用 Java 编写,但如果需要,我可以学习 Python。

我的cmets

  1. 我需要添加一条小注释。文本可能包含不同语言的短语,作为整体的一部分或作为错误的结果。在经典文学中我们有很多例子,因为贵族成员会说多种语言。因此,概率更好地描述了这种情况,因为文本的大部分内容是用一种语言编写的,而其他部分可能是用另一种语言编写的。
  2. Google API - 互联网连接。我不想使用远程功能/服务,因为我需要自己做或使用可下载的库。我想对该主题进行研究。

【问题讨论】:

  • @EugeneP:法语会更像“Je suis un bel homme ...”;)但语言检测器不太可能发现这个错误(或至少非常不常见的用法)。
  • @WizardOfOdds Je suis un bonhomme alors, merci, quand meme ;)
  • 另外,希望你已经检查过这个:stackoverflow.com/questions/1383503/…

标签: java nlp


【解决方案1】:

有一个名为 JLangDetect 的包似乎完全符合您的要求:

langof("un texte en français") = fr : OK
langof("a text in english") = en : OK
langof("un texto en español") = es : OK
langof("un texte un peu plus long en français") = fr : OK
langof("a text a little longer in english") = en : OK
langof("a little longer text in english") = en : OK
langof("un texto un poco mas largo en español") = es : OK
langof("J'aime les bisounours !") = fr : OK
langof("Bienvenue à Montmartre !") = fr : OK
langof("Welcome to London !") = en : OK
// ...

编辑:正如 Kevin 指出的那样,Nutch project 包提供的 org.apache.nutch.analysis.lang 有类似的功能。

【讨论】:

  • 为什么没有德语例子?
  • @Chris 好吧,问得好。我只知道一个词,看看我能不能写对。
  • 我不知道,但德语被列为支持的语言
  • @EugeneP:试试Dies ist ein kurzer deutscher Text
  • 您好!只是为了完整性,“longer”在西班牙语中拼写为“largo”:)
【解决方案2】:

【讨论】:

【解决方案3】:

对于较大的文本语料库,您通常使用字母、二合字母甚至三字母的分布,并与您想要检测的语言的已知分布进行比较。

但是,一个句子很可能太短而无法产生任何有用的统计指标。那么,用字典匹配单个单词可能会更幸运。

【讨论】:

    【解决方案4】:

    NGramJ 似乎更新了一点:

    http://ngramj.sourceforge.net/

    它还具有面向字符和面向字节的配置文件,因此它也应该能够识别字符集。

    对于多种语言的文档,您需要识别字符集(ICU4J 有一个 CharsetDetector 可以做到这一点),然后将文本拆分为合理的内容,例如多个换行符,或者如果文本被标记则为段落.

    【讨论】:

      【解决方案5】:

      试试 Nutch 的Language Identifier。它使用 n-gram 语言配置文件进行训练,可用语言配置文件与输入文本匹配。有趣的是,如果需要,您可以添加更多语言。

      【讨论】:

      • 我们使用 nutch 的语言标识符,效果非常好。它是二元模型的标准实现,适用于共享字符集的语言。
      【解决方案6】:

      查找马尔可夫链。

      基本上,您将需要您想要识别的语言的具有统计意义的样本。当你得到一个新文件时,看看特定音节或音素的频率是多少,并比较预先计算的样本。选择最接近的。

      【讨论】:

        【解决方案7】:

        虽然比您正在寻找的解决方案更复杂,但您可以使用 Vowpal Wabbit 并使用来自不同语言的句子对其进行训练。

        理论上,您可以为文档中的每个句子恢复一种语言。

        http://hunch.net/~vw/

        (不要被项目副标题中的“在线”所迷惑 - 这只是用于学习的数学语言,无需记忆完整的学习材料)

        【讨论】:

          【解决方案8】:

          如果您对可以执行语言检测的机制感兴趣,我推荐您参考以下article(基于python),它使用(非常)幼稚的方法,但特别是对这个问题的一个很好的介绍,并且机器学习(只是一个大词)。

          对于 java 实现,其他海报所建议的 JLangDetect 和 Nutch 非常好。另请查看LingpipeJTCLNGramJ


          对于同一页面中有多种语言的问题,您可以使用句子边界检测器将页面分割成句子,然后尝试识别每个句子的语言。假设一个句子只包含一种(主要)语言,您仍然应该通过上述任何实现获得良好的结果。

          注意:理论上,句子边界检测器 (SBD) 是特定于语言的(鸡蛋问题,因为您需要一个用于另一个)。但是对于主要使用句点(除了感叹号等)来分隔句子的基于拉丁文字的语言(英语、法语、德语等),即使您使用专为英语设计的 SBD,您也会得到可接受的结果。我写了一个基于规则的英语 SBD,它非常适合法语文本。有关实现,请查看OpenNLP

          使用 SBD 的另一种选择是使用 10 个标记(空格分隔)的滑动窗口来创建 伪句 (PS) 并尝试识别语言更改的边界.这样做的缺点是,如果您的整个文档有 n 个标记,您将对每个长度为 10 个标记的字符串执行大约 n-10 次分类操作。在另一种方法中,如果平均句子有 10 个标记,那么您将执行大约 n/10 次分类操作。如果文档中有 n = 1000 个单词,则您将 990 次操作与 100 次操作进行比较:一个数量级的差异。


          如果您有简短的短语(少于 20 个字符),根据我的经验,语言检测的准确性很差。特别是在专有名词以及跨语言相同的名词(如“巧克力”)的情况下。例如。如果“New York”出现在法语句子中,它是英语单词还是法语单词?

          【讨论】:

            【解决方案9】:

            如果您有互联网连接,那么 Google Language API 将是您的最佳选择。

            // This example request includes an optional API key which you will need to
            // remove or replace with your own key.
            // Read more about why it's useful to have an API key.
            // The request also includes the userip parameter which provides the end
            // user's IP address. Doing so will help distinguish this legitimate
            // server-side traffic from traffic which doesn't come from an end-user.
            URL url = new URL(
                "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&"
                + "q=Paris%20Hilton&key=INSERT-YOUR-KEY&userip=USERS-IP-ADDRESS");
            URLConnection connection = url.openConnection();
            connection.addRequestProperty("Referer", /* Enter the URL of your site here */);
            
            String line;
            StringBuilder builder = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            while((line = reader.readLine()) != null) {
             builder.append(line);
            }
            
            JSONObject json = new JSONObject(builder.toString());
            // now have some fun with the results...
            

            如果没有,还有其他方法。

            【讨论】:

              【解决方案10】:

              bigram 模型表现良好,易于编写、易于训练,并且只需要少量文本即可进行检测。 nutch 语言标识符是我们发现并使用瘦包装器的 java 实现。

              我们在混合 CJK 和英文文本的二元模型上遇到了问题(即,一条推文主要是日语,但只有一个英文单词)。从数学的角度来看,这很明显(日语有更多的字符,所以任何给定对的概率都很低)。我认为你可以通过一些更复杂的对数线性比较来解决这个问题,但我作弊并使用了一个基于某些语言特有的字符集的简单过滤器(即,如果它只包含统一的韩语,那么它就是中文,如果它包含一些日文假名,统一汉文,则为日文)。

              【讨论】:

                猜你喜欢
                • 2015-12-14
                • 1970-01-01
                • 2012-08-17
                • 1970-01-01
                • 1970-01-01
                • 2012-04-23
                • 2018-06-30
                • 1970-01-01
                • 2011-06-06
                相关资源
                最近更新 更多