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
СНР

Можливо, див. Також github.com/topics/language-identification?l=python
tripleee

Відповіді:


56

Ви бачили 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вийшов другим
jamescampbell

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робите тут найкращу роботу.

Я відібрав 10000 документів із колекції брудних і випадкових HTML-кодів, і ось результати:

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

Я помітив, що багато методів зосереджені на коротких текстах, мабуть, тому, що це важка проблема для вирішення: якщо у вас багато тексту, мови дуже легко виявити (наприклад, можна просто скористатися словником!). Однак це ускладнює пошук легкого та придатного методу для довгих текстів.


polyglotВизначення мови базується на тому pycld2, що не все так швидко. Або є спосіб використовувати його для ідентифікації мови в якомусь пакетному режимі? Я намагався лише обробити речення за реченням.
Wiktor Stribiżew

Я припускаю, що довгий текст написаний однією мовою. Я читаю 10000 документів і зберігаю їх у пам'яті. Для fastextcc мені потрібно видалити \nсимволи, але не для поліглота (результати cdl2 були майже однаковими, я теж тестував це). Я не розумію, чому ви думаєте, що поліглот повільний, це було найшвидше. Ви вважаєте, що мені слід було також видалити \nі те, і що мої результати просто відображають перше речення (тобто перед першим \n)
toto_tico

Я маю на увазі, я перевіряю мови мільйонів окремих документів, які є всіми рядками в один рядок. Це повільно з pycld2.
Wiktor Stribiżew

Я бачу, я не думаю, що є спосіб зробити це. Ви повинні робити це по одному. Залежно від того, де зберігаються ваші документи, ви можете використовувати можливості багатопроцесорної обробки. Крім того, я закінчив використовувати 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 наборів (по одному на мову) з найпоширенішими М-словами. Потім перетинайте текст із кожним набором. Набір із найбільшою кількістю перетинів буде вашою виявленою мовою.

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: Стиснення ZIP

Це більше цікавості, ніж будь-що інше, але тут справа йде ... Ви можете стиснути текст (наприклад, LZ77), а потім виміряти відстань поштового індексу щодо стисненого тексту посилання (цільова мова). Особисто мені це не сподобалось, оскільки він повільніший, менш точний і менш описовий, ніж інші методи. Тим не менше, для цього методу можуть бути цікаві програми. Читати далі: Мовні дерева та застібки-блискавки


2

Ви можете використовувати Googletrans (неофіційний) безкоштовний і необмежений API перекладу Google для Python.

Ви можете робити скільки завгодно запитів, обмежень немає

Встановлення:

$ pip install googletrans

Виявлення мови:

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

1

Модель швидкого текстового перегляду, яка найкраще працювала для моїх подібних потреб

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

Поекспериментувавши, щоб знайти найкраще серед його рекомендацій, а саме, переконавшись, що текстові файли мають англійську мову в 60 000+ текстових файлів, я виявив, що швидкий текст є чудовим інструментом для такого завдання.

Трохи попрацювавши, я мав інструмент, який працював дуже швидко над багатьма файлами. Але його можна легко змінити для чогось на зразок вашого випадку, оскільки швидкий текст легко працює над списком рядків.

Мій код із коментарями є серед відповідей на ЦЮ публікацію. Я вважаю, що ви та інші можете легко змінити цей код для інших конкретних потреб.


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.