如何判断写入的纯文本文件是什么语言?

时间:2010-02-24 12:51:43

标签: java nlp

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

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

第三个带有德语文本: “Guten morgen。Wie geht's?”

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

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

我的评论

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

10 个答案:

答案 0 :(得分:19)

有一个名为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中有类似的功能。

答案 1 :(得分:5)

答案 2 :(得分:5)

对于较大的文本corpi,您通常使用字母,有向图甚至三字母的分布,并与您想要检测的语言的已知分布进行比较。

然而,单句很可能太短而无法产生任何有用的统计指标。然后,您可能会更幸运地将单个单词与字典匹配。

答案 3 :(得分:4)

NGramJ似乎更新一些:

http://ngramj.sourceforge.net/

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

对于多种语言的文档,您需要识别字符集(ICU4J有一个CharsetDetector可以执行此操作),然后将文本拆分为合理的内容,如多个换行符或段落,如果文字已标记。

答案 4 :(得分:4)

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

答案 5 :(得分:3)

查找马尔可夫链。

基本上,您需要具有统计学意义的语言样本才能识别。当您获得新文件时,请查看特定音节或音素的频率,并比较预先计算的样本。选择最近的一个。

答案 6 :(得分:2)

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

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

http://hunch.net/~vw/

(不要被项目副标题中的“在线”所愚弄 - 这只是学习数学,而不必在记忆中有完整的学习材料)

答案 7 :(得分:2)

如果您对可以执行语言检测的机制感兴趣,我建议您使用以下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个字符),语言检测的准确性在我的经验中很差。特别是在专有名词的情况下以及在“巧克力”之类的语言中使用相同的名词。例如。如果“纽约”出现在法语句子中,它是英语单词还是法语单词?

答案 8 :(得分:0)

如果您有互联网连接,那么Google语言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...

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

答案 9 :(得分:0)

bigram模型表现良好,编写简单,训练简单,只需要少量文本进行检测。 nutch语言标识符是我们发现的一个java实现,并与一个瘦包装器一起使用。

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