如何确定一段文本的语言?

187

我想要获得这个:

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

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

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

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

我该如何用Python实现它?


1
这可能会有所帮助:https://dev59.com/ym855IYBdhLWcg3wFAHy - Sardorbek Imomaliev
这里很好地总结了 https://dev59.com/LVcQ5IYBdhLWcg3wEPsK#48436520 - SNA
也许还可以参考 https://github.com/topics/language-identification?l=python - tripleee
16个回答

2

我已经尝试了所有的库,得出结论pycld2是最好的一个,速度快且准确。

你可以像这样安装它:

python -m pip install -U pycld2

你可以这样使用:

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

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

2

根据情况,您可能会对以下方法之一感兴趣:

方法0:使用API或库

通常,这些库存在一些问题,因为其中一些对于小文本不准确,某些语言缺失,速度慢,需要互联网连接,是非免费的等等。但总体而言,它们将适合大多数需求。

方法1:语言模型

一个语言模型可以给我们提供一串单词的概率。这很重要,因为它能够让我们准确地检测一段文本的语言,即使这段文本中包含其他语言的单词(例如:“'Hola' 在西班牙语中意味着 '你好'”)。
您可以使用 N 种语言模型(每种语言一种),来对您的文本进行打分。被检测到的语言将是得分最高的模型所代表的语言。
如果您想创建一个简单的语言模型,我会选择 1-grams 模型。要做到这一点,您只需要统计大文本(例如“X”语言的维基百科语料库)中每个单词出现的次数。
然后,一个单词的概率就是它的频率除以分析的所有单词的总数(也就是所有频率之和)。
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")

如果要检测的文本很大,我建议抽样N个随机单词,然后使用对数之和而不是乘法来避免浮点精度问题。
P(s) = 0.03 * 0.01 * 0.014 = 0.0000042
P(s) = log10(0.03) + log10(0.01) + log10(0.014) = -5.376

方法二:交集法

一种更简单的方法是准备N个集合(每种语言一个),包含前M个最常用的单词。然后将您的文本与每个集合进行交集运算。交集数量最多的集合即为检测到的语言。

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

方法三:Zip 压缩

这更多是好奇而已,但还是来说一下吧... 你可以压缩文本(例如 LZ77),然后测量与参考压缩文本(目标语言)之间的 zip 距离。个人认为,这种方法比其他方法更慢、不够准确和不够描述性。尽管如此,这种方法可能有有趣的应用。

阅读更多:Language Trees and Zipping


1
你可以尝试确定输入字符串中字符的Unicode组,以指出语言类型(例如俄语的西里尔文),然后在文本中搜索特定于语言的符号。

1
如果您要检测的语言包括以下语言:
阿拉伯语(ar) 保加利亚语(bg) 德语(de) 现代希腊语(el) 英语(en) 西班牙语(es) 法语(fr) 印地语(hi) 意大利语(it) 日语(ja) 荷兰语(nl) 波兰语(pl) 葡萄牙语(pt) 俄语(ru) 斯瓦希里语(sw) 泰语(th) 土耳其语(tr) 乌尔都语(ur) 越南语(vi) 中文(zh)
那么使用HuggingFace库和模型(深度学习自然语言处理,如果您对此不熟悉)就相对容易了:
# Import libraries
from transformers import pipeline
# Load pipeline
classifier = pipeline("text-classification", model = "papluca/xlm-roberta-base-language-detection")
# Example sentence
sentence1 = 'Ciao, come stai?'
# Get language
classifier(sentence1)

输出:

[{'label': 'it', 'score': 0.9948362112045288}]
一些细节:

训练集包含70k个样本,而验证和测试集各有10k个。测试集上的平均准确率为99.6%。

您可以在模型页面找到更多信息,我相信您可以找到其他适合您需求的模型。


1
您可以安装pycld2 Python库。
pip install pycld2

或者

python -m pip install -U pycld2

