22

我有一套两种语言的文件:英语和德语。这些文档没有可用的元信息,程序只能查看内容。基于此,程序必须决定文档是用两种语言中的哪一种编写的。

对于这个问题,有没有可以在几个小时内实现的“标准”算法?或者,一个可以做到这一点的免费 .NET 库或工具包?我知道LingPipe,但它是

  1. 爪哇
  2. “半商业”使用不是免费的

这个问题似乎出奇的难。我检查了Google AJAX 语言 API(我首先通过搜索这个站点找到了它),但它非常糟糕。对于我指出的六个德语网页,只有一个猜测是正确的。其他猜测是瑞典语、英语、丹麦语和法语……

我想出的一个简单方法是使用停用词列表。我的应用程序已经使用这样的德语文档列表,以便使用 Lucene.Net 分析它们。如果我的应用程序扫描文档以查找任何一种语言中出现的停用词,那么出现次数较多的将获胜。可以肯定的是,这是一种非常幼稚的方法,但它可能已经足够好了。不幸的是,我没有时间成为自然语言处理方面的专家,尽管这是一个有趣的话题。

4

11 回答 11

6

使用停用词列表的问题是稳健性之一。停用词列表基本上是一组规则,每个单词一个规则。与统计方法相比,基于规则的方法对看不见的数据的鲁棒性往往较低。您将遇到的一些问题是包含相同数量的每种语言的停用词的文档、没有停用词的文档、具有来自错误语言的停用词的文档等。基于规则的方法无法执行其规则不做的任何事情t 指定。

一种不需要您自己实现朴素贝叶斯或任何其他复杂的数学或机器学习算法的方法是计算字符二元组和三元组(取决于您是否有大量或少量数据开始——二元组将使用较少的训练数据)。对少数已知源语言的文档(越多越好)进行计数,然后根据计数为每种语言构建一个有序列表。例如,英语将“th”作为最常见的二元组。拿着您的有序列表,计算您希望分类的文档中的二元组并将它们按顺序排列。然后遍历每一个并将其在排序的未知文档列表中的位置与其在每个训练列表中的排名进行比较。为每种语言给每个二元组打分

1 / ABS(RankInUnknown - RankInLanguage + 1).

无论哪种语言最终得分最高,都是赢家。它很简单,不需要大量编码,也不需要大量训练数据。更好的是,您可以继续向其中添加数据,并且它会有所改善。此外,您不必手动创建停用词列表,并且不会因为文档中没有停用词而失败。

它仍然会被包含相等对称双元计数的文档混淆。如果您可以获得足够的训练数据,使用三元组会降低这种可能性。但是使用三元组意味着您还需要更长的未知文档。非常短的文档可能需要您减少到单个字符(unigram)计数。

所有这一切都说,你会有错误。没有灵丹妙药。组合方法并选择能够最大限度地提高您对每种方法的信心的语言可能是最明智的做法。

于 2009-09-07T00:29:18.203 回答
6

尝试测量文本中每个字母的出现次数。对于英语和德语文本,计算频率,也许还有它们的分布。获得这些数据后,您可能会推断出您的文本的频率分布属于哪种语言。

您应该使用贝叶斯推理来确定最接近的语言(具有一定的错误概率),或者,对于此类任务,也许还有其他统计方法。

于 2009-09-05T15:13:47.437 回答
5

英语和德语使用相同的字母集,除了 ä、ö、ü 和 ß (eszett)。您可以查找这些字母以确定语言。

您还可以查看 Grefenstette 的此文本(比较两种语言识别方案)。它着眼于字母三元组和短词。德语 en_、er_、_de 的常用三元组。英语 the_, he_, the... 的常用三元组

还有 Bob Carpenter 的LingPipe 如何执行语言 ID?

于 2009-09-05T21:49:02.790 回答
3

我相信标准程序是使用测试数据(即使用语料库)来衡量提议算法的质量。定义您希望算法实现的正确分析百分比,然后在您手动分类的许多文档上运行它。

至于具体算法:使用停用词列表听起来不错。据报道,另一种可行的方法是使用贝叶斯过滤器,例如SpamBayes。与其将其训练成火腿和垃圾邮件,不如将其训练成英语和德语。使用您的语料库的一部分,通过 spambayes 运行它,然后在完整数据上对其进行测试。

于 2009-09-05T14:59:11.250 回答
3

从概念上讲,语言检测并不是很困难。请查看我对相关问题的回复以及对同一问题的其他回复。

如果你想尝试自己写,你应该可以在半天之内写出一个朴素的检测器。我们在工作中使用了类似于以下算法的东西,并且效果出奇的好。另请阅读我链接的帖子中的 python 实现教程。

