Python: come determinare la lingua?


89

Voglio ottenere questo:

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

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

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

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

Come posso farlo in Python? Grazie.


4
Cosa hai provato?
Raskayu



Risposte:


57

Hai dato un'occhiata a langdetect ?

from langdetect import detect

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

print lang
#output: de

28
Non molto accurato: rileva la lingua del testo "struttura anatomica" come ro(rumeno). È richiesto un output in più lingue per questi casi. polyglot funziona molto meglio.
Yuriy Petrovskiy

2
Interessante, per lo stesso esempio langdetectpuò determinare lingue diverse :-)
Denis Kuzin

1
per qualche motivo, langdetect riceve degli errori, sto usando Python 3.6
allusione

Mai sentito parlare di Ein !!!
Timo

200
  1. TextBlob . Richiede il pacchetto NLTK, utilizza Google.

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

    pip install textblob

  2. Poliglotta . Richiede numpy e alcune librerie arcane, improbabile che funzioni per Windows . (Per Windows, procurati una versione appropriata di PyICU , Morfessor e PyCLD2 da qui , quindi solo pip install downloaded_wheel.whl.) In grado di rilevare testi con lingue miste.

    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

    Per installare le dipendenze, esegui: sudo apt-get install python-numpy libicu-dev

  3. chardet ha anche una funzione di rilevamento delle lingue se ci sono byte di caratteri nell'intervallo (127-255]:

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

    pip install chardet

  4. langdetect Richiede grandi porzioni di testo. Utilizza un approccio non deterministico sotto il cofano. Ciò significa che ottieni risultati diversi per lo stesso campione di testo. I documenti dicono che devi usare il seguente codice per determinarlo:

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

    pip install langdetect

  5. guess_language Può rilevare campioni molto brevi utilizzando questo correttore ortografico con dizionari.

    pip install guess_language-spirit

  6. langid fornisce entrambi i moduli

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

    e uno strumento da riga di comando:

    $ langid < README.md
    

    pip install langid

  7. FastText è un classificatore di testo, può essere utilizzato per riconoscere 176 lingue con modelli adeguati per la classificazione linguistica . Scarica questo modello , quindi:

    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 è un modello di rete neurale per l'identificazione del linguaggio. Questo pacchetto contiene il codice di inferenza e un modello addestrato.

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

    pip install pycld3


2
detectlangè molto più veloce diTextblob
Anwarvic

7
@Anwarvic TextBlob utilizza l'API di Google ( github.com/sloria/TextBlob/blob/dev/textblob/translate.py#L33 )! ecco perché è lento.
Thomas Decaux

4
polyglotha finito per essere il più performante per il mio caso d'uso. langidè arrivato secondo
jamescampbell il

3
In realtà non devi occuparti dell'intero pacchetto Polyglot se il rilevamento della lingua è l'unica cosa di cui hai bisogno. Come affermato nei documenti , il rilevamento viene effettuato da pyCLD2 , che è una libreria molto semplice e facile da usare.
Jeyekomon

1
C'è anche pyCLD3 .
tttthomasssss

7

Si è verificato un problema con langdetectquando viene utilizzato per la parallelizzazione e non riesce. Ma spacy_langdetectè un involucro per questo e puoi usarlo per quello scopo. Puoi utilizzare anche il seguente frammento:

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)

Ho seguito la tua risposta, ma penso di ottenere ancora la stessa velocità di langdetect. Ho una colonna DF con testi, sto usando column.apply()con una funzione che fa scipy_langdetect. Eventuali suggerimenti?
Rishabh Sahrawat

È necessario utilizzare una libreria parallela per poter sfruttare la parallelizzazione della funzione come dask, altrimenti non farebbe alcuna differenza.
Habib Karbasian

3

Se siete alla ricerca di una libreria che è veloce con testi lunghi , polyglote fastextsta facendo il miglior lavoro qui.

Ho campionato 10000 documenti da una raccolta di HTML sporchi e casuali, ed ecco i risultati:

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

Ho notato che molti metodi si concentrano su testi brevi, probabilmente perché è il problema difficile da risolvere: se hai molto testo, è davvero facile individuare le lingue (ad esempio, si potrebbe usare solo un dizionario!). Tuttavia, questo rende difficile trovare un metodo facile e adatto per testi lunghi.


polyglotil rilevamento della lingua si basa su pycld2, che non è così veloce tutto sommato. O c'è un modo per usarlo per identificare la lingua in una sorta di modalità batch? Ho solo provato a gestire frase per frase.
Wiktor Stribiżew

Presumo che il testo lungo sia nella stessa lingua. Ho letto i 10000 documenti e li tengo in memoria. Per fastextcc devo rimuovere i \ncaratteri, ma non per polyglot (i risultati di cdl2 erano più o meno gli stessi, l'ho testato anch'io). Non capisco perché pensi che il poliglotta sia lento, è stato il più veloce. Pensi che avrei dovuto rimuovere \nanche il, e che i miei risultati riflettono solo la prima frase (cioè, prima della prima \n)
toto_tico

