Python: Dil nasıl belirlenir?


88

Bunu almak istiyorum:

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

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

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

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

Bunu python'da nasıl yapabilirim? Teşekkürler.


4
Ne denedin
Raskayu


Burada güzel bir şekilde özetlenmiştir stackoverflow.com/a/48436520/2063605
SNA

Yanıtlar:


57

Langdetect'e bir göz attın mı?

from langdetect import detect

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

print lang
#output: de

28
Çok doğru değil - metnin 'anatomik yapısını' ro(Romence) olarak algılar . Bu tür durumlar için çoklu dil çıkışı gereklidir. polyglot çok daha iyi performans gösterir.
Yuriy Petrovskiy

2
İlginç, aynı örnek langdetectiçin farklı diller belirleyebilir :-)
Denis Kuzin

1
Bazı nedenlerden dolayı, langdetect'e hatalar verildi, Python 3.6 kullanıyorum
innuendo

Duymadım Ein !!!
Timo

199
  1. TextBlob . NLTK paketi gerektirir, Google'ı kullanır.

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

    pip install textblob

  2. Polyglot . Windows için çalışması pek olası olmayan numpy ve bazı esrarengiz kitaplıklar gerektirir . (Windows için, uygun bir sürümlerini almak PyICU , Morfessor ve PyCLD2 dan buraya sonra sadece, pip install downloaded_wheel.whl.) Karışık dillerle metinleri tespit edebiliyoruz.

    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

    Bağımlılıkları yüklemek için şunu çalıştırın: sudo apt-get install python-numpy libicu-dev

  3. chardet , aralıkta (127-255] karakter baytları varsa, dilleri algılama özelliğine de sahiptir:

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

    pip install chardet

  4. langdetect Büyük metin bölümleri gerektirir. Başlık altında deterministik olmayan bir yaklaşım kullanır. Bu, aynı metin örneği için farklı sonuçlar alacağınız anlamına gelir. Dokümanlar, bunu belirlemek için aşağıdaki kodu kullanmanız gerektiğini söylüyor:

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

    pip install langdetect

  5. Tahmin_langu Bu yazım denetleyicisini sözlüklerle birlikte kullanarak çok kısa örnekleri algılayabilir .

    pip install guess_language-spirit

  6. langid her iki modülü de sağlar

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

    ve bir komut satırı aracı:

    $ langid < README.md
    

    pip install langid

  7. FastText bir metin sınıflandırıcıdır ve 176 dili uygun bir dil sınıflandırması modeliyle tanımak için kullanılabilir . Bu modeli indirin , ardından:

    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 , dil tanımlaması için bir sinir ağı modelidir. Bu paket, çıkarım kodunu ve eğitimli bir modeli içerir.

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

    pip install pycld3


2
detectlangçok daha hızlıTextblob
Anwarvic

7
@Anwarvic TextBlob, Google API kullanır ( github.com/sloria/TextBlob/blob/dev/textblob/translate.py#L33 )! bu yüzden yavaş.
Thomas Decaux

4
polyglotkullanım durumum için en iyi performans gösteren oldu. langidikinci geldi
jamescampbell

3
İhtiyacınız olan tek şey dil algılama ise aslında tüm Polyglot paketiyle uğraşmak zorunda değilsiniz. Dokümanlarda belirtildiği gibi , algılama , çok basit ve kullanımı kolay olan pyCLD2 ile yapılır .
Jeyekomon

1
Ayrıca pyCLD3 de vardır .
tttthomasssss

7

langdetectParalelleştirme için kullanıldığında bir sorun var ve başarısız oluyor. Ama spacy_langdetectbunun için bir paketleyicidir ve bunu bu amaçla kullanabilirsiniz. Aşağıdaki parçacığı da kullanabilirsiniz:

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)

Cevabınızı takip ettim ama sanırım hala ile aynı hıza ulaşıyorum langdetect. Yazılı bir DF sütunum var, column.apply()yapıyorum bir fonksiyon ile kullanıyorum scipy_langdetect. Herhangi bir öneri?
Rishabh Sahrawat

Fonksiyonun paralelleştirilmesinden yararlanabilmek için paralel bir kütüphane kullanmanız gerekir dask, aksi takdirde bir fark yaratmaz.
Habib Karbasian

3

Eğer aradığınız uzun metinlerle hızlı bir kütüphane , polyglotve fastextburada en iyi iş yapıyoruz.

Kirli ve rastgele HTML koleksiyonundan 10000 belgeyi örnekledim ve işte sonuçlar:

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

Pek çok yöntemin kısa metinlere odaklandığını fark ettim, çünkü muhtemelen çözülmesi zor bir sorundur: çok fazla metniniz varsa, dilleri algılamak gerçekten kolaydır (örneğin, bir sözlük kullanabilir!). Ancak bu, uzun metinler için kolay ve uygun bir yöntem bulmayı zorlaştırmaktadır.


polyglotdil tespiti temel alır pycld2, bu sonuçta o kadar hızlı değildir. Veya dili bir tür toplu modda tanımlamak için kullanmanın bir yolu var mı? Sadece cümle ile cümle kurmayı denedim.
Wiktor Stribiżew

