Python: как определить язык?


86

Я хочу получить вот это:

Input text: "ру́сский язы́к"
Output text: "Russian" 

Input text: "中文"
Output text: "Chinese" 

Input text: "にほんご"
Output text: "Japanese" 

Input text: "العَرَبِيَّة"
Output text: "Arabic"

Как я могу это сделать на Python? Спасибо.


2
Что ты пробовал?
Raskayu


Красиво обобщено здесь stackoverflow.com/a/48436520/2063605
SNA

Ответы:


57

Вы смотрели на langdetect ?

from langdetect import detect

lang = detect("Ein, zwei, drei, vier")

print lang
#output: de

26
Не очень точно - определяет язык текста «анатомическая структура» как ro(румынский). В таких случаях требуется вывод на несколько языков. полиглот работает намного лучше.
Юрий Петровский

1
Интересно, по одному и тому же примеру langdetectможно определять разные языки :-)
Денис Кузин

1
по какой - то причине, langdetect дается ошибки, я использую Python 3.6
недосказанность

184
  1. TextBlob . Требуется пакет NLTK, использует Google.

    from textblob import TextBlob
    b = TextBlob("bonjour")
    b.detect_language()
    

    pip install textblob

  2. Полиглот . Требуется numpy и некоторые загадочные библиотеки, вряд ли они будут работать в Windows . (Для Windows, получить соответствующие версии PyICU , Morfessor и PyCLD2 от сюда , то просто pip install downloaded_wheel.whl) . Способен обнаружить тексты со смешанными языками.

    from polyglot.detect import Detector
    
    mixed_text = u"""
    China (simplified Chinese: 中国; traditional Chinese: 中國),
    officially the People's Republic of China (PRC), is a sovereign state
    located in East Asia.
    """
    for language in Detector(mixed_text).languages:
            print(language)
    
    # name: English     code: en       confidence:  87.0 read bytes:  1154
    # name: Chinese     code: zh_Hant  confidence:   5.0 read bytes:  1755
    # name: un          code: un       confidence:   0.0 read bytes:     0
    

    pip install polyglot

    Чтобы установить зависимости, запустите: sudo apt-get install python-numpy libicu-dev

  3. chardet также имеет функцию определения языков, если есть символьные байты в диапазоне (127-255):

    >>> chardet.detect("Я люблю вкусные пампушки".encode('cp1251'))
    {'encoding': 'windows-1251', 'confidence': 0.9637267119204621, 'language': 'Russian'}
    

    pip install chardet

  4. langdetect Требуется большой объем текста. Под капотом он использует недетерминированный подход. Это означает, что вы получите разные результаты для одного и того же образца текста. Документы говорят, что вам нужно использовать следующий код, чтобы определить его:

    from langdetect import detect, DetectorFactory
    DetectorFactory.seed = 0
    detect('今一はお前さん')
    

    pip install langdetect

  5. guess_language Может обнаруживать очень короткие образцы с помощью этого средства проверки правописания со словарями.

    pip install guess_language-spirit

  6. langid предоставляет оба модуля

    import langid
    langid.classify("This is a test")
    # ('en', -54.41310358047485)
    

    и инструмент командной строки:

    $ langid < README.md
    

    pip install langid

  7. FastText - это классификатор текста, может использоваться для распознавания 176 языков с соответствующими моделями классификации языков . Скачайте эту модель , затем:

    import fasttext
    model = fasttext.load_model('lid.176.ftz')
    print(model.predict('الشمس تشرق', k=2))  # top 2 matching languages
    
    (('__label__ar', '__label__fa'), array([0.98124713, 0.01265871]))
    

    pip install fasttext

  8. pyCLD3 - это модель нейронной сети для идентификации языка. Этот пакет содержит код вывода и обученную модель.

    import cld3
    cld3.get_language("影響包含對氣候的變化以及自然資源的枯竭程度")
    
    LanguagePrediction(language='zh', probability=0.999969482421875, is_reliable=True, proportion=1.0)
    

    pip install pycld3


2
detectlangнамного быстрее, чемTextblob
Anwarvic