为了使下面的代码正常工作。
import pycld2 as cld2

isReliable, textBytesFound, details = cld2.detect(
    "а неправильный формат идентификатора дн назад"
)

print(isReliable)
# True
details[0]
# ('RUSSIAN', 'ru', 98, 404.0)

fr_en_Latn = """\
France is the largest country in Western Europe and the third-largest in Europe as a whole.
A accès aux chiens et aux frontaux qui lui ont été il peut consulter et modifier ses collections
et exporter Cet article concerne le pays européen aujourd’hui appelé République française.
Pour d’autres usages du nom France, Pour une aide rapide et effective, veuiller trouver votre aide
dans le menu ci-dessus.
Motoring events began soon after the construction of the first successful gasoline-fueled automobiles.
The quick brown fox jumped over the lazy dog."""

isReliable, textBytesFound, details, vectors = cld2.detect(
    fr_en_Latn, returnVectors=True
)
print(vectors)
# ((0, 94, 'ENGLISH', 'en'), (94, 329, 'FRENCH', 'fr'), (423, 139, 'ENGLISH', 'en'))

Pycld2 Python库是Compact Language Detect 2(CLD2)的Python绑定。 您可以探索Pycld2的不同功能。 在此处了解有关Pycld2的更多信息


1

确定一个文本的语言最好的方法是实现以下函数:

from langdetect import detect

