Python: Jak określić język?


86

Chcę to uzyskać:

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

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

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

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

Jak mogę to zrobić w Pythonie? Dzięki.


2
Czego próbowałeś?
Raskayu,


Ładnie podsumowane tutaj stackoverflow.com/a/48436520/2063605
SNA

Odpowiedzi:


57

Czy spojrzałeś na langdetect ?

from langdetect import detect

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

print lang
#output: de

26
Niezbyt dokładne - wykrywa język tekstu „struktura anatomiczna” jako ro(rumuński). W takich przypadkach wymagane jest wyjście w wielu językach. polyglot działa znacznie lepiej.
Yuriy Petrovskiy

1
Ciekawe, dla tego samego przykładu langdetectmożna określić różne języki :-)
Denis Kuzin

1
z jakiegoś powodu langdetect ma błędy, używam Pythona 3.6
insynuacje

184
  1. TextBlob . Wymaga pakietu NLTK, korzysta z Google.

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

    pip install textblob

  2. Polyglot . Wymaga numpy i niektórych tajemnych bibliotek, mało prawdopodobne, aby działał w systemie Windows . (W przypadku systemu Windows uzyskać odpowiednie wersje PyICU , Morfessor i PyCLD2 od tutaj , a potem po prostu pip install downloaded_wheel.whl.) W stanie wykryć tekstów z języków mieszanych.

    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

    Aby zainstalować zależności, uruchom: sudo apt-get install python-numpy libicu-dev

  3. chardet ma również funkcję wykrywania języków, jeśli w zakresie są bajty znaków (127-255]:

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

    pip install chardet

  4. langdetect Wymaga dużych fragmentów tekstu. Używa niedeterministycznego podejścia pod maską. Oznacza to, że otrzymujesz różne wyniki dla tej samej próbki tekstu. Dokumenty mówią, że aby to ustalić, musisz użyć następującego kodu:

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

    pip install langdetect

  5. guess_language Potrafi wykryć bardzo krótkie próbki za pomocą tego modułu sprawdzania pisowni ze słownikami.

    pip install guess_language-spirit

  6. langid zapewnia oba moduły

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

    i narzędzie wiersza poleceń:

    $ langid < README.md
    

    pip install langid

  7. FastText to klasyfikator tekstu, który może służyć do rozpoznawania 176 języków z odpowiednimi modelami klasyfikacji języków . Pobierz ten model , a następnie:

    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 to model sieci neuronowej służący do identyfikacji języka. Ten pakiet zawiera kod wnioskowania i wyszkolony model.

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

    pip install pycld3


2
detectlangjest znacznie szybszy niżTextblob
Anwarvic

6
@Anwarvic TextBlob korzysta z Google API ( github.com/sloria/TextBlob/blob/dev/textblob/translate.py#L33 )! dlatego jest wolny.
Thomas Decaux,

3
polyglotokazał się najbardziej wydajny w moim przypadku użycia. langidzajął drugie miejsce
jamescampbell

3
W rzeczywistości nie musisz zajmować się całym pakietem Polyglot, jeśli wykrywanie języka jest jedyną rzeczą, której potrzebujesz. Jak stwierdzono w dokumentacji , wykrywanie jest wykonywane przez pyCLD2 , który jest bardzo prostą i łatwą w użyciu biblioteką.
Jeyekomon,

1
Jest też pyCLD3 .
tttthomasssss

7

Występuje problem z tym, langdetectkiedy jest używany do zrównoleglania i kończy się niepowodzeniem. Ale spacy_langdetectjest to opakowanie i możesz go użyć do tego celu. Możesz również użyć następującego fragmentu kodu:

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)

Podążyłem za twoją odpowiedzią, ale myślę, że nadal osiągam tę samą prędkość, co w przypadku langdetect. Mam kolumnę DF z tekstami, używam column.apply()z funkcją do wykonania scipy_langdetect. Jakieś sugestie?
Rishabh Sahrawat

Musisz użyć biblioteki równoległej, aby móc skorzystać z równoległości funkcji, takiej jak dask, w przeciwnym razie nie miałoby to żadnego znaczenia.
Habib Karbasian

3

Jeśli szukasz biblioteki, który jest szybki z długich tekstów , polyglota fastextrobią najlepszą pracę tutaj.

Próbowałem 10000 dokumentów z kolekcji brudnych i losowych kodów HTML, a oto wyniki:

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

Zauważyłem, że wiele metod koncentruje się na krótkich tekstach, prawdopodobnie dlatego, że jest to trudny problem do rozwiązania: jeśli masz dużo tekstu, bardzo łatwo jest wykryć języki (np. Można po prostu użyć słownika!). Jednak utrudnia to znalezienie łatwej i odpowiedniej metody dla długich tekstów.


polyglotopiera się na wykrywaniu języka pycld2, który nie jest wcale taki szybki. A może jest sposób, aby użyć go do identyfikacji języka w trybie wsadowym? Próbowałem tylko radzić sobie zdanie po zdaniu.
Wiktor Stribiżew

Zakładam, że długi tekst jest w tym samym języku. Przeczytałem 10000 dokumentów i zachowuję je w pamięci. W przypadku fastextcc muszę usunąć \nznaki, ale nie dla polyglota (wyniki cdl2 były prawie takie same, testowałem to również). Nie rozumiem, dlaczego uważasz, że poliglota jest powolna, była najszybsza. Czy myślisz, że powinienem był również usunąć \n, a moje wyniki odzwierciedlają tylko pierwsze zdanie (tj. Przed pierwszym \n)
toto_tico

