2011-01-05 56 views
8

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

+1

可能的重复的[Python - 我可以检测unicode字符串语言代码?](http://stackoverflow.com/questions/4545977/python-can-i-detect-unicode-string-language-code) – ismail 2011-01-05 14:26:53

+2

我'在这里只需要英语,而不是那个他们要求任何语言的线程。 – user449511 2011-01-05 14:34:36

+0

这对英语来说很好。 – ismail 2011-01-05 14:42:54

回答

10

我读的方法,通过使用八卦

http://en.wikipedia.org/wiki/Trigram

你可以在文本,并尝试以检测最常用的卦检测Enlgish的langauge话。如果最常用的那些英语单词中最常用的匹配,可以将文本用英文写的

尝试在这个Ruby项目看:

https://github.com/feedbackmine/language_detector

+0

Trigams +1 - 非常酷。 – 2011-01-05 14:37:04

+0

谢谢!这是一个很容易实现的想法,我可以用一小组测试文本给出一个快速测试,我必须看看它的工作效果如何! – user449511 2011-01-05 14:37:32

+0

这将需要大量的示例文本。 OP可能无法访问。 – marcog 2011-01-05 14:38:11

4

编辑:这不会在这种情况下工作,因为OP是处理散装这是对谷歌的服务条款的文字。

使用谷歌翻译language detect 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' 
+0

“Google语言检测API必须用于用户生成的语言检测,严禁自动或批量查询任何类型的查询。” 我想这就是为什么问题提供者指的是他也看到的服务条款,并且我假设他因此想要在没有任何用户输入的情况下检测语言。 – 2011-01-05 14:33:31

+0

@tomlog你可能是对的。我认为他指的是抓取GT页面。 @user,你能确认你是否正在处理用户生成的字符串吗? – marcog 2011-01-05 14:36:31

+0

我正在用我的文本批量查询他们的api,并被拒绝访问并意识到我的问题。我没有使用用户生成的字符串。谢谢! – user449511 2011-01-05 14:38:55

1

Altough不如谷歌自己的,我使用Apache Nutch LanguageIdentifier获得了很好的结果,它带有自己的pregrained ngram模型。我在多种语言的大型(50GB pdf,主要是文本)实际数据语料库上取得了相当不错的结果。

这是在Java中,但我敢肯定,你可以重读它的配置文件NGRAM如果你想重新实现它在Python。

0

我最近写了一个解决方案。我的解决方案并不是简单的证明,我认为这对于大量文本在计算上是不可行的,但在我看来,对于小句子来说,这很好。

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

  1. “LETMEBEGINBYSAYINGTHANKS”
  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. 构建顶点的曲线图,它的位置是在句子中的单词的起始索引,以向边到字结束后信的开始位置。 E.g,(0)L,使 “让” 可以通过(0) -> (3)表示,其中(3)M,这样的 “LET ME”。
  3. 找到0到len(text)之间的最大整数n,其中存在从索引0到索引n的简单定向路径。
  4. 除以文本的长度数n得到一个什么样的文字%的似乎是连续的英文单词一个大概的了解。

请注意,我的代码假设单词之间没有空格,但我想你可以很容易地将它调整为考虑空格。不是说我的代码要工作,你需要一个英文单词表文件。我从here得到了一个,但是你可以使用任何这样的文件,并且我想象这种方法也可以扩展到其他语言。

下面是代码:

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是英文。这听起来正确!

扩展这个大得多件的文字,我的建议是二次采样随机短串并检查他们的“英国风格”。希望这可以帮助!

+0

我的一位教授观察到,我的技术可以通过向后而不是向前通过图来改进,假设我们通常不会看英文。此外,我认为使用平分搜索方法可以稍微改进,以消除不必要的检查 - 无论天气与否,这可能会改善可能取决于输入英文长度的频率分布。 – 2018-02-19 20:29:35