它的任务很简单:它告诉您有些提供的文本数据写在哪种语言中。这是自然语言处理应用程序(例如文本分类和拼写检查)中语言数据的预处理步骤非常有用的。例如,其他用例可能包括基于电子邮件的语言将电子邮件路由到正确的地理位置客户服务部门。
语言检测通常是大型机器学习框架或自然语言处理应用程序的一部分。如果您不需要这些系统的全面功能或不想学习这些系统的绳索,那么一个小的灵活库就派上用场了。
到目前为止,在JVM上工作的其他三个全面的开源库是Apache Tika,Apache OpenNLP和Optimaize语言检测器。不幸的是,尤其是后者有三个主要缺点:
通用旨在消除这些问题。它几乎不需要任何配置,即使在单个单词和短语上,也可以在长文本和短文本上产生相当准确的结果。它借鉴了基于规则的和统计方法,但不使用任何单词字典。它也不需要与任何外部API或服务的连接。库下载后,可以完全离线使用。
与其他语言检测库相比,通用库的重点是质量而不是数量,也就是说,在添加新语言之前,首先要为一小部分语言进行检测。目前,支持以下75种语言:
通用语言能够为每种受支持的语言可用的一些捆绑测试数据报告准确性统计信息。每种语言的测试数据分为三个部分:
语言模型和测试数据都是从德国莱比锡大学提供的磨砂机构的单独文档创建的。来自各种新闻网站的数据已被用于培训,每个语料库包括一百万个句子。为了进行测试,已经使用了任意选择的网站的语料库,每个网站包括一万个句子。从每个测试语料库中,分别提取了1000个单词,1000个单词和1000个句子的随机未分类子集。
鉴于生成的测试数据,我使用参数化的JUNIT测试在Lingua支持的75种语言的数据上运行的参数化JUNIT测试,比较了语言, Apache Tika , Apache OpenNLP的检测结果。在检测过程中,其他图书馆不支持的语言被简单地忽略了。
以下每个部分都包含两个图。条图显示了每种受支持语言的详细准确性结果。框图说明了每个分类器的精度值的分布。盒子本身代表了中间数据中的50%所在的区域。在彩色框中,水平线标记了分布的中位数。
下表显示了每种语言和分类器的详细统计信息,包括均值,中值和标准偏差。
| 语言 | 平均的 | 单词 | 单词对 | 句子 | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 语言 (高精度模式) | 语言 (精确模式低) | 蒂卡 | OpenNLP | 优化 | 语言 (高精度模式) | 语言 (精确模式低) | 蒂卡 | OpenNLP | 优化 | 语言 (高精度模式) | 语言 (精确模式低) | 蒂卡 | OpenNLP | 优化 | 语言 (高精度模式) | 语言 (精确模式低) | 蒂卡 | OpenNLP | 优化 | |
| 南非荷兰语 | 79 | 64 | 71 | 72 | 39 | 58 | 38 | 44 | 41 | 3 | 81 | 62 | 70 | 75 | 22 | 97 | 93 | 98 | 99 | 93 |
| 阿尔巴尼亚人 | 88 | 80 | 79 | 71 | 70 | 69 | 54 | 54 | 40 | 38 | 95 | 86 | 84 | 73 | 73 | 100 | 99 | 99 | 100 | 98 |
| 阿拉伯 | 98 | 94 | 97 | 84 | 89 | 96 | 88 | 94 | 65 | 72 | 99 | 96 | 99 | 88 | 94 | 100 | 99 | 100 | 99 | 100 |
| 亚美尼亚人 | 100 | 100 | - | 100 | - | 100 | 100 | - | 100 | - | 100 | 100 | - | 100 | - | 100 | 100 | - | 100 | - |
| 阿塞拜疆 | 90 | 82 | - | 82 | - | 77 | 71 | - | 60 | - | 92 | 78 | - | 86 | - | 99 | 96 | - | 99 | - |
| 巴斯克 | 84 | 74 | 83 | 77 | 66 | 71 | 56 | 64 | 56 | 33 | 87 | 76 | 86 | 82 | 70 | 93 | 91 | 98 | 92 | 95 |
| 白俄罗斯人 | 97 | 92 | 96 | 91 | 87 | 92 | 80 | 92 | 78 | 69 | 99 | 95 | 98 | 95 | 92 | 100 | 100 | 100 | 100 | 99 |
| 孟加拉 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| 博克马尔 | 58 | 49 | - | 66 | - | 39 | 27 | - | 42 | - | 59 | 47 | - | 69 | - | 75 | 74 | - | 87 | - |
| 波斯尼亚 | 35 | 29 | - | 26 | - | 29 | 23 | - | 12 | - | 35 | 29 | - | 22 | - | 40 | 36 | - | 44 | - |
| 保加利亚语 | 87 | 78 | 73 | 83 | 48 | 70 | 56 | 52 | 62 | 18 | 91 | 81 | 69 | 87 | 36 | 99 | 96 | 96 | 100 | 91 |
| 加泰罗尼亚 | 70 | 58 | 58 | 42 | 31 | 51 | 33 | 32 | 11 | 2 | 74 | 60 | 57 | 32 | 16 | 86 | 81 | 84 | 81 | 77 |
| 中国人 | 100 | 100 | 69 | 78 | 31 | 100 | 100 | 20 | 40 | 0 | 100 | 100 | 86 | 94 | 2 | 100 | 100 | 100 | 100 | 91 |
| 克罗地亚人 | 72 | 60 | 74 | 50 | 41 | 53 | 36 | 54 | 23 | 8 | 74 | 57 | 72 | 44 | 24 | 90 | 85 | 97 | 81 | 91 |
| 捷克 | 80 | 71 | 72 | 67 | 49 | 66 | 54 | 54 | 42 | 21 | 84 | 72 | 75 | 70 | 46 | 91 | 87 | 88 | 90 | 81 |
| 丹麦语 | 81 | 70 | 83 | 60 | 55 | 61 | 45 | 63 | 34 | 19 | 84 | 70 | 86 | 52 | 51 | 98 | 95 | 99 | 94 | 96 |
| 荷兰 | 77 | 64 | 60 | 61 | 39 | 55 | 36 | 31 | 31 | 6 | 81 | 61 | 52 | 57 | 19 | 96 | 94 | 98 | 97 | 91 |
| 英语 | 81 | 62 | 64 | 52 | 41 | 55 | 29 | 30 | 10 | 2 | 89 | 62 | 62 | 46 | 23 | 99 | 96 | 99 | 99 | 97 |
| 世界语 | 84 | 66 | - | 76 | - | 67 | 44 | - | 50 | - | 85 | 61 | - | 78 | - | 98 | 92 | - | 100 | - |
| 爱沙尼亚人 | 92 | 83 | 84 | 59 | 61 | 80 | 62 | 66 | 29 | 23 | 96 | 88 | 88 | 60 | 63 | 100 | 99 | 100 | 88 | 98 |
| 芬兰 | 96 | 91 | 94 | 86 | 79 | 90 | 77 | 86 | 68 | 51 | 98 | 95 | 96 | 91 | 86 | 100 | 100 | 100 | 100 | 100 |
| 法语 | 89 | 77 | 78 | 59 | 54 | 74 | 52 | 55 | 25 | 18 | 94 | 83 | 80 | 55 | 48 | 99 | 97 | 99 | 98 | 97 |
| 甘达 | 91 | 84 | - | - | - | 79 | 65 | - | - | - | 95 | 87 | - | - | - | 100 | 100 | - | - | - |
| 格鲁吉亚人 | 100 | 100 | - | 100 | - | 100 | 100 | - | 100 | - | 100 | 100 | - | 100 | - | 100 | 100 | - | 100 | - |
| 德语 | 89 | 80 | 74 | 67 | 55 | 74 | 57 | 50 | 38 | 21 | 94 | 84 | 71 | 66 | 46 | 100 | 99 | 100 | 98 | 99 |
| 希腊语 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| 古吉拉特语 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| 希伯来语 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| 印地语 | 73 | 33 | 80 | 58 | 51 | 61 | 11 | 65 | 28 | 16 | 64 | 20 | 75 | 49 | 38 | 93 | 67 | 99 | 99 | 98 |
| 匈牙利 | 95 | 90 | 88 | 78 | 77 | 87 | 77 | 75 | 53 | 51 | 98 | 94 | 91 | 82 | 82 | 100 | 100 | 100 | 100 | 99 |
| 冰岛 | 93 | 88 | 90 | 76 | 78 | 83 | 72 | 76 | 53 | 53 | 97 | 92 | 94 | 76 | 82 | 100 | 99 | 100 | 99 | 99 |
| 印度尼西亚 | 60 | 48 | 60 | 29 | 18 | 39 | 25 | 37 | 10 | 0 | 61 | 46 | 62 | 25 | 1 | 81 | 72 | 82 | 52 | 54 |
| 爱尔兰人 | 91 | 85 | 90 | 78 | 80 | 82 | 70 | 80 | 56 | 58 | 94 | 90 | 92 | 82 | 85 | 96 | 95 | 99 | 97 | 98 |
| 意大利人 | 87 | 71 | 80 | 64 | 51 | 69 | 42 | 58 | 31 | 12 | 92 | 74 | 84 | 61 | 43 | 100 | 98 | 99 | 100 | 98 |
| 日本人 | 100 | 100 | 25 | 95 | 98 | 100 | 100 | 1 | 87 | 99 | 100 | 100 | 5 | 100 | 100 | 100 | 100 | 68 | 100 | 96 |
| 哈萨克 | 92 | 90 | - | 85 | - | 80 | 78 | - | 66 | - | 96 | 93 | - | 90 | - | 99 | 99 | - | 100 | - |
| 韩国人 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| 拉丁 | 87 | 73 | - | 70 | - | 72 | 49 | - | 43 | - | 93 | 76 | - | 71 | - | 97 | 93 | - | 96 | - |
| 拉脱维亚 | 93 | 87 | 90 | 86 | 78 | 85 | 75 | 78 | 72 | 56 | 97 | 90 | 93 | 88 | 82 | 99 | 97 | 98 | 98 | 97 |
| 立陶宛语 | 95 | 87 | 89 | 79 | 72 | 86 | 76 | 74 | 56 | 40 | 98 | 89 | 92 | 83 | 77 | 100 | 98 | 99 | 99 | 98 |
| 马其顿 | 84 | 72 | 83 | 68 | 46 | 66 | 52 | 66 | 37 | 10 | 86 | 70 | 83 | 68 | 32 | 99 | 95 | 100 | 98 | 97 |
| 马来语 | 31 | 31 | 23 | 19 | 4 | 26 | 22 | 19 | 10 | 0 | 38 | 36 | 22 | 20 | 0 | 30 | 36 | 28 | 27 | 11 |
| 毛利人 | 92 | 83 | - | 92 | - | 84 | 64 | - | 85 | - | 92 | 88 | - | 90 | - | 99 | 98 | - | 100 | - |
| 马拉地语 | 85 | 41 | 90 | 81 | 71 | 74 | 20 | 81 | 62 | 43 | 85 | 30 | 92 | 83 | 74 | 96 | 72 | 98 | 98 | 96 |
| 蒙 | 97 | 96 | - | 84 | - | 93 | 89 | - | 66 | - | 99 | 98 | - | 88 | - | 99 | 99 | - | 99 | - |
| Nynorsk | 66 | 52 | - | 55 | - | 41 | 25 | - | 24 | - | 66 | 49 | - | 47 | - | 90 | 81 | - | 92 | - |
| 波斯语 | 90 | 80 | 81 | 75 | 62 | 78 | 62 | 65 | 53 | 29 | 94 | 80 | 79 | 74 | 58 | 100 | 98 | 99 | 99 | 99 |
| 抛光 | 95 | 90 | 90 | 83 | 81 | 85 | 77 | 76 | 61 | 57 | 98 | 93 | 93 | 89 | 86 | 100 | 99 | 100 | 100 | 100 |
| 葡萄牙语 | 81 | 69 | 63 | 58 | 40 | 59 | 42 | 34 | 22 | 7 | 85 | 70 | 58 | 54 | 19 | 98 | 95 | 98 | 98 | 94 |
| 旁遮普 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| 罗马尼亚人 | 87 | 72 | 78 | 67 | 55 | 69 | 49 | 57 | 34 | 24 | 92 | 74 | 80 | 68 | 50 | 99 | 94 | 97 | 99 | 91 |
| 俄语 | 90 | 78 | 80 | 50 | 53 | 76 | 59 | 62 | 20 | 22 | 95 | 84 | 85 | 43 | 50 | 98 | 92 | 94 | 86 | 87 |
| 塞尔维亚 | 88 | 78 | 73 | 73 | 46 | 74 | 62 | 57 | 46 | 18 | 90 | 80 | 70 | 74 | 39 | 99 | 91 | 90 | 98 | 80 |
| 肖纳 | 91 | 81 | - | - | - | 78 | 56 | - | - | - | 96 | 86 | - | - | - | 100 | 100 | - | - | - |
| 斯洛伐克 | 84 | 75 | 76 | 70 | 47 | 64 | 49 | 53 | 39 | 12 | 90 | 78 | 76 | 73 | 38 | 99 | 97 | 98 | 99 | 92 |
| 斯洛文尼亚 | 82 | 67 | 74 | 71 | 37 | 61 | 39 | 53 | 43 | 3 | 87 | 68 | 72 | 72 | 18 | 99 | 93 | 98 | 99 | 90 |
| 索马里 | 92 | 85 | 91 | 69 | 79 | 82 | 64 | 78 | 35 | 50 | 96 | 90 | 94 | 74 | 88 | 100 | 100 | 100 | 98 | 100 |
| 索托 | 85 | 72 | - | - | - | 67 | 43 | - | - | - | 90 | 75 | - | - | - | 99 | 97 | - | - | - |
| 西班牙语 | 70 | 56 | 59 | 42 | 32 | 44 | 26 | 29 | 8 | 0 | 69 | 49 | 50 | 25 | 6 | 97 | 94 | 97 | 93 | 91 |
| 斯瓦希里语 | 81 | 70 | 75 | 73 | 60 | 60 | 43 | 50 | 45 | 26 | 84 | 68 | 75 | 74 | 58 | 98 | 97 | 99 | 99 | 98 |
| 瑞典 | 84 | 72 | 71 | 69 | 50 | 64 | 46 | 44 | 41 | 15 | 88 | 76 | 72 | 69 | 42 | 99 | 95 | 97 | 97 | 94 |
| 他加禄语 | 78 | 66 | 77 | 61 | 61 | 52 | 36 | 53 | 27 | 23 | 83 | 67 | 79 | 57 | 62 | 99 | 96 | 99 | 98 | 97 |
| 泰米尔人 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| 泰卢固语 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| 泰国 | 99 | 99 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 98 | 98 | 100 | 99 | 100 |
| Tsonga | 84 | 72 | - | - | - | 66 | 46 | - | - | - | 89 | 73 | - | - | - | 98 | 97 | - | - | - |
| TSWANA | 84 | 71 | - | - | - | 65 | 44 | - | - | - | 88 | 73 | - | - | - | 99 | 96 | - | - | - |
| 土耳其 | 94 | 87 | 81 | 72 | 70 | 84 | 71 | 62 | 48 | 43 | 98 | 91 | 83 | 71 | 70 | 100 | 99 | 99 | 98 | 96 |
| 乌克兰 | 92 | 86 | 81 | 79 | 68 | 84 | 75 | 62 | 54 | 39 | 97 | 92 | 84 | 83 | 69 | 95 | 93 | 97 | 99 | 94 |
| 乌尔都语 | 91 | 80 | 83 | 68 | 72 | 80 | 65 | 68 | 45 | 49 | 94 | 78 | 84 | 62 | 71 | 98 | 96 | 96 | 98 | 96 |
| 越南人 | 91 | 87 | 85 | 84 | 87 | 79 | 76 | 63 | 66 | 65 | 94 | 87 | 92 | 86 | 95 | 99 | 98 | 100 | 100 | 100 |
| 威尔士语 | 91 | 82 | 85 | 77 | 77 | 78 | 61 | 68 | 50 | 50 | 96 | 87 | 88 | 81 | 82 | 99 | 99 | 100 | 99 | 99 |
| xhosa | 82 | 69 | - | - | - | 64 | 45 | - | - | - | 85 | 67 | - | - | - | 98 | 94 | - | - | - |
| 约鲁巴 | 75 | 62 | - | - | - | 50 | 33 | - | - | - | 77 | 61 | - | - | - | 97 | 93 | - | - | - |
| 祖鲁 | 81 | 70 | - | 78 | - | 62 | 45 | - | 51 | - | 83 | 72 | - | 82 | - | 97 | 94 | - | 100 | - |
| 意思是 | 86 | 77 | 80 | 74 | 65 | 74 | 61 | 64 | 53 | 41 | 89 | 78 | 81 | 74 | 61 | 96 | 93 | 96 | 95 | 93 |
| 中位数 | 89.23 | 79.63 | 81.3 | 75.55 | 63.85 | 74.3 | 56.7 | 63.39 | 48.7 | 30.75 | 93.7 | 80.6 | 84.25 | 75.55 | 65.95 | 99.0 | 96.9 | 99.15 | 99.0 | 97.4 |
| 标准偏差 | 13.12 | 17.26 | 16.2 | 18.56 | 23.87 | 18.43 | 24.81 | 23.9 | 27.37 | 33.87 | 13.13 | 18.96 | 18.74 | 21.32 | 31.32 | 11.02 | 11.86 | 10.77 | 12.59 | 13.54 |
每个语言检测器都使用对某些培训语料库中字符分布训练的概率N-Gram模型。大多数库仅使用尺寸3的n-grams(Trigrams),这对于检测由多个句子组成的较长文本片段的语言令人满意。但是,对于简短的短语或单词,Trigram还不够。输入文本越短,n-gram的可用性越少。从如此少数的n-gram估计的概率是不可靠的。这就是为什么语言利用尺寸1最多5的n-grams的原因,从而可以更准确地预测正确的语言。
第二个重要区别是语言不仅使用这种统计模型,还使用基于规则的引擎。该引擎首先确定输入文本的字母,并搜索一种或多种语言独特的字符。如果完全可以可靠地选择一种语言,则不再需要统计模型。无论如何,基于规则的引擎会过滤出不满足输入文本条件的语言。仅在第二步中,考虑了概率的n-gram模型。这是有道理的,因为加载更少的语言模型意味着更少的内存消耗和更好的运行时性能。
通常,最好使用相应的API方法限制在分类过程中考虑要考虑的语言集。如果您事先知道某些语言永远不会在输入文本中出现,请不要让这些语言参加分类过程。基于规则的引擎的过滤机制非常好,但是,根据您对输入文本的了解,过滤总是最好的。
如果要复制上述准确性结果,则可以通过以下方式为所有四个分类器和所有语言生成测试报告:
./gradlew accuracyReport
您还可以通过将参数传递给Gradle任务来限制分类器和语言来生成报告。以下任务仅生成语言的报告和英语和德语的语言:
./gradlew accuracyReport -Pdetectors=Lingua -Planguages=English,German
默认情况下,仅使用单个CPU核心进行报告生成。如果您的计算机中有多核CPU,则可以与CPU内核一样多。这加快了报告的生成。但是,请注意,分叉多个过程可以消耗大量RAM。你这样做:
./gradlew accuracyReport -PcpuCores=2
对于每个检测器和语言,然后将测试报告文件写入/accuracy-reports中,将在src目录旁边找到。例如,这是德语报告的当前输出:
##### GERMAN #####
Legend: 'low accuracy mode | high accuracy mode'
>>> Accuracy on average: 79.80% | 89.23%
>> Detection of 1000 single words (average length: 9 chars)
Accuracy: 56.70% | 73.90%
Erroneously classified as DUTCH: 2.80% | 2.30%, DANISH: 2.20% | 2.10%, ENGLISH: 1.90% | 2.00%, LATIN: 1.90% | 1.90%, BOKMAL: 2.40% | 1.60%, BASQUE: 1.60% | 1.20%, ITALIAN: 1.00% | 1.20%, FRENCH: 1.60% | 1.20%, ESPERANTO: 1.10% | 1.10%, SWEDISH: 3.20% | 1.00%, AFRIKAANS: 1.30% | 0.80%, TSONGA: 1.50% | 0.70%, NYNORSK: 1.40% | 0.60%, PORTUGUESE: 0.50% | 0.60%, YORUBA: 0.40% | 0.60%, SOTHO: 0.70% | 0.50%, FINNISH: 0.80% | 0.50%, WELSH: 1.30% | 0.50%, SPANISH: 1.20% | 0.40%, SWAHILI: 0.60% | 0.40%, TSWANA: 2.20% | 0.40%, POLISH: 0.70% | 0.40%, ESTONIAN: 0.90% | 0.40%, IRISH: 0.50% | 0.40%, TAGALOG: 0.10% | 0.30%, ICELANDIC: 0.30% | 0.30%, BOSNIAN: 0.10% | 0.30%, LITHUANIAN: 0.80% | 0.20%, MAORI: 0.50% | 0.20%, INDONESIAN: 0.40% | 0.20%, ALBANIAN: 0.60% | 0.20%, CATALAN: 0.70% | 0.20%, ZULU: 0.30% | 0.20%, ROMANIAN: 1.20% | 0.20%, CROATIAN: 0.10% | 0.20%, XHOSA: 0.40% | 0.20%, TURKISH: 0.70% | 0.10%, MALAY: 0.50% | 0.10%, LATVIAN: 0.40% | 0.10%, SLOVENE: 0.00% | 0.10%, SLOVAK: 0.30% | 0.10%, SOMALI: 0.00% | 0.10%, HUNGARIAN: 0.40% | 0.00%, SHONA: 0.80% | 0.00%, VIETNAMESE: 0.40% | 0.00%, CZECH: 0.30% | 0.00%, GANDA: 0.20% | 0.00%, AZERBAIJANI: 0.10% | 0.00%
>> Detection of 1000 word pairs (average length: 18 chars)
Accuracy: 83.50% | 94.10%
Erroneously classified as DUTCH: 1.50% | 0.90%, LATIN: 1.00% | 0.80%, ENGLISH: 1.40% | 0.70%, SWEDISH: 1.40% | 0.60%, DANISH: 1.20% | 0.50%, FRENCH: 0.60% | 0.40%, BOKMAL: 1.40% | 0.30%, TAGALOG: 0.10% | 0.20%, IRISH: 0.20% | 0.20%, TURKISH: 0.10% | 0.10%, NYNORSK: 0.90% | 0.10%, TSONGA: 0.40% | 0.10%, ZULU: 0.10% | 0.10%, ESPERANTO: 0.30% | 0.10%, AFRIKAANS: 0.60% | 0.10%, ITALIAN: 0.10% | 0.10%, ESTONIAN: 0.30% | 0.10%, FINNISH: 0.40% | 0.10%, SOMALI: 0.00% | 0.10%, SWAHILI: 0.20% | 0.10%, MAORI: 0.00% | 0.10%, WELSH: 0.10% | 0.10%, LITHUANIAN: 0.40% | 0.00%, INDONESIAN: 0.10% | 0.00%, CATALAN: 0.30% | 0.00%, LATVIAN: 0.20% | 0.00%, XHOSA: 0.30% | 0.00%, SPANISH: 0.50% | 0.00%, MALAY: 0.10% | 0.00%, SLOVAK: 0.10% | 0.00%, BASQUE: 0.40% | 0.00%, YORUBA: 0.20% | 0.00%, TSWANA: 0.30% | 0.00%, SHONA: 0.10% | 0.00%, PORTUGUESE: 0.10% | 0.00%, SOTHO: 0.30% | 0.00%, CZECH: 0.10% | 0.00%, ALBANIAN: 0.40% | 0.00%, AZERBAIJANI: 0.10% | 0.00%, ICELANDIC: 0.10% | 0.00%, SLOVENE: 0.10% | 0.00%
>> Detection of 1000 sentences (average length: 111 chars)
Accuracy: 99.20% | 99.70%
Erroneously classified as DUTCH: 0.00% | 0.20%, LATIN: 0.20% | 0.10%, NYNORSK: 0.10% | 0.00%, SPANISH: 0.10% | 0.00%, DANISH: 0.10% | 0.00%, SOTHO: 0.20% | 0.00%, ZULU: 0.10% | 0.00%
语言托管在GitHub包装和Maven Central上。
// Groovy syntax
implementation 'com.github.pemistahl:lingua:1.2.2'
// Kotlin syntax
implementation("com.github.pemistahl:lingua:1.2.2")
<dependency>
<groupId>com.github.pemistahl</groupId>
<artifactId>lingua</artifactId>
<version>1.2.2</version>
</dependency>
语言使用gradle来构建,并需要Java> = 1.8。
git clone https://github.com/pemistahl/lingua.git
cd lingua
./gradlew build
可以从项目中创建几个JAR档案。
./gradlew jar组装lingua-1.2.2.jar仅包含编译的来源。./gradlew sourcesJar组装lingua-1.2.2-sources.jar包含普通源代码。./gradlew jarWithDependencies组装lingua-1.2.2-with-dependencies.jar包含运行时所需的编译源和所有外部依赖关系。该JAR文件可以包含在没有依赖性管理系统的项目中。它也可用于以独立模式运行通用语言(见下文)。 语言可以在您自己的代码或独立模式下以编程方式使用。
API非常简单,可以在Kotlin和Java代码中使用。
/* Kotlin */
import com.github.pemistahl.lingua.api.*
import com.github.pemistahl.lingua.api.Language.*
val detector : LanguageDetector = LanguageDetectorBuilder .fromLanguages( ENGLISH , FRENCH , GERMAN , SPANISH ).build()
val detectedLanguage : Language = detector.detectLanguageOf(text = " languages are awesome " )语言的公共API永远不会在某处返回null ,因此也可以在Java代码中使用。
/* Java */
import com . github . pemistahl . lingua . api .*;
import static com . github . pemistahl . lingua . api . Language .*;
final LanguageDetector detector = LanguageDetectorBuilder . fromLanguages ( ENGLISH , FRENCH , GERMAN , SPANISH ). build ();
final Language detectedLanguage = detector . detectLanguageOf ( "languages are awesome" );默认情况下,语言返回给定输入文本的最可能的语言。但是,某些单词在多种语言中拼写相同。例如, Prologue一词既是有效的英语和法语单词。语言将输出英语或法语,这在给定的情况下可能是错误的。对于这样的情况,可以指定对数化的最小相对距离,并概括了每种可能的语言必须满足的概率。可以通过以下方式说明:
val detector = LanguageDetectorBuilder
.fromAllLanguages()
.withMinimumRelativeDistance( 0.25 ) // minimum: 0.00 maximum: 0.99 default: 0.00
.build()请注意,语言概率之间的距离取决于输入文本的长度。输入文本越长,语言之间的距离就越大。因此,如果您想对非常短的文本短语进行分类,请不要将最小相对距离设置为太高。否则,您将获得大多数结果为Language.UNKNOWN ,这是语言检测不太可能可靠的情况的返回值。
了解最可能的语言很不错,但是计算的可能性有多可靠?与最可能的语言相比,其他研究的语言的可能性较小?这些问题也可以回答:
val detector = LanguageDetectorBuilder .fromLanguages( GERMAN , ENGLISH , FRENCH , SPANISH ).build()
val confidenceValues = detector.computeLanguageConfidenceValues(text = " Coding is fun. " )
// {
// ENGLISH=1.0,
// GERMAN=0.8665738136456169,
// FRENCH=0.8249537317466078,
// SPANISH=0.7792362923625288
// }在上面的示例中,返回了所有可能的语言的地图,并按照其降序顺序的信心价值进行排序。检测器计算的值是相对置信度度量的一部分,而不是绝对置信度度量。每个值的数量为0.0至1.0。最有可能的语言总是以值1.0返回。所有其他语言都获得低于1.0的值的值,表示这些语言与最可能的语言相比的可能性较小。
该方法返回的地图不一定包含构建LanguageDetector呼叫实例的所有语言。如果基于规则的引擎决定确实是不可能的,那么它将不会成为返回的地图的一部分。同样,如果在给定输入文本的检测器语言中找不到NGRAM概率,则返回的映射将为空。假定每种语言的置信值为不属于返回的地图的一部分为0.0。
默认情况下,语言仅使用懒惰加载来按需加载这些语言模型,这些模型被基于规则的滤波器引擎认为相关。例如,对于Web服务,将所有语言模型预加载到内存是相当有益的,以避免在等待服务响应时出乎意料的延迟。如果要启用急切的加载模式,则可以这样做:
LanguageDetectorBuilder .fromAllLanguages().withPreloadedLanguageModels().build() LanguageDetector的多个实例在内存中共享相同的语言模型,这些模型可通过实例异步访问。
语言的高检测准确性是比其他语言探测器明显慢的成本。大语言模型还消耗了大量的记忆。对于资源低下的系统,这些要求可能是不可行的。如果您想将大部分文本分类或需要节省资源,则可以启用低精度模式,该模式仅将一小部分语言模型加载到内存中:
LanguageDetectorBuilder .fromAllLanguages().withLowAccuracyMode().build()这种方法的缺点是,由少于120个字符组成的短文本的检测准确性将大大下降。但是,超过120个字符的文本的检测准确性将主要不受影响。
较小的内存足迹和更快的性能的替代方法是减少构建语言检测器时的语言集。在大多数情况下,不建议从所有受支持的语言中构建检测器。当您了解要分类的文本时,几乎总是可以将某些语言排除为不可能或不可能发生的语言。
可能会有一些分类任务,您事先知道您的语言数据绝对不是用拉丁语编写的(真是一个惊喜:-)。如果您将某些语言排除在决策过程中,或者只是明确包含相关语言,则检测准确性可以变得更好。
// include all languages available in the library
// WARNING: in the worst case this produces high memory
// consumption of approximately 3.5GB
// and slow runtime performance
// (in high accuracy mode)
LanguageDetectorBuilder .fromAllLanguages()
// include only languages that are not yet extinct (= currently excludes Latin)
LanguageDetectorBuilder .fromAllSpokenLanguages()
// include only languages written with Cyrillic script
LanguageDetectorBuilder .fromAllLanguagesWithCyrillicScript()
// exclude only the Spanish language from the decision algorithm
LanguageDetectorBuilder .fromAllLanguagesWithout( Language . SPANISH )
// only decide between English and German
LanguageDetectorBuilder .fromLanguages( Language . ENGLISH , Language . GERMAN )
// select languages by ISO 639-1 code
LanguageDetectorBuilder .fromIsoCodes639_1( IsoCode639_1 . EN , IsoCode639_3 . DE )
// select languages by ISO 639-3 code
LanguageDetectorBuilder .fromIsoCodes639_3( IsoCode639_3 . ENG , IsoCode639_3 . DEU )语言在内部有效地使用CPU的所有内核,以加快语言模型和语言检测本身的加速。为此,使用了内部forkjoinpool。如果在应用程序服务器中使用了库,则当应用程序未剥削时,将不会自动释放所消耗的内存。
如果您想释放通用的所有资源,则必须在不放弃期间通过调用detector.unloadLanguageModels()手动执行此操作。这将从内存中清除所有已加载的语言模型,但线程池将继续运行。
如果您想在决定是否使用它之前尝试使用通用语言,则可以在repl中运行它,并立即查看其检测结果。
./gradlew runLinguaOnConsole --console=plainjava -jar lingua-1.2.2-with-dependencies.jar然后玩:
This is Lingua.
Select the language models to load.
1: enter language iso codes manually
2: all supported languages
Type a number and press <Enter>.
Type :quit to exit.
> 1
List some language iso 639-1 codes separated by spaces and press <Enter>.
Type :quit to exit.
> en fr de es
Loading language models...
Done. 4 language models loaded lazily.
Type some text and press <Enter> to detect its language.
Type :quit to exit.
> languages
ENGLISH
> Sprachen
GERMAN
> langues
FRENCH
> :quit
Bye! Ciao! Tschüss! Salut!
如果您想为语言做出贡献,那么鼓励您这样做。您有改善API的想法吗?您是否想早日支持一些特定的语言?还是到目前为止发现了任何错误?随时打开问题或发送拉请请求。非常感谢。
对于拉的请求,请确保所有单元测试通过,并且根据Kotlin官方样式指南对代码进行格式。您可以使用./gradlew ktlintCheck运行Kotlin Linter ktlint来检查这一点。 Linter识别的大多数问题都可以通过运行./gradlew ktlintFormat解决。所有其他问题,尤其是超过120个字符的行,无法自动修复。在这种情况下,请手工格式化各自的行。您会注意到,如果格式不正确,则构建将失败。
欢迎各种拉动请求。最喜欢的是新语言。如果您想为语言贡献新的语言,这里有一本详细的手册,解释了如何实现这一目标。
非常感谢您的所有贡献,无论它们还是很小。
为了执行以下步骤,您将需要Java 8或更高。即使库本身在Java> = 6上运行, FilesWriter类也使用Java.nio API,该api是用Java 8介绍的。
IsoCode639_1和IsoCode639_3 ,并添加语言的ISO代码。在其他站点中,维基百科提供了全面的清单。Language ,并为您的语言添加新条目。如果该语言是用语言的Alphabet枚举尚未支持的脚本编写的,请在其中添加一个新的条目。Language枚举中的各个条目中。但是,如果字符以一种以上的语言出现,但没有以所有语言出现,请将它们添加到类CHARS_TO_LANGUAGES_MAPPING Constand中的Chars_to_to_languages_mapping Constant中。LanguageModelFilesWriter创建语言模型文件。除了成为有效的TXT文件之外,不需要用于NGRAM概率估计的训练数据文件。/src/main/resources/language-models中创建一个新的子目录,然后将生成的语言模型文件放入其中。不要重命名语言模型文件。子目录的名称必须是该语言的ISO 639-1代码,完全下降。TestDataFilesWriter创建用于准确报告生成的测试数据文件。创建测试数据的输入文件应在单独的行上具有每个句子。/src/accuracyReport/resources/language-testdata中。不要重命名测试数据文件。/src/accuracyReport/kotlin/com/github/pemistahl/lingua/report/config的主要逻辑创建一个抽象基类。查看此目录中的其他语言文件,以查看类的外观。这应该是不言而喻的。/src/accuracyReport/kotlin/com/github/pemistahl/lingua/report/lingua中创建一个混凝土测试类。查看此目录中的其他语言文件,以查看类的外观。这应该是不言而喻的。如果其他语言检测器库之一已经支持您的语言,则可以为其中添加测试类。每个库都有自己的目录为此目的。如果您的语言不受其他语言检测器库的支持,请将其排除在AbstractLanguageDetectionAccuracyReport中。/gradle.properties中,将您的新语言添加到属性的linguaSupportedLanguages 。./gradlew accuracyReport ,然后将更新的准确性报告添加到您的拉请请求中。./gradlew drawAccuracyPlots ,然后将更新的图添加到您的拉请请求中。./gradlew writeAccuracyTable ,并将更新的精度表添加到您的拉请请求中。看看计划中的问题。