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

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个回答

374

1. TextBlob。 (已弃用 - 改用官方的Google翻译API)

需要NLTK软件包,使用Google。

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

pip install textblob

注意:此解决方案需要互联网访问,并且Textblob使用调用API使用Google翻译的语言检测器

2. Polyglot

需要numpy和一些神秘的库,不太可能在Windows上运行。(对于Windows,请从这里获取适当版本的PyICUMorfessorPyCLD2,然后只需pip install downloaded_wheel.whl。)能够检测到混合语言的文本。

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

安装依赖项,请运行: sudo apt-get install python-numpy libicu-dev

注意:Polyglot正在使用pycld2,有关详细信息,请参见https://github.com/aboSamoor/polyglot/blob/master/polyglot/detect/base.py#L72

3. chardet

如果字符字节在范围(127-255]内,则Chardet还具有检测语言的功能:

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

pip install chardet

4. langdetect

需要大量文本。它在幕后使用的是非确定性方法。

这意味着您会在相同的文本样本中获得不同的结果。文档说您必须使用以下代码来使其确定:

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

pip install langdetect

5. 猜测语言

可以使用这个拼写检查器和字典来检测非常短的样本。

pip install guess_language-spirit

6. langid

langid.py提供了一个模块

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

以及一个命令行工具:

$ langid < README.md

pip install langid

7. FastText

FastText是一个文本分类器,可以用来识别176种语言,并配备适当的语言分类模型。下载此模型,然后执行以下操作:

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

pycld3是用于语言识别的神经网络模型。该软件包包含推理代码和训练模型。

import cld3
cld3.get_language("影響包含對氣候的變化以及自然資源的枯竭程度")

LanguagePrediction(language='zh', probability=0.999969482421875, is_reliable=True, proportion=1.0)

pip install pycld3


7
detectlangTextblob 快得多。 - Anwarvic
11
TextBlob使用Google API(https://github.com/sloria/TextBlob/blob/dev/textblob/translate.py#L33),所以速度较慢。 - Thomas Decaux
11
我的用例中,“polyglot”表现最佳,“langid”排名第二。 - james-see
12
如果您只需要语言检测,实际上并不需要涉及整个Polyglot包。如文档中所述,检测由pyCLD2完成,这是一个非常简单易用的库。 - Jeyekomon
10
也可以使用[pyCLD3](https://github.com/bsolomon1124/pycld3)进行操作。 - tttthomasssss
显示剩余9条评论

82

你有看过langdetect吗?

from langdetect import detect

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

print lang
#output: de

44
准确性不太好 - 将"anatomical structure"这段文字的语言识别为ro(罗马尼亚语)。在这种情况下需要输出多种语言结果。polyglot表现得更好。 - Yuriy Petrovskiy
3
有趣的是,对于相同的例子,“langdetect”可以确定不同的语言 :-) - Denis Kuzin
1
由于某些原因,langdetect 出现了错误,我正在使用 Python 3.6。 - innuendo
@DenisKuzin 我只得到了“anatomical structure”的罗马尼亚语版本。不知道你能否分享一下你使用的langdetect版本? - famargar
2
不准确,将“上帝爱你”识别为克罗地亚语的hr。 - Jesus Boadas
如果在循环中操作langdetect,并且在循环之间不重置文本缓冲区,则其实是有问题的。https://github.com/Mimino666/langdetect/issues/77 - plunker

37

@Rabash在https://dev59.com/S1kT5IYBdhLWcg3wB7XP#47106810上列出了一些好用的工具。

而@toto_tico在展示速度比较方面也做得很好。

以下是对以上优秀回答的总结(截至2021年):

语言识别软件 使用者 开源/模型 基于规则 基于统计 可训练/调整
谷歌翻译语言检测 TextBlob (有限使用) - -
Chardet -
Guess Language (非活跃开发) spirit-guess (更新改写) 最小程度
pyCLD2 Polyglot 有些 不确定
CLD3 - 可能
langid-py - 不确定
langdetect SpaCy-langdetect
FastText What The Lang 不确定

2
谢谢您的回答,根据您的经验,哪种方法可以最准确且快速地检测出用英语写的句子呢? - sel

34

如果您正在寻找一种快速处理长文本的库,polyglotfastext在这方面做得最好。

我从一组混乱和随机的HTML中抽取了10000个文档,以下是结果:

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

我注意到很多方法都专注于短文本,这可能是因为这是一个难以解决的问题:如果你有很多文本,那么检测语言就非常容易(例如,可以使用字典!)。然而,这使得寻找适用于长文本的简单和合适的方法变得困难。


1
“polyglot” 语言检测基于 “pycld2”,总体来说速度不是很快。或者有没有一种方法可以使用它以批处理模式识别语言?我只尝试过逐句处理。 - Wiktor Stribiżew
我假设长文本是同一种语言。我读取了10000个文档并将它们保存在内存中。对于fastextcc,我必须删除\n字符,但对于polyglot则不需要(我也测试了cdl2结果几乎相同)。我不明白为什么你认为polyglot很慢,它是最快的。你认为我也应该删除\n,而我的结果只反映了第一句话(即第一个\n之前)吗? - toto_tico
1
我的意思是,我检查数百万个单行字符串文档的语言。使用pycld2检测速度很慢。 - Wiktor Stribiżew
在我的情况下,大多数文档都很长,而基准测试可能会因为短句子而有所不同。 - toto_tico
但是识别语言的成功率是多少呢?解析文本是一回事,得到正确的结果是另一回事。如果您使用cld3在14秒内将10k个文档解析错误,我宁愿等待4分钟并使用chardet。 - Andrea Moro
显示剩余2条评论

11

当使用 langdetect 进行并行处理时可能会出现问题,但是 spacy_langdetect 是一个针对此类问题的包装器,您可以用它来解决这个问题。您也可以使用以下代码片段:

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)

