2011-01-05 2 views
8

Я ищу простой способ определить, является ли короткий отрывок текста, несколько предложений, английским или нет. Мне кажется, что эта проблема намного проще, чем попытка обнаружить произвольный язык. Есть ли там программное обеспечение, которое может это сделать? Я пишу на python и предпочитаю библиотеку python, но что-то еще будет хорошо. Я пробовал Google, но потом понял, что TOS не разрешает автоматические запросы.Обнаруживает, является ли текст английским (навалом)

+1

Возможный дубликат [Python - могу ли я определить код языка юникода?] (Http://stackoverflow.com/questions/4545977/python-can-i-detect-unicode-string-language-code) – ismail

+2

I ' m просят только на английском языке, в отличие от этой темы, где они просят любой произвольный язык. – user449511

+0

Он просто отлично работает на английском языке. – ismail

ответ

10

Я прочитал метод обнаружения Enlgish LANGAUGE с помощью триграмм

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

Вы можете перейти по тексту, и попытаться обнаружить наиболее часто используемые триграмм в слова. Если наиболее часто используемые из них совпадают с наиболее часто используемыми среди английских слов, текст может быть написан на английском языке

Попробуйте посмотреть в этом рубинового проекта:

https://github.com/feedbackmine/language_detector

+0

+1 для Trigams - очень круто. –

+0

Спасибо!Это простая идея для реализации, я могу дать это быстрый тест с небольшим набором тестового текста, который я должен увидеть, насколько он работает! – user449511

+0

Это потребует большой партии текста образца. OP может не иметь доступа к этому. – marcog

4

EDIT: В этом случае это не сработает, так как OP обрабатывает текст в массовом порядке, что противоречит TOS Google.

Используйте Google Translate 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

«API-интерфейс Google Language Detect должен использоваться для пользовательского обнаружения языка. Автоматизированные или пакетные запросы любого типа строго запрещены». Я думаю, именно поэтому вопросник касается и Условий обслуживания, которые он видел, и я предполагаю, что он поэтому хочет обнаружить язык без какого-либо ввода пользователем. –

+0

@tomlog Вы, вероятно, правы. Я думал, что он имел в виду соскабливание страниц GT. @user, можете ли вы подтвердить, обрабатываете ли вы строки, созданные пользователем? – marcog

+0

Я участвовал в пакетном опросе своего api с моим текстом, и мне отказали в доступе и поняли мою проблему. Я не использую созданные пользователем строки. Благодаря! – user449511

1

Altough не так хорошо, как свои собственные Google, У меня были хорошие результаты, используя Apache Nutch LanguageIdentifier, который поставляется с собственными предварительно обработанными моделями ngram. У меня были неплохие результаты на большом (50GB pdf, текстовом) корпусе реальных данных на нескольких языках.

Это на Java, но я уверен, что вы можете перечитать профили ngram из него, если вы хотите переопределить его в Python.

1

Google Translate API v2 allows automated queries, но для этого требуется использовать ключ API, который вы можете свободно получить по адресу Google APIs console.

Для того, чтобы обнаружить ли текст английский можно использовать detect_language_v2() функцию (которая использует этот API) от моего ответа на вопрос Python - can I detect unicode string language code?:

if all(lang == 'en' for lang in detect_language_v2(['some text', 'more text'])): 
    # all text fragments are in English 
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. Построить граф вершин, положением которых являются начальные индексы слов в предложении, с направленными ребрами в начальные позиции буквы после окончания слова. Например, (0) будет L, поэтому «LET» может быть представлено (0) -> (3), где (3) - M, так что это «LET ME».
  3. Найти наибольшее целое число n между 0 и len(text), для которого существует простой направленный путь от индекса 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

Профессор мой заметил, что моя техника может быть улучшена путем перехода назад, а не вперед по графику, предполагая, что чаще всего мы не смотрим на английский. Кроме того, я думаю, что небольшое улучшение может быть сделано с помощью метода поиска пополам, чтобы избавиться от ненужных проверок - погода или нет, это улучшит ситуацию, вероятно, будет зависеть от частотного распределения длины английского языка ввода. –