Voglio dire, controllo le lingue di milioni di documenti separati che sono tutte stringhe di una riga. Questo è lento con pycld2.
Wiktor Stribiżew

Capisco, non credo che ci sia un modo per farlo. Devi farlo uno per uno. A seconda di dove sono archiviati i tuoi documenti, potresti essere in grado di utilizzare le funzionalità di multiprocessing. Inoltre, ho finito di usare fasttextcc perché avevo dei problemi con le codifiche in lingua asiatica.
toto_tico

Nel mio caso, la maggior parte dei documenti era lunga e un benchmark potrebbe apparire molto diverso con frasi brevi.
toto_tico

3

Puoi utilizzare Googletrans (non ufficiale), un'API di traduzione di Google gratuita e illimitata per Python.

Puoi fare tutte le richieste che vuoi, non ci sono limiti

Installazione:

$ pip install googletrans

Rilevamento della lingua:

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

2

A seconda del caso, potresti essere interessato a utilizzare uno dei seguenti metodi:

Metodo 0: utilizza un'API o una libreria

Di solito, ci sono alcuni problemi con queste librerie perché alcune di esse non sono accurate per testi di piccole dimensioni, alcune lingue mancano, sono lente, richiedono una connessione a Internet, non sono libere, ... Ma in generale, soddisfano la maggior parte delle esigenze .

Metodo 1: modelli linguistici

Un modello linguistico ci dà la probabilità di una sequenza di parole. Questo è importante perché ci permette di rilevare in modo affidabile la lingua di un testo, anche quando il testo contiene parole in altre lingue (es: "'Hola' significa 'ciao' in spagnolo" ).

Puoi utilizzare N modelli linguistici (uno per lingua) per assegnare un punteggio al testo. La lingua rilevata sarà la lingua del modello che ti ha dato il punteggio più alto.

Se vuoi costruire un semplice modello di linguaggio per questo, sceglierei 1 grammo. Per fare questo, devi solo contare il numero di volte in cui ogni parola di un testo grande (es. Wikipedia Corpus in lingua "X") è apparsa.

Quindi, la probabilità di una parola sarà la sua frequenza divisa per il numero totale di parole analizzate (somma di tutte le frequenze).

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 il testo da rilevare è abbastanza grande, consiglio di campionare N parole casuali e quindi utilizzare la somma dei logaritmi invece delle moltiplicazioni per evitare problemi di precisione in virgola mobile.

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

Metodo 2: insiemi intersecanti

Un approccio ancora più semplice consiste nel preparare N set (uno per lingua) con le M prime parole più frequenti. Quindi interseca il testo con ogni set. Il set con il maggior numero di incroci sarà la tua lingua rilevata.

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

Metodo 3: compressione zip

Questa è più una curiosità che altro, ma eccola qui ... Puoi comprimere il tuo testo (es. LZ77) e quindi misurare la distanza zip rispetto a un testo compresso di riferimento (lingua di destinazione). Personalmente non mi è piaciuto perché è più lento, meno accurato e meno descrittivo di altri metodi. Tuttavia, potrebbero esserci applicazioni interessanti per questo metodo. Per saperne di più: Alberi delle lingue e compressione


1

Il modello di testo veloce pre-addestrato ha funzionato meglio per le mie esigenze simili

Sono arrivato alla tua domanda con un'esigenza molto simile. Ho trovato il massimo aiuto dalle risposte di Rabash per le mie esigenze specifiche.

Dopo aver sperimentato per trovare ciò che funzionava meglio tra i suoi consigli, ovvero assicurarsi che i file di testo fossero in inglese in oltre 60.000 file di testo, ho scoperto che il fasttext era uno strumento eccellente per tale compito.

Con un po 'di lavoro, avevo uno strumento che funzionava molto velocemente su molti file. Ma potrebbe essere facilmente modificato per qualcosa come il tuo caso, perché fasttext funziona facilmente su un elenco di righe.

Il mio codice con i commenti è tra le risposte su QUESTO post. Credo che tu e altri possiate modificare facilmente questo codice per altre esigenze specifiche.


0

Puoi provare a determinare il gruppo di caratteri Unicode nella stringa di input per indicare il tipo di lingua (cirillico per russo, ad esempio), quindi cercare simboli specifici della lingua nel testo.


0

Ho provato tutte le librerie disponibili e ho concluso che pycld2 è la migliore, veloce e precisa.

puoi installarlo in questo modo:

python -m pip install -U pycld2

puoi usarlo in questo modo:

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

print(isReliable, details[0][1]) # reliablity(bool),lang abbrev.(en/es/de...)   
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.