6
@Anwarvic TextBlob использует Google API ( github.com/sloria/TextBlob/blob/dev/textblob/translate.py#L33 )! вот почему это медленно.
Thomas Decaux

3
polyglotоказался наиболее эффективным для моего случая использования. langidзанял второе место
Джеймскэмпбелл

3
На самом деле вам не нужно иметь дело со всем пакетом Polyglot, если вам нужно только определение языка. Как указано в документации , обнаружение выполняется с помощью pyCLD2 , которая является очень простой и удобной библиотекой.
Jeyekomon

1
Также существует pyCLD3 .
tttthomasssss

7

Возникает проблема, langdetectкогда он используется для распараллеливания, и он не работает. Но spacy_langdetectэто оболочка для этого, и вы можете использовать ее для этой цели. Вы также можете использовать следующий фрагмент:

import spacy
from spacy_langdetect import LanguageDetector

nlp = spacy.load("en")
nlp.add_pipe(LanguageDetector(), name="language_detector", last=True)
text = "This is English text Er lebt mit seinen Eltern und seiner Schwester in Berlin. Yo me divierto todos los días en el parque. Je m'appelle Angélica Summer, j'ai 12 ans et je suis canadienne."
doc = nlp(text)
# document level language detection. Think of it like average language of document!
print(doc._.language['language'])
# sentence level language detection
for i, sent in enumerate(doc.sents):
    print(sent, sent._.language)

Я следил за вашим ответом, но думаю, я все еще получаю ту же скорость, что и с langdetect. У меня есть столбец DF с текстами, который я использую для column.apply()выполнения функции scipy_langdetect. Какие-либо предложения?
Ришаб Сахрават,

Вам нужно использовать параллельную библиотеку, чтобы иметь возможность использовать преимущества распараллеливания функции, например dask, иначе это не будет иметь никакого значения.
Хабиб Карбасян

3

Если вы ищете библиотеки , которая быстро с длинными текстами , polyglotи fastextделают самую лучшую работу здесь.

Я взял 10 000 документов из коллекции грязных и случайных HTML-кодов, и вот результаты:

+------------+----------+
| Library    | Time     |
+------------+----------+
| polyglot   | 3.67 s   |
+------------+----------+
| fasttext   | 6.41     |
+------------+----------+
| cld3       | 14 s     |
+------------+----------+
| langid     | 1min 8s  |
+------------+----------+
| langdetect | 2min 53s |
+------------+----------+
| chardet    | 4min 36s |
+------------+----------+

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


polyglotопределение языка основано на том pycld2, что это в целом не так быстро. Или есть способ использовать его для идентификации языка в своего рода пакетном режиме? Я только пробовал рассматривать предложение за предложением.
Виктор Стрибилёв,

Я предполагаю, что длинный текст на том же языке. Я читаю 10000 документов и храню их в памяти. Для fastextcc я должен удалить \nсимволы, но не для полиглота (результаты cdl2 были почти такими же, я тоже его тестировал). Не понимаю, почему вы думаете, что полиглот медленный, он был самым быстрым. Как вы думаете, мне следовало также удалить \n, и что мои результаты просто отражают первое предложение (то есть перед первым \n)
toto_tico

Я имею в виду, что я проверяю языки миллионов отдельных документов, которые представляют собой однострочные строки. Это медленно с pycld2.
Виктор Стрибилёв,

Я понимаю, я не думаю, что есть способ сделать это. Вы должны делать это по одному. В зависимости от того, где хранятся ваши документы, вы можете использовать возможности многопроцессорной обработки. Кроме того, я прекратил использовать fasttextcc, потому что у меня были проблемы с кодировками азиатских языков.
toto_tico,

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

2

В зависимости от случая вам может быть интересно использовать один из следующих методов:

Метод 0: используйте API или библиотеку

Обычно с этими библиотеками возникает несколько проблем, потому что некоторые из них не подходят для небольших текстов, некоторые языки отсутствуют, они медленные, требуют подключения к Интернету, не бесплатны, ... Но в целом они подходят для большинства потребностей .

Метод 1: языковые модели

Языковая модель дает нам вероятность последовательности слов. Это важно, потому что позволяет нам надежно определять язык текста, даже если текст содержит слова на других языках (например: «Hola» означает «привет» на испанском языке » ).

Вы можете использовать N языковых моделей (по одной на каждый язык), чтобы оценить свой текст. Обнаруженный язык будет языком модели, которая дала вам наивысшую оценку.

Если вы хотите создать для этого простую языковую модель, я бы выбрал 1-грамм. Для этого вам нужно всего лишь подсчитать, сколько раз появлялось каждое слово из большого текста (например, Корпус Википедии на языке "X").

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

the 23135851162
of  13151942776
and 12997637966
to  12136980858
a   9081174698
in  8469404971
for 5933321709
...

=> P("'Hola' means 'hello' in spanish") = P("hola") * P("means") * P("hello") * P("in") * P("spanish")

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

P(s) = 0.03 * 0.01 * 0.014 = 0.0000042
P(s) = log10(0.03) + log10(0.01) + log10(0.014) = -5.376

Метод 2: пересекающиеся множества

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

spanish_set = {"de", "hola", "la", "casa",...}
english_set = {"of", "hello", "the", "house",...}
czech_set = {"z", "ahoj", "závěrky", "dům",...}
...

text_set = {"hola", "means", "hello", "in", "spanish"}

spanish_votes = text_set.intersection(spanish_set)  # 1
english_votes = text_set.intersection(english_set)  # 4
czech_votes = text_set.intersection(czech_set)  # 0
...

Метод 3: сжатие почтового индекса

Это скорее любопытство, чем что-либо еще, но вот оно ... Вы можете сжать свой текст (например, LZ77), а затем измерить расстояние zip относительно эталонного сжатого текста (целевой язык). Лично мне он не понравился, потому что он медленнее, менее точен и менее информативен, чем другие методы. Тем не менее, у этого метода могут быть интересные приложения. Чтобы узнать больше: языковые деревья и архивирование


2

Вы можете использовать Googletrans (неофициальный), бесплатный и неограниченный API Google Translate для Python.

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

Установка:

$ pip install googletrans

Определение языка:

>>> from googletrans import Translator
>>> t = Translator().detect("hello world!")
>>> t.lang
'en'
>>> t.confidence
0.8225234

1

Предварительно обученная модель быстрого текста лучше всего подходит для моих аналогичных потребностей

Я подошел к вашему вопросу с очень похожей потребностью. Больше всего мне помогли ответы Рабаша для моих конкретных потребностей.

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

Немного поработав, у меня появился инструмент, который очень быстро работал со многими файлами. Но его можно легко изменить для чего-то вроде вашего случая, потому что fasttext легко работает со списком строк.

Мой код с комментариями есть среди ответов на ЭТОЙ пост. Я считаю, что вы и другие легко можете изменить этот код для других конкретных нужд.


0

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


0

Я перепробовал все библиотеки и пришел к выводу, что pycld2 - лучшая, быстрая и точная.

установить его можно так:

python -m pip install -U pycld2

вы можете использовать это так:

isReliable, textBytesFound, details = cld2.detect(your_sentence)

print(isReliable, details[0][1]) # reliablity(bool),lang abbrev.(en/es/de...)   
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.