Python – могу ли я обнаружить код строкового языка Unicode?

Я столкнулся с ситуацией, когда я читаю строку текста, и мне нужно определить код языка (en, de, fr, es и т. д.).

Есть ли простой способ сделать это в python?


person sa125    schedule 28.12.2010    source источник


Ответы (7)


Если вам нужно определить язык в ответ на действие пользователя, вы можете использовать google. API языка ajax:

#!/usr/bin/env python
import json
import urllib, urllib2

def detect_language(text,
    userip=None,
    referrer="http://stackoverflow.com/q/4545977/4279",
    api_key=None):        

    query = {'q': text.encode('utf-8') if isinstance(text, unicode) else text}
    if userip: query.update(userip=userip)
    if api_key: query.update(key=api_key)

    url = 'https://ajax.googleapis.com/ajax/services/language/detect?v=1.0&%s'%(
        urllib.urlencode(query))

    request = urllib2.Request(url, None, headers=dict(Referer=referrer))
    d = json.load(urllib2.urlopen(request))

    if d['responseStatus'] != 200 or u'error' in d['responseData']:
        raise IOError(d)

    return d['responseData']['language']

print detect_language("Python - can I detect unicode string language code?")

Выход

en

API Google Translate v2

Ограничение по умолчанию 100000 символов/день (не более 5000 за раз).

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import urllib, urllib2

from operator import itemgetter

def detect_language_v2(chunks, api_key):
    """
    chunks: either string or sequence of strings

    Return list of corresponding language codes
    """
    if isinstance(chunks, basestring):
        chunks = [chunks] 

    url = 'https://www.googleapis.com/language/translate/v2'

    data = urllib.urlencode(dict(
        q=[t.encode('utf-8') if isinstance(t, unicode) else t 
           for t in chunks],
        key=api_key,
        target="en"), doseq=1)

    # the request length MUST be < 5000
    if len(data) > 5000:
        raise ValueError("request is too long, see "
            "http://code.google.com/apis/language/translate/terms.html")

    #NOTE: use POST to allow more than 2K characters
    request = urllib2.Request(url, data,
        headers={'X-HTTP-Method-Override': 'GET'})
    d = json.load(urllib2.urlopen(request))
    if u'error' in d:
        raise IOError(d)
    return map(itemgetter('detectedSourceLanguage'), d['data']['translations'])

Теперь вы можете явно запрашивать определение языка:

def detect_language_v2(chunks, api_key):
    """
    chunks: either string or sequence of strings

    Return list of corresponding language codes
    """
    if isinstance(chunks, basestring):
        chunks = [chunks] 

    url = 'https://www.googleapis.com/language/translate/v2/detect'

    data = urllib.urlencode(dict(
        q=[t.encode('utf-8') if isinstance(t, unicode) else t
           for t in chunks],
        key=api_key), doseq=True)

    # the request length MUST be < 5000
    if len(data) > 5000:
        raise ValueError("request is too long, see "
            "http://code.google.com/apis/language/translate/terms.html")

    #NOTE: use POST to allow more than 2K characters
    request = urllib2.Request(url, data,
        headers={'X-HTTP-Method-Override': 'GET'})
    d = json.load(urllib2.urlopen(request))

    return [sorted(L, key=itemgetter('confidence'))[-1]['language']
            for L in d['data']['detections']]

Пример:

print detect_language_v2(
    ["Python - can I detect unicode string language code?",
     u"матрёшка",
     u"打水"], api_key=open('api_key.txt').read().strip())

Выход

[u'en', u'ru', u'zh-CN']
person jfs    schedule 28.12.2010
comment
+1: Хороший способ использовать мощь некоторых хороших существующих инструментов. - person Eric O Lebigot; 28.12.2010
comment
@ShimonDoodkin: вы можете попробовать аналогичные услуги от разных поставщиков, например, microsoft-translate.py. - person jfs; 01.12.2014

В моем случае мне нужно определить только два языка, поэтому я просто проверяю первый символ:

import unicodedata

def is_greek(term):
    return 'GREEK' in unicodedata.name(term.strip()[0])


def is_hebrew(term):
    return 'HEBREW' in unicodedata.name(term.strip()[0])
person yekta    schedule 03.11.2015

Взгляните на угадай-язык:

Попытки определить естественный язык выделенного текста Unicode (utf-8).

Но, как следует из названия, оно угадывает язык. Вы не можете ожидать 100% правильных результатов.

Изменить:

язык догадок не поддерживается. Но есть ответвление (поддерживающее python3): guess_language-spirit

person Benjamin Wohlwend    schedule 28.12.2010

Ознакомьтесь с набором инструментов естественного языка и Автоматическая идентификация языка с помощью Python для идей.

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

person Paulo Scardine    schedule 28.12.2010

полезная статья предполагает, что этот открытый исходный код под названием CLD является лучшим выбором для определения языка в python.

В статье показано сравнение скорости и точности между 3 решениями:

  1. language-detection или его порт python langdetect
  2. Тика
  3. Распознавание языка Chromium (CLD)

Я потратил свое время на langdetect, теперь я переключаюсь на CLD, который в 16 раз быстрее, чем langdetect, и имеет точность 98,8%.

person Tushar Goswami    schedule 19.10.2016
comment
Есть идеи, улучшился ли langdetect с тех пор, как вы ответили на этот вопрос? - person Glen Thompson; 23.08.2017

Попробуйте Universal Encoding Detector — это порт chardet модуля из Firefox в Python.

person ismail    schedule 28.12.2010
comment
Это хорошая библиотека, но она дает мне кодировку вместо локали, которая мне не нужна. все равно спасибо. - person sa125; 28.12.2010
comment
Вы можете просто сопоставить кодировку с локалью. - person ismail; 28.12.2010
comment
@ İsmail 'cartman' Донмез: Это возможно только в том случае, если у языка есть собственная кодировка. Многие языки используют один и тот же алфавит. На какую локаль сопоставляется ascii? - person pafcu; 28.12.2010
comment
@pafcu, правда, но в фрагменте текста вы можете определить только кодировку, а не локаль, это зависит от системы. - person ismail; 28.12.2010
comment
Я предполагаю, что sa125 означает язык, а не локаль. - person pafcu; 28.12.2010
comment
@pafcu: ASCII был специально разработан для en_US; A действительно означает американский. Лучшим примером является windows-1252, который используется для английского, немецкого, испанского, французского, итальянского и т. д. - person dan04; 29.12.2010
comment
@ dan04: ASCII был разработан для en_US, но это не значит, что он не используется где-либо еще. Тот факт, что текст написан в ASCII, не означает, что он написан на американском английском языке. - person pafcu; 29.12.2010
comment
@dan04: Вот пример в ASCII, который не является английским текстом: 'Jeto ne anglijskij tekst' (detect_language_v2() из моего ответа сказано (неверно), что это 'cs' (чешский) stackoverflow.com/questions/4545977/ ) На самом деле это транслитерация русского языка (так что догадка гугла почти верна). - person jfs; 04.01.2011
comment
@Дж.Ф. Себастьян, хороший пример. - person ismail; 04.01.2011

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

person pafcu    schedule 28.12.2010