Python: Como determinar a linguagem?

86

Eu quero pegar isso:

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

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

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

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

Como posso fazer isso em python? Obrigado.

Rita
fonte
2
O que você tentou?
Raskayu
1
isso pode ajudar stackoverflow.com/questions/4545977/…
Sardorbek Imomaliev
Muito bem resumido aqui stackoverflow.com/a/48436520/2063605
SNA

Respostas:

57

Você já deu uma olhada no langdetect ?

from langdetect import detect

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

print lang
#output: de
Dheiberg
fonte
26
Não muito preciso - detecta a linguagem da 'estrutura anatômica' do texto como ro(romeno). Saída em vários idiomas necessária para tais casos. poliglota tem um desempenho muito melhor.
Yuriy Petrovskiy de
1
Interessante, para o mesmo exemplo langdetectpode determinar diferentes idiomas :-)
Denis Kuzin
1
por algum motivo, langdetect recebe erros, estou usando Python 3.6
insinuação de
184
  1. TextBlob . Requer pacote NLTK, usa Google.

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

    pip install textblob

  2. Poliglota . Requer bibliotecas numpy e algumas bibliotecas misteriosas, improvável que funcione para Windows . (Para Windows, obtenha as versões apropriadas de PyICU , Morfessor e PyCLD2 a partir daqui , então apenas pip install downloaded_wheel.whl.) Capaz de detectar textos com idiomas mistos.

    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

    Para instalar as dependências, execute: sudo apt-get install python-numpy libicu-dev

  3. chardet também tem um recurso de detecção de idiomas se houver bytes de caracteres no intervalo (127-255]:

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

    pip install chardet

  4. langdetect Requer grandes porções de texto. Ele usa uma abordagem não determinística nos bastidores. Isso significa que você obtém resultados diferentes para a mesma amostra de texto. Os documentos dizem que você deve usar o seguinte código para torná-lo determinado:

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

    pip install langdetect

  5. guess_language Pode detectar amostras muito curtas usando este corretor ortográfico com dicionários.

    pip install guess_language-spirit

  6. langid fornece ambos os módulos

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

    e uma ferramenta de linha de comando:

    $ langid < README.md
    

    pip install langid

  7. FastText é um classificador de texto, pode ser usado para reconhecer 176 idiomas com modelos adequados para classificação de idiomas . Baixe este modelo e:

    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 é um modelo de rede neural para identificação de linguagem. Este pacote contém o código de inferência e um modelo treinado.

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

    pip install pycld3

Rabash
fonte
2
detectlangé muito mais rápido do queTextblob
Anwarvic
6
@Anwarvic TextBlob usa API do Google ( github.com/sloria/TextBlob/blob/dev/textblob/translate.py#L33 )! é por isso que é lento.
Thomas Decaux
3
polyglotacabou sendo o melhor desempenho para meu caso de uso. langidficou em segundo lugar
jamescampbell
3
Na verdade, você não precisa lidar com todo o pacote Polyglot se a detecção de idioma for a única coisa de que você precisa. Conforme declarado na documentação , a detecção é feita por pyCLD2 , que é uma biblioteca muito simples e fácil de usar.
Jeyekomon
1
Também existe o pyCLD3 .
tttthomasssss
7

Há um problema langdetectquando ele está sendo usado para paralelização e falha. Mas spacy_langdetecté um invólucro para isso e você pode usá-lo para essa finalidade. Você também pode usar o seguinte snippet:

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)
Habib Karbasian
fonte
Segui sua resposta, mas acho que ainda estou obtendo a mesma velocidade com o langdetect. Tenho uma coluna DF com textos, estou usando column.apply()com uma função fazendo scipy_langdetect. Alguma sugestão?
Rishabh Sahrawat
Você precisa usar uma biblioteca paralela para poder aproveitar a paralelização da função como dask, caso contrário não faria nenhuma diferença.
Habib Karbasian
3

Se procura uma biblioteca que seja rápida com textos longos , polyglote fastextestá a fazer o melhor trabalho aqui.

Eu fiz uma amostra de 10.000 documentos de uma coleção de HTMLs sujos e aleatórios, e aqui estão os resultados:

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

Percebi que muitos métodos focam em textos curtos, provavelmente porque é o problema difícil de resolver: se você tem muito texto, é realmente fácil detectar idiomas (por exemplo, pode-se usar apenas um dicionário!). No entanto, isso torna difícil encontrar um método fácil e adequado para textos longos.