步骤

  1. 为两种语言获取两个语料库并提取字符级二元组、三元组和空格分隔的标记(单词)。跟踪他们的频率。此步骤为这两种语言构建您的“语言模型”。

  2. 给定一段文本,识别每个语料库的 char bigrams、trigrams 和空格分隔的标记及其对应的“相对频率”。如果您的模型中缺少特定的“特征”(char bigram/trigram 或 token),则将其“原始计数”视为 1 并使用它来计算其“相对频率”。

  3. 特定语言的相对频率的乘积给出了该语言的“分数”。这是句子属于该语言的概率的非常简单的近似。

  4. 得分较高的语言获胜。

注意 1:对于我们的语言模型中没有出现的特征,我们将“原始计数”视为 1。这是因为,实际上,该特征的价值非常小,但由于我们的语料库有限,我们可能还没有遇到它。如果您将其计数为零,那么您的整个产品也将为零。为了避免这种情况,我们假设它在我们的语料库中出现为 1。这称为加一平滑。还有其他高级平滑技术

注意 2:由于您将乘以大量分数,因此您可以轻松地运行到零。为避免这种情况,您可以在对数空间中工作并使用此等式计算您的分数。

                a X b =  exp(log(a)+log(b))

注 3:我描述的算法是“朴素贝叶斯算法”的“非常朴素”版本。

于 2010-04-03T03:38:00.197 回答
3

如果您想锻炼自己的编程能力并尝试自己解决问题,我鼓励您这样做;但是,如果您想使用它,轮子就存在。

Windows 7 内置了此功能。一个名为“扩展语言服务”(ELS) 的组件能够检测脚本和自然语言,并且它在任何 Windows 7 或 Windows Server 2008 机器上的包装盒中。取决于您是否有任何此类机器可用以及您说“免费”时的意思,这将为您完成。无论如何,这是 Google 或此处提到的其他供应商的替代品。

http://msdn.microsoft.com/en-us/library/dd317700(v=VS.85).aspx

如果你想从 .NET 访问它,这里有一些信息:

http://windowsteamblog.com/blogs/developers/archive/2009/05/18/windows-7-managed-code-apis.aspx

希望有帮助。

于 2010-04-03T04:37:05.393 回答
2

例如,这两种语言的停用词方法很快,并且可以通过对其他语言中没有出现的德语“das”和英语中的“the”进行大量加权来更快。“专有词”的使用也将有助于将这种方法稳健地扩展到更大的语言组。

于 2009-09-05T14:59:08.537 回答
1

您可以使用 Google 语言检测 API。

这是一个使用它的小程序:

baseUrl = "http://ajax.googleapis.com/ajax/services/language/detect"

def detect(text):
    import json,urllib
    """Returns the W3C language code of a natural language"""

    params = urllib.urlencode({'v': '1.0' , "q":text[0:3000]}) # only use first 3000 characters                    
    resp = json.load(urllib.urlopen(baseUrl + "?" + params))
    try:
        retText = resp['responseData']['language']
    except:
        raise
    return retText


def test():
    print "Type some text to detect its language:"
    while True:
        text = raw_input('#>  ')
        retText = detect(text)
        print retText


if __name__=='__main__':
    import sys
    try:
        test()
    except KeyboardInterrupt:
        print "\n"
        sys.exit(0)

其他有用的参考资料:

Google 宣布 API(和演示):http: //googleblog.blogspot.com/2008/03/new-google-ajax-language-api-tools-for.html

Python 包装器: http ://code.activestate.com/recipes/576890-python-wrapper-for-google-ajax-language-api/

另一个python脚本: http ://www.halotis.com/2009/09/15/google-translate-api-python-script/

RFC 1766 定义了 W3C 语言

从以下网址获取当前语言代码: http ://www.iana.org/assignments/language-subtag-registry

于 2010-04-02T05:29:31.463 回答
1

如果您只有两种语言(英语和德语)可供选择,问题不是容易几个数量级吗?在这种情况下,您的停用词列表方法可能就足够了。

显然,如果您在列表中添加了更多语言,则需要考虑重写。

于 2009-09-05T14:55:24.027 回答
1

首先,您应该对当前解决方案进行测试,看看它是否达到了您想要的准确度。在您的特定领域取得成功比遵循标准程序更重要。

如果您的方法需要改进,请尝试根据大量英语和德语语料库中的稀有度来衡量您的停用词。或者您可以使用更复杂的技术,例如训练马尔可夫模型贝叶斯分类器。您可以扩展任何算法以查看更高阶的n-gram(例如,两个或三个单词序列)或文本中的其他特征。

于 2009-09-05T15:22:59.697 回答
0

你试过Apache Tika吗?它可以确定给定文本的语言:

http://www.dovetailsoftware.com/blogs/kmiller/archive/2010/07/02/using-the-tika-java-library-in-your-net-application-with-ikvm

我对 .Net 没有经验,但该链接可能会有所帮助。如果您可以在您的环境中执行 jar,请尝试以下操作:

 java -jar tika-app-1.0.jar -l http://www.admin.ch/

输出:

de

希望有帮助。

于 2012-03-20T09:30:53.587 回答