Uzun metnin aynı dilde olduğunu varsayıyorum. 10000 belgeyi okudum ve hafızada tutuyorum. Fastextcc için \nkarakterleri kaldırmam gerekiyor , ancak çok dilli için değil (cdl2 sonuçları hemen hemen aynıydı, ben de test ettim). Neden poliglotun yavaş olduğunu düşündüğünü anlamıyorum, bu en hızlıydı. Sence ben de kaldırmalı mıyım \nve sonuçlarımın sadece ilk cümleyi (yani, \n
ilkinden

Demek istediğim, hepsi tek satır dizileri olan milyonlarca ayrı belgenin dillerini kontrol ediyorum. Bu pycld2 ile yavaştır.
Wiktor Stribiżew

Anlıyorum, bunu yapmanın bir yolu olduğunu sanmıyorum. Bunu tek tek yapmalısın. Belgelerinizin nerede saklandığına bağlı olarak, çoklu işlem yeteneklerini kullanabilirsiniz. Ayrıca, fasttextcc kullanmayı bıraktım çünkü Asya dili kodlamalarıyla ilgili bazı sorunlar yaşıyordum.
toto_tico

Benim durumumda, belgelerin çoğu uzundu ve kısa cümlelerle kıyaslama çok farklı görünebilir.
toto_tico

3

Python için ücretsiz ve sınırsız bir Google çeviri API'sı olan Googletrans'ı (resmi olmayan) kullanabilirsiniz .

İstediğiniz kadar talepte bulunabilirsiniz, limit yoktur

Kurulum:

$ pip install googletrans

Dil algılama:

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

2

Vakaya bağlı olarak, aşağıdaki yöntemlerden birini kullanmak ilginizi çekebilir:

Yöntem 0: Bir API veya kitaplık kullanın

Genellikle, bu kütüphanelerde bir kaç sorun vardır çünkü bunlardan bazıları küçük metinler için doğru değildir, bazı diller eksiktir, yavaştır, internet bağlantısı gerektirir, özgür değildir, ... Ancak genel olarak konuşursak, çoğu ihtiyaca uygun olacaktır. .

Yöntem 1: Dil modelleri

Bir dil modeli bize bir dizi kelime olasılığını verir. Bu önemlidir, çünkü metin başka dillerde sözcükler içerse bile (örneğin: "'Hola' ispanyolca'da 'merhaba' anlamına gelir) bile bir metnin dilini sağlam bir şekilde algılamamıza izin verir .

Metninizi puanlamak için N dil modelini (her dil için bir tane) kullanabilirsiniz. Tespit edilen dil, size en yüksek puanı veren modelin dili olacaktır.

Bunun için basit bir dil modeli oluşturmak istiyorsanız, 1 gram tercih ederim. Bunu yapmak için, yalnızca büyük bir metindeki her kelimenin (örneğin "X" dilinde Wikipedia Corpus) görünme sayısını saymanız gerekir.

Daha sonra, bir kelimenin olasılığı, analiz edilen toplam kelime sayısına (tüm frekansların toplamı) bölünmesiyle elde edilen frekans olacaktır.

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

Algılanacak metin oldukça büyükse, N rastgele kelimeyi örneklemenizi ve ardından kayan nokta hassasiyet sorunlarını önlemek için çarpma yerine logaritma toplamını kullanmanızı öneririm.

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

Yöntem 2: Kesişen kümeler

Daha da basit bir yaklaşım, en sık kullanılan M kelimeyi içeren N küme (dil başına bir) hazırlamaktır. Sonra metninizi her setle kesiştirin. En yüksek sayıda kesişme noktasına sahip olan set, tespit edilen diliniz olacaktır.

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

Yöntem 3: Zip sıkıştırması

Bu, her şeyden çok bir merak, ama işte burada ... Metninizi sıkıştırabilir (örn. LZ77) ve sonra zip mesafesini referans sıkıştırılmış metne (hedef dil) göre ölçebilirsiniz. Kişisel olarak, diğer yöntemlere göre daha yavaş, daha az doğru ve daha az açıklayıcı olduğu için beğenmedim. Yine de, bu yöntem için ilginç uygulamalar olabilir. Daha fazlasını okumak için: Dil Ağaçları ve Sıkıştırma


1

Önceden Eğitilmiş Hızlı Metin Modeli Benzer İhtiyaçlarım İçin En İyi Şekilde Çalıştı

Sorunuza çok benzer bir ihtiyaç ile geldim. Özel ihtiyaçlarım için Rabash'ın cevaplarından en çok yardımı buldum.

Önerileri arasında en çok neyin işe yaradığını bulmayı denedikten sonra, bu metin dosyalarının 60.000'den fazla metin dosyasında İngilizce olmasını sağladıktan sonra, fasttext'in böyle bir görev için mükemmel bir araç olduğunu keşfettim.

Küçük bir çalışmayla birçok dosyada çok hızlı çalışan bir araca sahip oldum. Ancak, sizin durumunuz gibi bir şey için kolayca değiştirilebilir, çünkü fasttext bir satır listesi üzerinde kolayca çalışır.

Yorumlarla Kodum üzerinde cevaplar arasında yer alıyor BU yazı. Sizin ve başkalarının bu kodu diğer özel ihtiyaçlar için kolayca değiştirebileceğine inanıyorum.


0

Dil türünü belirtmek için giriş dizesindeki Unicode karakter grubunu belirlemeyi deneyebilir (örneğin, Rusça için Kiril) ve ardından metinde dile özgü sembolleri arayabilirsiniz.


0

Oradaki tüm kütüphaneleri denedim ve pycld2'nin en iyisi, hızlı ve doğru olduğu sonucuna vardım.

şu şekilde kurabilirsiniz:

python -m pip install -U pycld2

bunu şu şekilde kullanabilirsiniz:

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

print(isReliable, details[0][1]) # reliablity(bool),lang abbrev.(en/es/de...)   
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.