toto_tico
fonte
polyglota detecção de idioma é baseada em pycld2, que não é tão rápida em tudo. Ou existe uma maneira de usá-lo para identificar a linguagem em uma espécie de modo de lote? Só tentei lidar com frase por frase.
Wiktor Stribiżew
Presumo que o texto descritivo esteja no mesmo idioma. Eu li os 10.000 documentos e os mantenho na memória. Para fastextcc eu tenho que remover os \ncaracteres, mas não para poliglota (os resultados do cdl2 foram praticamente os mesmos, eu testei também). Não entendo porque você acha que o poliglota é lento, foi o mais rápido. Você acha que eu deveria ter removido o \ntambém, e que meus resultados refletem apenas a primeira frase (ou seja, antes da primeira \n)
toto_tico
Quer dizer, eu verifico os idiomas de milhões de documentos separados que são strings de uma linha. Isso é lento com pycld2.
Wiktor Stribiżew
Entendo, não acho que haja uma maneira de fazer isso. Você tem que fazer um por um. Dependendo de onde seus documentos estão armazenados, você pode usar os recursos de multiprocessamento. Além disso, terminei de usar fasttextcc porque estava tendo alguns problemas com a codificação de idiomas asiáticos.
toto_tico
No meu caso, a maioria dos documentos era longa e um benchmark pode parecer muito diferente com frases curtas.
toto_tico
2

Dependendo do caso, você pode estar interessado em usar um dos seguintes métodos:

Método 0: Use uma API ou biblioteca

Normalmente, existem alguns problemas com essas bibliotecas porque algumas delas não são precisas para textos pequenos, faltam alguns idiomas, são lentas, exigem conexão com a Internet, não são gratuitas, ... Mas, de modo geral, elas atenderão à maioria das necessidades .

Método 1: modelos de linguagem

Um modelo de linguagem nos dá a probabilidade de uma sequência de palavras. Isso é importante porque nos permite detectar de forma robusta o idioma de um texto, mesmo quando o texto contém palavras em outros idiomas (por exemplo: "'Hola' significa 'Olá' em espanhol" ).

Você pode usar N modelos de idioma (um por idioma) para pontuar seu texto. O idioma detectado será o idioma do modelo que deu a você a maior pontuação.

Se você quiser construir um modelo de linguagem simples para isso, eu escolheria 1 grama. Para fazer isso, você só precisa contar o número de vezes que cada palavra de um grande texto (por exemplo, Wikipedia Corpus no idioma "X") apareceu.

Então, a probabilidade de uma palavra será sua frequência dividida pelo número total de palavras analisadas (soma de todas as frequências).

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")

Se o texto a ser detectado for muito grande, recomendo amostrar N palavras aleatórias e usar a soma dos logaritmos em vez de multiplicações para evitar problemas de precisão de ponto flutuante.

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

Método 2: Conjuntos de intersecção

Uma abordagem ainda mais simples é preparar N conjuntos (um por idioma) com as M primeiras palavras mais frequentes. Em seguida, cruze seu texto com cada conjunto. O conjunto com o maior número de cruzamentos será o seu idioma detectado.

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
...

Método 3: compressão Zip

Isso é mais uma curiosidade do que qualquer outra coisa, mas aqui vai ... Você pode compactar seu texto (por exemplo, LZ77) e então medir a distância zip em relação a um texto compactado de referência (idioma de destino). Pessoalmente, não gostei porque é mais lento, menos preciso e menos descritivo do que outros métodos. No entanto, pode haver aplicações interessantes para este método. Para ler mais: Árvores de linguagem e compactação

Salva Carrión
fonte
2

Você pode usar Googletrans (não oficial), uma API de tradução gratuita e ilimitada do Google para Python.

Você pode fazer quantas solicitações quiser, não há limites

Instalação:

$ pip install googletrans

Detecção de idioma:

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

O modelo de texto rápido pré-treinado funcionou melhor para minhas necessidades semelhantes

Cheguei à sua pergunta com uma necessidade muito semelhante. Eu encontrei mais ajuda nas respostas do Rabash para minhas necessidades específicas.

Depois de experimentar para encontrar o que funcionava melhor entre suas recomendações, que era garantir que os arquivos de texto estivessem em inglês em mais de 60.000 arquivos de texto, descobri que o texto rápido era uma excelente ferramenta para essa tarefa.

Com um pouco de trabalho, eu tinha uma ferramenta que funcionava muito rápido em muitos arquivos. Mas ele poderia ser facilmente modificado para algo como o seu caso, porque o texto rápido funciona facilmente em uma lista de linhas.

Meu código com comentários está entre as respostas sobre ESTE post. Eu acredito que você e outras pessoas podem facilmente modificar este código para outras necessidades específicas.

Thom Ives
fonte
0

Você pode tentar determinar o grupo Unicode de caracteres na string de entrada para apontar o tipo de idioma (cirílico para russo, por exemplo) e, em seguida, pesquisar símbolos específicos do idioma no texto.

Kerbiter
fonte
0

Tentei todas as bibliotecas que existem e concluí que pycld2 é a melhor, rápida e precisa.

você pode instalá-lo assim:

python -m pip install -U pycld2

você pode usá-lo assim:

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

print(isReliable, details[0][1]) # reliablity(bool),lang abbrev.(en/es/de...)   
Fei Yan
fonte