2011-01-05 63 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