Chodzi mi o to, że sprawdzam języki milionów oddzielnych dokumentów, które są jednym ciągiem wierszy. To jest powolne w przypadku pycld2.
Wiktor Stribiżew

Rozumiem, nie sądzę, aby można było to zrobić. Musisz to zrobić jeden po drugim. W zależności od tego, gdzie przechowywane są Twoje dokumenty, możesz skorzystać z możliwości przetwarzania wieloprocesowego. Skończyłem też z fasttextcc, ponieważ miałem problemy z kodowaniem w językach azjatyckich.
toto_tico

W moim przypadku większość dokumentów była długa, a benchmark może wyglądać zupełnie inaczej z krótkimi zdaniami.
toto_tico

2

W zależności od przypadku możesz być zainteresowany użyciem jednej z następujących metod:

Metoda 0: użyj interfejsu API lub biblioteki

Zwykle jest kilka problemów z tymi bibliotekami, ponieważ niektóre z nich nie są dokładne dla małych tekstów, brakuje niektórych języków, są wolne, wymagają połączenia z Internetem, są płatne, ... Ale ogólnie rzecz biorąc, będą odpowiadać większości potrzeb .

Metoda 1: Modele językowe

Model języka daje nam prawdopodobieństwo wystąpienia sekwencji słów. Jest to ważne, ponieważ pozwala nam skutecznie wykryć język tekstu, nawet jeśli tekst zawiera słowa w innych językach (np. „Hola” oznacza „cześć” po hiszpańsku ” ).

Możesz użyć N modeli językowych (po jednym na język), aby ocenić swój tekst. Wykryty język będzie językiem modelu, który dał Ci najwyższy wynik.

Jeśli chcesz zbudować do tego prosty model językowy, wybrałbym 1-gram. Aby to zrobić, wystarczy policzyć, ile razy pojawiło się każde słowo z dużego tekstu (np. Korpus Wikipedii w języku „X”).

Wtedy prawdopodobieństwo wystąpienia słowa będzie równe jego częstotliwości podzielonej przez całkowitą liczbę przeanalizowanych słów (suma wszystkich częstości).

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

Jeśli tekst do wykrycia jest dość duży, zalecam próbkowanie N losowych słów, a następnie użycie sumy logarytmów zamiast mnożenia, aby uniknąć problemów z precyzją zmiennoprzecinkową.

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

Metoda 2: Przecinające się zbiory

Jeszcze prostszym podejściem jest przygotowanie N zestawów (po jednym na język) z M najczęściej występującymi słowami. Następnie przetnij swój tekst z każdym zestawem. Zestaw z największą liczbą skrzyżowań będzie wykrytym językiem.

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

Metoda 3: Kompresja zip

To bardziej ciekawostka niż cokolwiek innego, ale oto jest ... Możesz skompresować swój tekst (np. LZ77), a następnie zmierzyć odległość zip w odniesieniu do skompresowanego tekstu referencyjnego (język docelowy). Osobiście mi się to nie podobało, ponieważ jest wolniejsze, mniej dokładne i mniej opisowe niż inne metody. Niemniej jednak mogą istnieć interesujące zastosowania tej metody. Aby przeczytać więcej: Drzewa języków i zipowanie


2

Możesz użyć Googletrans (nieoficjalnego) bezpłatnego i nieograniczonego API Google do tłumaczenia dla języka Python.

Możesz składać tyle żądań, ile chcesz, nie ma ograniczeń

Instalacja:

$ pip install googletrans

Wykrywanie języka:

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

1

Wstępnie wytrenowany model szybkiego tekstu sprawdził się najlepiej w przypadku moich podobnych potrzeb

Przyszedłem do twojego pytania z bardzo podobną potrzebą. Największą pomoc znalazłem w odpowiedziach Rabasha na moje konkretne potrzeby.

Po przeprowadzeniu eksperymentów w celu znalezienia tego, co działało najlepiej z jego zaleceń, czyli upewnienia się, że pliki tekstowe są w języku angielskim w ponad 60 000 plikach tekstowych, stwierdziłem, że fasttext był doskonałym narzędziem do takiego zadania.

Przy odrobinie pracy miałem narzędzie, które działało bardzo szybko na wielu plikach. Ale można go łatwo zmodyfikować dla czegoś takiego jak twoja sprawa, ponieważ fasttext łatwo działa na liście linii.

Mój kod z komentarzami jest jedną z odpowiedzi w TYM poście. Wierzę, że Ty i inni możecie łatwo zmodyfikować ten kod pod kątem innych specyficznych potrzeb.


0

Możesz spróbować określić grupę znaków Unicode w ciągu wejściowym, aby wskazać typ języka (na przykład cyrylica dla języka rosyjskiego), a następnie wyszukać w tekście symbole specyficzne dla języka.


0

Wypróbowałem wszystkie dostępne biblioteki i doszedłem do wniosku, że pycld2 jest najlepszy, szybki i dokładny.

możesz to zainstalować w ten sposób:

python -m pip install -U pycld2

możesz tego użyć w ten sposób:

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

print(isReliable, details[0][1]) # reliablity(bool),lang abbrev.(en/es/de...)   
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.