def get_language(text):

    keys =['ab', 'aa', 'af', 'ak', 'sq', 'am', 'ar', 'an', 'hy', 'as', 'av', 'ae', 'ay', 'az', 'bm', 'ba', 'eu', 'be', 'bn', 'bi', 'bs', 'br', 'bg', 'my', 'ca', 'ch', 'ce', 'ny', 'zh', 'cu', 'cv', 'kw', 'co', 'cr', 'hr', 'cs', 'da', 'dv', 'nl', 'dz', 'en', 'eo', 'et', 'ee', 'fo', 'fj', 'fi', 'fr', 'fy', 'ff', 'gd', 'gl', 'lg', 'ka', 'de', 'el', 'kl', 'gn', 'gu', 'ht', 'ha', 'he', 'hz', 'hi', 'ho', 'hu', 'is', 'io', 'ig', 'id', 'ia', 'ie', 'iu', 'ik', 'ga', 'it', 'ja', 'jv', 'kn', 'kr', 'ks', 'kk', 'km', 'ki', 'rw', 'ky', 'kv', 'kg', 'ko', 'kj', 'ku', 'lo', 'la', 'lv', 'li', 'ln', 'lt', 'lu', 'lb', 'mk', 'mg', 'ms', 'ml', 'mt', 'gv', 'mi', 'mr', 'mh', 'mn', 'na', 'nv', 'nd', 'nr', 'ng', 'ne', 'no', 'nb', 'nn', 'ii', 'oc', 'oj', 'or', 'om', 'os', 'pi', 'ps', 'fa', 'pl', 'pt', 'pa', 'qu', 'ro', 'rm', 'rn', 'ru', 'se', 'sm', 'sg', 'sa', 'sc', 'sr', 'sn', 'sd', 'si', 'sk', 'sl', 'so', 'st', 'es', 'su', 'sw', 'ss', 'sv', 'tl', 'ty', 'tg', 'ta', 'tt', 'te', 'th', 'bo', 'ti', 'to', 'ts', 'tn', 'tr', 'tk', 'tw', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'cy', 'wo', 'xh', 'yi', 'yo', 'za', 'zu']
    
    langs = ['Abkhazian', 'Afar', 'Afrikaans', 'Akan', 'Albanian', 'Amharic', 'Arabic', 'Aragonese', 'Armenian', 'Assamese', 'Avaric', 'Avestan', 'Aymara', 'Azerbaijani', 'Bambara', 'Bashkir', 'Basque', 'Belarusian', 'Bengali', 'Bislama', 'Bosnian', 'Breton', 'Bulgarian', 'Burmese', 'Catalan, Valencian', 'Chamorro', 'Chechen', 'Chichewa, Chewa, Nyanja', 'Chinese', 'Church Slavonic, Old Slavonic, Old Church Slavonic', 'Chuvash', 'Cornish', 'Corsican', 'Cree', 'Croatian', 'Czech', 'Danish', 'Divehi, Dhivehi, Maldivian', 'Dutch, Flemish', 'Dzongkha', 'English', 'Esperanto', 'Estonian', 'Ewe', 'Faroese', 'Fijian', 'Finnish', 'French', 'Western Frisian', 'Fulah', 'Gaelic, Scottish Gaelic', 'Galician', 'Ganda', 'Georgian', 'German', 'Greek, Modern (1453–)', 'Kalaallisut, Greenlandic', 'Guarani', 'Gujarati', 'Haitian, Haitian Creole', 'Hausa', 'Hebrew', 'Herero', 'Hindi', 'Hiri Motu', 'Hungarian', 'Icelandic', 'Ido', 'Igbo', 'Indonesian', 'Interlingua (International Auxiliary Language Association)', 'Interlingue, Occidental', 'Inuktitut', 'Inupiaq', 'Irish', 'Italian', 'Japanese', 'Javanese', 'Kannada', 'Kanuri', 'Kashmiri', 'Kazakh', 'Central Khmer', 'Kikuyu, Gikuyu', 'Kinyarwanda', 'Kirghiz, Kyrgyz', 'Komi', 'Kongo', 'Korean', 'Kuanyama, Kwanyama', 'Kurdish', 'Lao', 'Latin', 'Latvian', 'Limburgan, Limburger, Limburgish', 'Lingala', 'Lithuanian', 'Luba-Katanga', 'Luxembourgish, Letzeburgesch', 'Macedonian', 'Malagasy', 'Malay', 'Malayalam', 'Maltese', 'Manx', 'Maori', 'Marathi', 'Marshallese', 'Mongolian', 'Nauru', 'Navajo, Navaho', 'North Ndebele', 'South Ndebele', 'Ndonga', 'Nepali', 'Norwegian', 'Norwegian Bokmål', 'Norwegian Nynorsk', 'Sichuan Yi, Nuosu', 'Occitan', 'Ojibwa', 'Oriya', 'Oromo', 'Ossetian, Ossetic', 'Pali', 'Pashto, Pushto', 'Persian', 'Polish', 'Portuguese', 'Punjabi, Panjabi', 'Quechua', 'Romanian, Moldavian, Moldovan', 'Romansh', 'Rundi', 'Russian', 'Northern Sami', 'Samoan', 'Sango', 'Sanskrit', 'Sardinian', 'Serbian', 'Shona', 'Sindhi', 'Sinhala, Sinhalese', 'Slovak', 'Slovenian', 'Somali', 'Southern Sotho', 'Spanish, Castilian', 'Sundanese', 'Swahili', 'Swati', 'Swedish', 'Tagalog', 'Tahitian', 'Tajik', 'Tamil', 'Tatar', 'Telugu', 'Thai', 'Tibetan', 'Tigrinya', 'Tonga (Tonga Islands)', 'Tsonga', 'Tswana', 'Turkish', 'Turkmen', 'Twi', 'Uighur, Uyghur', 'Ukrainian', 'Urdu', 'Uzbek', 'Venda', 'Vietnamese', 'Volapük', 'Walloon', 'Welsh', 'Wolof', 'Xhosa', 'Yiddish', 'Yoruba', 'Zhuang, Chuang', 'Zulu']
    
    lang_dict = {key : lan for (key, lan) in zip(keys, langs)}
    
    return lang_dict[detect(text)]

让我们试一试:

>>> get_language("Ich liebe meine Frau")

... 'German'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接