Python: ¿Cómo determinar el idioma?

86

Quiero conseguir esto:

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

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

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

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

¿Cómo puedo hacerlo en Python? Gracias.

Rita
fuente
2
¿Qué intentaste?
Raskayu
1
esto puede ayudar stackoverflow.com/questions/4545977/…
Sardorbek Imomaliev
Muy bien resumido aquí stackoverflow.com/a/48436520/2063605
SNA

Respuestas:

57

¿Ha echado un vistazo a langdetect ?

from langdetect import detect

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

print lang
#output: de
dheiberg
fuente
26
No muy preciso: detecta el idioma del texto "estructura anatómica" como ro(rumano). Se requiere salida en varios idiomas para tales casos. polyglot funciona mucho mejor.
Yuriy Petrovskiy
1
Interesante, el mismo ejemplo langdetectpuede determinar diferentes idiomas :-)
Denis Kuzin
1
por alguna razón, langdetect tiene errores, estoy usando Python 3.6
insinuación
184
  1. TextBlob . Requiere paquete NLTK, usa Google.

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

    pip install textblob

  2. Políglota . Requiere bibliotecas numpy y algunas arcanas, es poco probable que funcione para Windows . (Para Windows, obtenga una versión apropiada de PyICU , Morfessor y PyCLD2 desde aquí , luego solo pip install downloaded_wheel.whl.) Capaz de detectar textos con idiomas mixtos.

    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 las dependencias, ejecute: sudo apt-get install python-numpy libicu-dev

  3. chardet también tiene la función de detectar idiomas si hay bytes de caracteres en el rango (127-255]:

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

    pip install chardet

  4. langdetect Requiere grandes porciones de texto. Utiliza un enfoque no determinista bajo el capó. Eso significa que obtiene resultados diferentes para la misma muestra de texto. Los documentos dicen que debe usar el siguiente código para determinarlo:

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

    pip install langdetect

  5. guess_language Puede detectar muestras muy cortas utilizando este corrector ortográfico con diccionarios.

    pip install guess_language-spirit

  6. langid proporciona ambos módulos

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

    y una herramienta de línea de comandos:

    $ langid < README.md
    

    pip install langid

  7. FastText es un clasificador de texto, se puede utilizar para reconocer 176 idiomas con modelos adecuados para la clasificación de idiomas . Descargue este modelo , luego:

    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 es un modelo de red neuronal para la identificación de idiomas. Este paquete contiene el código de inferencia y un modelo entrenado.

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

    pip install pycld3