我按照你的答案操作了,但是我认为我仍然得到了与“langdetect”相同的速度。我有一个包含文本的DF列,我正在使用column.apply()和一个执行scipy_langdetect的函数。有什么建议吗? - Rishabh Sahrawat
你需要使用并行库来利用函数的并行化,例如dask,否则它不会有任何区别。 - Habib Karbasian
并行化存在什么问题? - stan0
我不记得具体是什么问题,但当我想要在dask并行化中使用langdetect库时,它抛出了一个异常,但是spacy_langdetect却可以正常工作。 - Habib Karbasian

9

你可以使用Googletrans(非官方)作为Python的免费且无限制的Google翻译API。

你可以随意发出请求,没有任何限制。

安装:

$ pip install googletrans

语言检测:

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

2
这个方法很棒,但我已经商业化地实施了它,不稳定性是因为在1-5K转换后需要更改IP地址。通过使用代理列表或在代码中每100次转换自动更改VPN,可以使此接口变得有用。希望这能帮助任何一个试图实现它的人。 :) - Muneeb Ahmad Khurram

3

我会毫不犹豫地选择 lingua.py。它比 fasttext 更快、更准确。绝对值得在这里列出。

安装

poety add lingua-language-detector

使用方法

from typing import List
from lingua.language import Language
from lingua.builder import LanguageDetectorBuilder
languages: List[Language] = [Language.ENGLISH, Language.TURKISH, Language.PERSIAN]
detector = LanguageDetectorBuilder.from_languages(*languages).build()

if __name__ == "__main__":
    print(detector.detect_language_of("Ben de iyiyim. Tesekkurler.")) # Language.TURKISH
    print(detector.detect_language_of("I'm fine and you?")) # Language.ENGLISH
    print(detector.detect_language_of("حال من خوبه؟ شما چطورید؟")) # Language.PERSIAN

我尝试了detect_language_of方法,但对我来说,它是所有之前选项中最慢的。 - undefined

2

预训练的Fast Text模型最适合我的类似需求

我有一个与你非常相似的需求,Rabash的答案对我的特定需求提供了最大的帮助。

在尝试他的建议中找到最佳方案后,我发现fasttext是这个任务的一个绝佳工具。只需要确保文本文件为英语,并且有60,000多个文本文件。

稍加修改,我就得到了一个可以快速处理多个文件的工具。但是它也可以轻松地针对像您的情况这样的需求进行修改,因为fasttext可以轻松地处理一系列行。

我的代码及注释已经在帖子的答案中。我相信您和其他人可以轻松地将此代码修改为其他特定需求。


2

我喜欢TextBlob提供的语言检测方法。这种方法非常简单易实现,使用的代码行数也比较少。在开始之前,您需要安装textblob Python库才能运行下面的代码。

from textblob import TextBlob
text = "это компьютерный портал для гиков."
lang = TextBlob(text)
print(lang.detect_language())

另一方面,如果你使用多种语言的组合,你可能需要尝试使用pycld2来通过准确定义句子或段落的部分进行语言检测。


2

Polygot或Cld2是最佳建议之一,因为它们可以检测文本中的多种语言。但由于“构建轮失败”,它们在Windows上安装起来并不容易。

对我有效的解决方案(我正在使用Windows 10)是安装CLD2-CFFI

所以首先安装cld2-cffi。

pip install cld2-cffi

然后像这样使用它:

text_content = """ 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. 
Welcome, to this world of Data Scientist. Today is a lovely day."""

import cld2

isReliable, textBytesFound, details = cld2.detect(text_content)
print('  reliable: %s' % (isReliable != 0))
print('  textBytes: %s' % textBytesFound)
print('  details: %s' % str(details))

输出结果如下:
reliable: True
textBytes: 377
details: (Detection(language_name='FRENCH', language_code='fr', percent=74, 
score=1360.0), Detection(language_name='ENGLISH', language_code='en', 
percent=25, score=1141.0), Detection(language_name='Unknown', 
language_code='un', percent=0, score=0.0))

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