8

我正在寻找一种简单的方法来检测一段简短的文本摘录,几句话,是否是英语。在我看来,这个问题比尝试检测任意语言要容易得多。有没有什么软件可以做到这一点?我正在用 python 编写,并且更喜欢 python 库,但其他东西也可以。我试过谷歌,但后来意识到 TOS 不允许自动查询。

4

5 回答 5

11

我阅读了一种使用Trigrams检测英语的方法

您可以查看文本,并尝试检测单词中最常用的三元组。如果最常用的与英语单词中最常用的匹配,则文本可能是用英文写的

尝试查看这个 ruby​​ 项目:

https://github.com/feedbackmine/language_detector

于 2011-01-05T14:28:37.130 回答
4

编辑:这在这种情况下不起作用,因为 OP 正在批量处理违反 Google 服务条款的文本。

使用谷歌翻译语言检测 API。文档中的 Python 示例:

url = ('https://ajax.googleapis.com/ajax/services/language/detect?' +
       'v=1.0&q=Hola,%20mi%20amigo!&key=INSERT-YOUR-KEY&userip=INSERT-USER-IP')
request = urllib2.Request(url, None, {'Referer': /* Enter the URL of your site here */})
response = urllib2.urlopen(request)
results = simplejson.load(response)
if results['responseData']['language'] == 'en':
    print 'English detected'
于 2011-01-05T14:26:25.883 回答
1

虽然不如谷歌自己的好,但我使用 Apache Nutch LanguageIdentifier 获得了很好的结果,它带有自己的预训练 ngram 模型。我在多种语言的大型(50GB pdf,主要是文本)真实世界数据语料库中取得了相当不错的结果。

它是用 Java 编写的,但如果你想用 Python 重新实现它,我相信你可以从中重新读取 ngram 配置文件。

于 2011-01-05T17:12:10.890 回答
1

Google Translate API v2 允许自动查询,但它需要使用您可以在Google API 控制台上免费获得的 API 密钥。

要检测文本是否为英语,您可以使用我对Pythondetect_language_v2()问题的回答中的函数(使用该 API) - 我可以检测 unicode 字符串语言代码吗?:

 if all(lang == 'en' for lang in detect_language_v2(['some text', 'more text'])):
    # all text fragments are in English
于 2011-04-12T08:38:14.430 回答
0

我最近为此写了一个解决方案。我的解决方案不是万无一失的,我认为它对于大量文本在计算上是不可行的,但在我看来,它适用于小句子。

假设您有两个文本字符串:

  1. “让我们先说谢谢”
  2. “UNGHSYINDJFHAKJSNFNDKUAJUD”

然后目标是确定 1. 可能是英语,而 2. 不是。直观地说,我的大脑决定这一点的方式是寻找句子中英语单词的单词边界(LET、ME、BEGIN 等)。但这在计算上并不简单,因为存在重叠的单词(BE、GIN、BEGIN、SAY、SAYING、THANK、THANKS 等)。

我的方法执行以下操作:

  1. { known English words }取和的交点{ all substrings of the text of all lengths }
  2. 构造一个顶点图,其位置是句子中单词的起始索引,有向边指向单词结尾后字母的起始位置。例如,(0)将是L,所以“LET”可以表示为(0) -> (3),其中(3)M“LET ME”。
  3. n找到0 到 0 之间len(text)存在从索引 0 到索引 的简单有向路径的最大整数n
  4. 将该数字除以n文本的长度,粗略了解文本中有多少百分比是连续的英文单词。

请注意,我的代码假定单词之间没有空格。如果您已经有空格,那么我的方法很愚蠢,因为我的解决方案的核心是弄清楚空格应该在哪里。(如果您正在阅读本文并且有空格,那么您可能正在尝试解决更复杂的问题。)。此外,要使我的代码正常工作,您需要一个英文单词表文件。我从这里得到了一个,但是你可以使用任何这样的文件,我想通过这种方式,这种技术也可以扩展到其他语言。

这是代码:

from collections import defaultdict

# This function tests what percent of the string seems to me to be maybe
# English-language
# We use an English words list from here: 
# https://github.com/first20hours/google-10000-english
def englishness(maybeplaintext):
    maybeplaintext = maybeplaintext.lower()
    f = open('words.txt', 'r')
    words = f.read()
    f.close()
    words = words.lower().split("\n")
    letters = [c for c in maybeplaintext]
    # Now let's iterate over letters and look for some English!
    wordGraph = defaultdict(list)
    lt = len(maybeplaintext)
    for start in range(0, lt):
        st = lt - start
        if st > 1:
            for length in range(2, st):
                end = start + length
                possibleWord = maybeplaintext[start:end]
                if possibleWord in words:
                    if not start in wordGraph:
                        wordGraph[start] = []
                    wordGraph[start].append(end)
    # Ok, now we have a big graph of words.
    # What is the shortest path from the first letter to the last letter,
    # moving exclusively through the English language?
    # Does any such path exist?
    englishness = 0
    values = set([a for sublist in list(wordGraph.values()) for a in sublist])
    numberVertices = len(set(wordGraph.keys()).union(values))
    for i in range(2, lt):
        if isReachable(numberVertices, wordGraph, i):
            englishness = i
    return englishness/lt
    
# Here I use my modified version of the technique from:
# https://www.geeksforgeeks.org/
#   find-if-there-is-a-path-between-two-vertices-in-a-given-graph/
def isReachable(numberVertices, wordGraph, end):
    visited = [0]
    queue = [0]
    while queue:
        n = queue.pop(0)
        if n == end or n > end:
            return True
        for i in wordGraph[n]:
            if not i in visited:
                queue.append(i)
                visited.append(i)
    return False

这是I/O我给出的初始示例:

In [5]: englishness('LETMEBEGINBYSAYINGTHANKS')
Out[5]: 0.9583333333333334

In [6]: englishness('UNGHSYINDJFHAKJSNFNDKUAJUD')
Out[6]: 0.07692307692307693

所以大致来说,我 96% 确定那LETMEBEGINBYSAYINGTHANKS是英语,8% 确定那UNGHSYINDJFHAKJSNFNDKUAJUD是英语。这听起来是对的!

要将其扩展到更大的文本,我的建议是对随机短子字符串进行二次抽样并检查它们的“英语”。希望这可以帮助!

于 2018-02-17T16:46:25.060 回答