Rabash
fuente
2
detectlanges mucho más rápido queTextblob
Anwarvic
6
@Anwarvic TextBlob usa la API de Google ( github.com/sloria/TextBlob/blob/dev/textblob/translate.py#L33 ). por eso es lento.
Thomas Decaux
3
polyglotterminó siendo el más eficaz para mi caso de uso. langidquedó en segundo lugar
jamescampbell
3
En realidad, no tiene que lidiar con todo el paquete Polyglot si la detección de idioma es lo único que necesita. Como se indica en los documentos , la detección la realiza pyCLD2 , que es una biblioteca muy simple y fácil de usar.
Jeyekomon
1
También existe pyCLD3 .
tttthomasssss
7

Hay un problema langdetectcuando se usa para la paralelización y falla. Pero spacy_langdetectes un envoltorio para eso y puedes usarlo para ese propósito. También puede utilizar el siguiente fragmento:

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
fuente
Seguí tu respuesta, pero creo que sigo obteniendo la misma velocidad que con langdetect. Tengo una columna DF con textos, estoy usando column.apply()con una función haciendo scipy_langdetect. ¿Alguna sugerencia?
Rishabh Sahrawat
Necesita usar una biblioteca paralela para poder aprovechar la paralelización de la función como dask, de lo contrario, no haría ninguna diferencia.
Habib Karbasian
3

Si está buscando una biblioteca que es rápido con textos largos , polygloty fastextestá haciendo el mejor trabajo aquí.

Tomé muestras de 10000 documentos de una colección de HTML sucios y aleatorios, y aquí están los resultados:

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

He notado que muchos de los métodos se enfocan en textos cortos, probablemente porque es un problema difícil de resolver: si tienes mucho texto, es muy fácil detectar idiomas (por ejemplo, ¡uno podría usar un diccionario!). Sin embargo, esto dificulta encontrar un método fácil y adecuado para textos largos.

toto_tico
fuente
polyglotLa detección del idioma se basa en pycld2, que no es tan rápido en general. ¿O hay alguna manera de usarlo para identificar el idioma en una especie de modo por lotes? Solo he intentado manejar frase por frase.
Wiktor Stribiżew
Supongo que el texto largo está en el mismo idioma. Leo los 10000 documentos y los guardo en la memoria. Para fastextcc tengo que eliminar los \ncaracteres, pero no para polyglot (los resultados de cdl2 fueron prácticamente los mismos, también lo probé). No entiendo por qué piensas que políglota es lento, fue el más rápido. ¿Crees que debería haber eliminado el \ntambién y que mis resultados solo reflejan la primera oración (es decir, antes de la primera \n)?
toto_tico
Quiero decir, verifico los idiomas de millones de documentos separados que son cadenas de una línea. Eso es lento con pycld2.
Wiktor Stribiżew
Ya veo, no creo que haya una manera de hacer eso. Tienes que hacerlo uno por uno. Dependiendo de dónde estén almacenados sus documentos, es posible que pueda utilizar las capacidades de multiprocesamiento. Además, terminé usando fasttextcc porque estaba teniendo algunos problemas con las codificaciones de idiomas asiáticos.
toto_tico
En mi caso, la mayoría de los documentos eran extensos y un punto de referencia podía verse muy diferente con frases cortas.
toto_tico
2

Según el caso, es posible que le interese utilizar uno de los siguientes métodos:

Método 0: use una API o biblioteca

Por lo general, hay algunos problemas con estas bibliotecas porque algunas de ellas no son precisas para textos pequeños, faltan algunos idiomas, son lentas, requieren conexión a Internet, no son gratuitas, ... Pero en general, se adaptarán a la mayoría de las necesidades. .

Método 1: modelos de lenguaje

Un modelo de lenguaje nos da la probabilidad de una secuencia de palabras. Esto es importante porque nos permite detectar de manera robusta el idioma de un texto, incluso cuando el texto contiene palabras en otros idiomas (por ejemplo: "'Hola' significa 'hola' en español" ).

Puede utilizar N modelos de idiomas (uno por idioma) para calificar su texto. El idioma detectado será el idioma del modelo que le otorgó la puntuación más alta.

Si desea construir un modelo de lenguaje simple para esto, optaría por 1 gramo. Para hacer esto, solo necesita contar el número de veces que ha aparecido cada palabra de un texto grande (por ejemplo, Wikipedia Corpus en lenguaje "X").

Entonces, la probabilidad de una palabra será su frecuencia dividida por el número total de palabras analizadas (suma de todas las frecuencias).

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

Si el texto a detectar es bastante grande, recomiendo muestrear N palabras al azar y luego usar la suma de logaritmos en lugar de multiplicaciones para evitar problemas de precisión de punto flotante.

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 intersección

Un enfoque aún más simple es preparar N conjuntos (uno por idioma) con las M palabras más frecuentes. Luego cruce su texto con cada conjunto. El conjunto con el mayor número de intersecciones será su 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: compresión zip

Esto es más una curiosidad que cualquier otra cosa, pero aquí va ... Puede comprimir su texto (por ejemplo, LZ77) y luego medir la distancia del zip con respecto a un texto comprimido de referencia (idioma de destino). Personalmente, no me gustó porque es más lento, menos preciso y menos descriptivo que otros métodos. Sin embargo, puede haber aplicaciones interesantes para este método. Para leer más: Árboles de idiomas y compresión

Salva Carrión
fuente
2

Puede utilizar Googletrans (no oficial), una API de traducción de Google gratuita e ilimitada para Python.

Puedes realizar tantas solicitudes como quieras, no hay límites

Instalación:

$ pip install googletrans

Detección de idioma:

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

El modelo de texto rápido previamente entrenado funcionó mejor para mis necesidades similares

Llegué a tu pregunta con una necesidad muy similar. Encontré la mayor ayuda en las respuestas de Rabash para mis necesidades específicas.

Después de experimentar para encontrar lo que funcionaba mejor entre sus recomendaciones, que era asegurarse de que los archivos de texto estuvieran en inglés en más de 60.000 archivos de texto, descubrí que fasttext era una herramienta excelente para tal tarea.

Con un poco de trabajo, tenía una herramienta que funcionaba muy rápido con muchos archivos. Pero podría modificarse fácilmente para algo como su caso, porque fasttext funciona fácilmente sobre una lista de líneas.

Mi código con comentarios se encuentra entre las respuestas en ESTA publicación. Creo que usted y otros pueden modificar fácilmente este código para otras necesidades específicas.

Thom Ives
fuente
0

Puede intentar determinar el grupo de caracteres Unicode en la cadena de entrada para señalar el tipo de idioma (cirílico para ruso, por ejemplo), y luego buscar símbolos específicos del idioma en el texto.

Kerbiter
fuente
0

Probé todas las bibliotecas que existen y llegué a la conclusión de que pycld2 es la mejor, rápida y precisa.

puedes instalarlo así:

python -m pip install -U pycld2

puedes usarlo así:

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

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