它的任務很簡單:它告訴您有些提供的文本數據寫在哪種語言中。這是自然語言處理應用程序(例如文本分類和拼寫檢查)中語言數據的預處理步驟非常有用的。例如,其他用例可能包括基於電子郵件的語言將電子郵件路由到正確的地理位置客戶服務部門。
語言檢測通常是大型機器學習框架或自然語言處理應用程序的一部分。如果您不需要這些系統的全面功能或不想學習這些系統的繩索,那麼一個小的靈活庫就派上用場了。
到目前為止,在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 ,並將更新的精度表添加到您的拉請請求中。看看計劃中的問題。