Seine Aufgabe ist einfach: Sie zeigt Ihnen, in welcher Sprache einige bereitgestellte Textdaten geschrieben sind. Dies ist sehr nützlich als Vorverarbeitungsschritt für sprachliche Daten in Anwendungen für natürliche Sprachverarbeitung wie Textklassifizierung und Zauberprüfung. Andere Anwendungsfälle umfassen beispielsweise möglicherweise das Routing von E-Mails an die richtige geografisch gelegene Kundendienstabteilung, die auf den Sprachen der E-Mails basiert.
Die Spracherkennung erfolgt häufig als Teil großer maschineller Lernrahmen oder Anwendungen für natürliche Sprachverarbeitung. In Fällen, in denen Sie nicht die vollwertige Funktionalität dieser Systeme benötigen oder die Seile dieser Seile nicht lernen möchten, ist eine kleine flexible Bibliothek nützlich.
Bisher sind drei weitere umfassende Open -Source -Bibliotheken, die an der JVM für diese Aufgabe arbeiten, Apache Tika, Apache OpenNLP und optimalisieren Sprachdetektor. Leider hat vor allem letztere drei wichtige Nachteile:
Lingua zielt darauf ab, diese Probleme zu beseitigen. Es benötigt fast keine Konfiguration und liefert auch bei einzelnen Wörtern und Phrasen ziemlich genaue Ergebnisse. Es stützt sich sowohl auf regelbasierte als auch auf statistische Methoden, verwendet jedoch keine Wörterbücher von Wörtern. Es benötigt weder eine Verbindung zu einer externen API noch zu einer Dienstleistung. Sobald die Bibliothek heruntergeladen wurde, kann sie offline vollständig verwendet werden.
Im Vergleich zu anderen Spracherkennungsbibliotheken liegt der Schwerpunkt von Lingua auf Qualität über Quantität , dh das Erkennung richtig für eine kleine Reihe von Sprachen, bevor sie neue hinzufügen. Derzeit werden die folgenden 75 Sprachen unterstützt:
Lingua kann Genauigkeitsstatistiken für einige gebündelte Testdaten melden, die für jede unterstützte Sprache verfügbar sind. Die Testdaten für jede Sprache sind in drei Teile aufgeteilt:
Sowohl die Sprachmodelle als auch die Testdaten wurden aus getrennten Dokumenten der von der Leipzig University, Deutschland angebotenen Wortschatz -Korpora erstellt. Daten, die aus verschiedenen Nachrichten -Websites gekrabbt wurden, wurden für das Training verwendet, wobei jedes Korpus eine Million Sätze umfasst. Zum Testen wurden Korpora aus willkürlich ausgewählten Websites verwendet, die jeweils zehntausend Sätze umfassen. Aus jedem Testkorpus wurde eine zufällige, unsortierte Untergruppe von 1000 einzelnen Wörtern, 1000 Wortpaaren bzw. 1000 Sätze extrahiert.
In Anbetracht der generierten Testdaten habe ich die Erkennungsergebnisse von Lingua , Apache Tika , Apache OpenNLP und optimaler Sprachdetektor unter Verwendung parametrisierter JUNIT -Tests verglichen, die über die Daten der unterstützten 75 Sprachen von Lingua ausgeführt werden. Sprachen, die von den anderen Bibliotheken nicht unterstützt werden, werden für diejenigen während des Erkennungsprozesses einfach ignoriert.
Jeder der folgenden Abschnitte enthält zwei Diagramme. Die Bar -Diagramm zeigt die detaillierten Genauigkeitsergebnisse für jede unterstützte Sprache. Das Box -Diagramm zeigt die Verteilungen der Genauigkeitswerte für jeden Klassifikator. Die Boxen selbst repräsentieren die Bereiche, in denen die mittleren 50 % der Daten liegen. Innerhalb der farbigen Kisten markieren die horizontalen Linien den Median der Verteilungen.
Die folgende Tabelle zeigt detaillierte Statistiken für jede Sprache und jeden Klassifikator, einschließlich Mittelwert, Median und Standardabweichung.
| Sprache | Durchschnitt | Einzelne Wörter | Wortpaare | Sätze | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| LINuA (hoher Genauigkeitsmodus) | LINuA (niedriger Genauigkeitsmodus) | Tika | OpenNLP | Optimaize | LINuA (hoher Genauigkeitsmodus) | LINuA (niedriger Genauigkeitsmodus) | Tika | OpenNLP | Optimaize | LINuA (hoher Genauigkeitsmodus) | LINuA (niedriger Genauigkeitsmodus) | Tika | OpenNLP | Optimaize | LINuA (hoher Genauigkeitsmodus) | LINuA (niedriger Genauigkeitsmodus) | Tika | OpenNLP | Optimaize | |
| Afrikaans | 79 | 64 | 71 | 72 | 39 | 58 | 38 | 44 | 41 | 3 | 81 | 62 | 70 | 75 | 22 | 97 | 93 | 98 | 99 | 93 |
| albanisch | 88 | 80 | 79 | 71 | 70 | 69 | 54 | 54 | 40 | 38 | 95 | 86 | 84 | 73 | 73 | 100 | 99 | 99 | 100 | 98 |
| Arabisch | 98 | 94 | 97 | 84 | 89 | 96 | 88 | 94 | 65 | 72 | 99 | 96 | 99 | 88 | 94 | 100 | 99 | 100 | 99 | 100 |
| Armenisch | 100 | 100 | - - | 100 | - - | 100 | 100 | - - | 100 | - - | 100 | 100 | - - | 100 | - - | 100 | 100 | - - | 100 | - - |
| Aserbaidschani | 90 | 82 | - - | 82 | - - | 77 | 71 | - - | 60 | - - | 92 | 78 | - - | 86 | - - | 99 | 96 | - - | 99 | - - |
| baskisch | 84 | 74 | 83 | 77 | 66 | 71 | 56 | 64 | 56 | 33 | 87 | 76 | 86 | 82 | 70 | 93 | 91 | 98 | 92 | 95 |
| Weißrussland | 97 | 92 | 96 | 91 | 87 | 92 | 80 | 92 | 78 | 69 | 99 | 95 | 98 | 95 | 92 | 100 | 100 | 100 | 100 | 99 |
| Bengali | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| Bokmal | 58 | 49 | - - | 66 | - - | 39 | 27 | - - | 42 | - - | 59 | 47 | - - | 69 | - - | 75 | 74 | - - | 87 | - - |
| bosnisch | 35 | 29 | - - | 26 | - - | 29 | 23 | - - | 12 | - - | 35 | 29 | - - | 22 | - - | 40 | 36 | - - | 44 | - - |
| bulgarisch | 87 | 78 | 73 | 83 | 48 | 70 | 56 | 52 | 62 | 18 | 91 | 81 | 69 | 87 | 36 | 99 | 96 | 96 | 100 | 91 |
| katalanisch | 70 | 58 | 58 | 42 | 31 | 51 | 33 | 32 | 11 | 2 | 74 | 60 | 57 | 32 | 16 | 86 | 81 | 84 | 81 | 77 |
| chinesisch | 100 | 100 | 69 | 78 | 31 | 100 | 100 | 20 | 40 | 0 | 100 | 100 | 86 | 94 | 2 | 100 | 100 | 100 | 100 | 91 |
| kroatisch | 72 | 60 | 74 | 50 | 41 | 53 | 36 | 54 | 23 | 8 | 74 | 57 | 72 | 44 | 24 | 90 | 85 | 97 | 81 | 91 |
| tschechisch | 80 | 71 | 72 | 67 | 49 | 66 | 54 | 54 | 42 | 21 | 84 | 72 | 75 | 70 | 46 | 91 | 87 | 88 | 90 | 81 |
| dänisch | 81 | 70 | 83 | 60 | 55 | 61 | 45 | 63 | 34 | 19 | 84 | 70 | 86 | 52 | 51 | 98 | 95 | 99 | 94 | 96 |
| Niederländisch | 77 | 64 | 60 | 61 | 39 | 55 | 36 | 31 | 31 | 6 | 81 | 61 | 52 | 57 | 19 | 96 | 94 | 98 | 97 | 91 |
| Englisch | 81 | 62 | 64 | 52 | 41 | 55 | 29 | 30 | 10 | 2 | 89 | 62 | 62 | 46 | 23 | 99 | 96 | 99 | 99 | 97 |
| Esperanto | 84 | 66 | - - | 76 | - - | 67 | 44 | - - | 50 | - - | 85 | 61 | - - | 78 | - - | 98 | 92 | - - | 100 | - - |
| estnisch | 92 | 83 | 84 | 59 | 61 | 80 | 62 | 66 | 29 | 23 | 96 | 88 | 88 | 60 | 63 | 100 | 99 | 100 | 88 | 98 |
| finnisch | 96 | 91 | 94 | 86 | 79 | 90 | 77 | 86 | 68 | 51 | 98 | 95 | 96 | 91 | 86 | 100 | 100 | 100 | 100 | 100 |
| Französisch | 89 | 77 | 78 | 59 | 54 | 74 | 52 | 55 | 25 | 18 | 94 | 83 | 80 | 55 | 48 | 99 | 97 | 99 | 98 | 97 |
| Ganda | 91 | 84 | - - | - - | - - | 79 | 65 | - - | - - | - - | 95 | 87 | - - | - - | - - | 100 | 100 | - - | - - | - - |
| georgisch | 100 | 100 | - - | 100 | - - | 100 | 100 | - - | 100 | - - | 100 | 100 | - - | 100 | - - | 100 | 100 | - - | 100 | - - |
| Deutsch | 89 | 80 | 74 | 67 | 55 | 74 | 57 | 50 | 38 | 21 | 94 | 84 | 71 | 66 | 46 | 100 | 99 | 100 | 98 | 99 |
| griechisch | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| Gujarati | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| hebräisch | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| Hindi | 73 | 33 | 80 | 58 | 51 | 61 | 11 | 65 | 28 | 16 | 64 | 20 | 75 | 49 | 38 | 93 | 67 | 99 | 99 | 98 |
| ungarisch | 95 | 90 | 88 | 78 | 77 | 87 | 77 | 75 | 53 | 51 | 98 | 94 | 91 | 82 | 82 | 100 | 100 | 100 | 100 | 99 |
| isländisch | 93 | 88 | 90 | 76 | 78 | 83 | 72 | 76 | 53 | 53 | 97 | 92 | 94 | 76 | 82 | 100 | 99 | 100 | 99 | 99 |
| Indonesisch | 60 | 48 | 60 | 29 | 18 | 39 | 25 | 37 | 10 | 0 | 61 | 46 | 62 | 25 | 1 | 81 | 72 | 82 | 52 | 54 |
| irisch | 91 | 85 | 90 | 78 | 80 | 82 | 70 | 80 | 56 | 58 | 94 | 90 | 92 | 82 | 85 | 96 | 95 | 99 | 97 | 98 |
| Italienisch | 87 | 71 | 80 | 64 | 51 | 69 | 42 | 58 | 31 | 12 | 92 | 74 | 84 | 61 | 43 | 100 | 98 | 99 | 100 | 98 |
| japanisch | 100 | 100 | 25 | 95 | 98 | 100 | 100 | 1 | 87 | 99 | 100 | 100 | 5 | 100 | 100 | 100 | 100 | 68 | 100 | 96 |
| Kasachisch | 92 | 90 | - - | 85 | - - | 80 | 78 | - - | 66 | - - | 96 | 93 | - - | 90 | - - | 99 | 99 | - - | 100 | - - |
| Koreanisch | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| lateinisch | 87 | 73 | - - | 70 | - - | 72 | 49 | - - | 43 | - - | 93 | 76 | - - | 71 | - - | 97 | 93 | - - | 96 | - - |
| lettisch | 93 | 87 | 90 | 86 | 78 | 85 | 75 | 78 | 72 | 56 | 97 | 90 | 93 | 88 | 82 | 99 | 97 | 98 | 98 | 97 |
| litauisch | 95 | 87 | 89 | 79 | 72 | 86 | 76 | 74 | 56 | 40 | 98 | 89 | 92 | 83 | 77 | 100 | 98 | 99 | 99 | 98 |
| mazedonisch | 84 | 72 | 83 | 68 | 46 | 66 | 52 | 66 | 37 | 10 | 86 | 70 | 83 | 68 | 32 | 99 | 95 | 100 | 98 | 97 |
| malaiisch | 31 | 31 | 23 | 19 | 4 | 26 | 22 | 19 | 10 | 0 | 38 | 36 | 22 | 20 | 0 | 30 | 36 | 28 | 27 | 11 |
| Maori | 92 | 83 | - - | 92 | - - | 84 | 64 | - - | 85 | - - | 92 | 88 | - - | 90 | - - | 99 | 98 | - - | 100 | - - |
| Marathi | 85 | 41 | 90 | 81 | 71 | 74 | 20 | 81 | 62 | 43 | 85 | 30 | 92 | 83 | 74 | 96 | 72 | 98 | 98 | 96 |
| mongolisch | 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 | - - |
| persisch | 90 | 80 | 81 | 75 | 62 | 78 | 62 | 65 | 53 | 29 | 94 | 80 | 79 | 74 | 58 | 100 | 98 | 99 | 99 | 99 |
| Polieren | 95 | 90 | 90 | 83 | 81 | 85 | 77 | 76 | 61 | 57 | 98 | 93 | 93 | 89 | 86 | 100 | 99 | 100 | 100 | 100 |
| Portugiesisch | 81 | 69 | 63 | 58 | 40 | 59 | 42 | 34 | 22 | 7 | 85 | 70 | 58 | 54 | 19 | 98 | 95 | 98 | 98 | 94 |
| Punjabi | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| rumänisch | 87 | 72 | 78 | 67 | 55 | 69 | 49 | 57 | 34 | 24 | 92 | 74 | 80 | 68 | 50 | 99 | 94 | 97 | 99 | 91 |
| Russisch | 90 | 78 | 80 | 50 | 53 | 76 | 59 | 62 | 20 | 22 | 95 | 84 | 85 | 43 | 50 | 98 | 92 | 94 | 86 | 87 |
| serbisch | 88 | 78 | 73 | 73 | 46 | 74 | 62 | 57 | 46 | 18 | 90 | 80 | 70 | 74 | 39 | 99 | 91 | 90 | 98 | 80 |
| Shona | 91 | 81 | - - | - - | - - | 78 | 56 | - - | - - | - - | 96 | 86 | - - | - - | - - | 100 | 100 | - - | - - | - - |
| slowakisch | 84 | 75 | 76 | 70 | 47 | 64 | 49 | 53 | 39 | 12 | 90 | 78 | 76 | 73 | 38 | 99 | 97 | 98 | 99 | 92 |
| Slowene | 82 | 67 | 74 | 71 | 37 | 61 | 39 | 53 | 43 | 3 | 87 | 68 | 72 | 72 | 18 | 99 | 93 | 98 | 99 | 90 |
| somali | 92 | 85 | 91 | 69 | 79 | 82 | 64 | 78 | 35 | 50 | 96 | 90 | 94 | 74 | 88 | 100 | 100 | 100 | 98 | 100 |
| Sotho | 85 | 72 | - - | - - | - - | 67 | 43 | - - | - - | - - | 90 | 75 | - - | - - | - - | 99 | 97 | - - | - - | - - |
| Spanisch | 70 | 56 | 59 | 42 | 32 | 44 | 26 | 29 | 8 | 0 | 69 | 49 | 50 | 25 | 6 | 97 | 94 | 97 | 93 | 91 |
| Swahili | 81 | 70 | 75 | 73 | 60 | 60 | 43 | 50 | 45 | 26 | 84 | 68 | 75 | 74 | 58 | 98 | 97 | 99 | 99 | 98 |
| Schwedisch | 84 | 72 | 71 | 69 | 50 | 64 | 46 | 44 | 41 | 15 | 88 | 76 | 72 | 69 | 42 | 99 | 95 | 97 | 97 | 94 |
| Tagalog | 78 | 66 | 77 | 61 | 61 | 52 | 36 | 53 | 27 | 23 | 83 | 67 | 79 | 57 | 62 | 99 | 96 | 99 | 98 | 97 |
| Tamil | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| Telugu | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 |
| Thai | 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 | - - | - - | - - |
| Türkisch | 94 | 87 | 81 | 72 | 70 | 84 | 71 | 62 | 48 | 43 | 98 | 91 | 83 | 71 | 70 | 100 | 99 | 99 | 98 | 96 |
| ukrainisch | 92 | 86 | 81 | 79 | 68 | 84 | 75 | 62 | 54 | 39 | 97 | 92 | 84 | 83 | 69 | 95 | 93 | 97 | 99 | 94 |
| Urdu | 91 | 80 | 83 | 68 | 72 | 80 | 65 | 68 | 45 | 49 | 94 | 78 | 84 | 62 | 71 | 98 | 96 | 96 | 98 | 96 |
| Vietnamesisch | 91 | 87 | 85 | 84 | 87 | 79 | 76 | 63 | 66 | 65 | 94 | 87 | 92 | 86 | 95 | 99 | 98 | 100 | 100 | 100 |
| Walisisch | 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 | - - | - - | - - |
| Yoruba | 75 | 62 | - - | - - | - - | 50 | 33 | - - | - - | - - | 77 | 61 | - - | - - | - - | 97 | 93 | - - | - - | - - |
| Zulu | 81 | 70 | - - | 78 | - - | 62 | 45 | - - | 51 | - - | 83 | 72 | - - | 82 | - - | 97 | 94 | - - | 100 | - - |
| Bedeuten | 86 | 77 | 80 | 74 | 65 | 74 | 61 | 64 | 53 | 41 | 89 | 78 | 81 | 74 | 61 | 96 | 93 | 96 | 95 | 93 |
| Mittlere | 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 |
| Standardabweichung | 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 |
Jeder Sprachdetektor verwendet ein probabilistisches N-Gramm-Modell, das auf der Charakterverteilung in einigen Trainingskorpus geschult ist. Die meisten Bibliotheken verwenden nur N-Gramm von Größe 3 (Trigramm), was für die Erkennung der Sprache längerer Textfragmente, die aus mehreren Sätzen bestehen, zufriedenstellend ist. Für kurze Phrasen oder einzelne Wörter reichen Trigramme jedoch nicht aus. Je kürzer der Eingangstext ist, desto weniger N-Gramm sind verfügbar. Die aus so wenigen N-Gramm geschätzten Wahrscheinlichkeiten sind nicht zuverlässig. Aus diesem Grund nutzt Lingua N-Gramm von Größen 1 bis zu 5, was zu einer viel genaueren Vorhersage der richtigen Sprache führt.
Ein zweiter wichtiger Unterschied besteht darin, dass Lingua nicht nur ein solches statistisches Modell, sondern auch einen regelbasierten Motor verwendet. Diese Engine bestimmt zunächst das Alphabet des Eingabentextes und sucht nach Zeichen, die in einer oder mehreren Sprachen eindeutig sind. Wenn genau eine Sprache auf diese Weise zuverlässig ausgewählt werden kann, ist das statistische Modell nicht mehr erforderlich. In jedem Fall filtert die regelbasierte Engine Sprachen heraus, die die Bedingungen des Eingabetxtes nicht erfüllen. Nur dann wird in einem zweiten Schritt das probabilistische n-Gramm-Modell berücksichtigt. Dies ist sinnvoll, da das Laden weniger Sprachmodelle weniger Speicherverbrauch und eine bessere Laufzeitleistung bedeutet.
Im Allgemeinen ist es immer eine gute Idee, die Sprachenmenge einzuschränken, die im Klassifizierungsprozess anhand der jeweiligen API -Methoden berücksichtigt werden soll. Wenn Sie vorher wissen, dass bestimmte Sprachen niemals in einem Eingabetxt auftreten dürfen, lassen Sie diese nicht am Klassifizierungsprozess teilnehmen. Der Filtermechanismus der regelbasierten Engine ist ziemlich gut. Die Filterung auf der Grundlage Ihrer eigenen Kenntnis des Eingabetxtes ist jedoch immer vorzuziehen.
Wenn Sie die oben genannten Genauigkeitsergebnisse reproduzieren möchten, können Sie die Testberichte selbst für alle vier Klassifizierer und alle Sprachen erstellen, indem Sie:
./gradlew accuracyReport
Sie können auch die Klassifikatoren und Sprachen einschränken, um Berichte für die Übergabe von Argumenten an die Gradle -Aufgabe zu erstellen. Die folgende Aufgabe generiert Berichte für Lingua und die Sprachen nur Englisch und Deutsch:
./gradlew accuracyReport -Pdetectors=Lingua -Planguages=English,German
Standardmäßig wird nur ein einzelner CPU -Kern für die Berichterstellung verwendet. Wenn Sie eine Multi-Core-CPU in Ihrer Maschine haben, können Sie so viele Prozesse wie Sie CPU-Kerne haben. Dies beschleunigt die Berichterstattung erheblich. Beachten Sie jedoch, dass mehr als ein Prozess viel RAM konsumieren kann. Du machst es so:
./gradlew accuracyReport -PcpuCores=2
Für jeden Detektor und jede Sprache wird dann eine Testberichtdatei in /accuracy-reports geschrieben, die neben dem src Verzeichnis gefunden werden soll. Als Beispiel finden Sie hier die aktuelle Ausgabe des Lingua Deutschen Berichts:
##### 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%
Lingua wird auf Github -Paketen und Maven Central gehostet.
// 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>
Lingua nutzt Gradle, um Java> = 1,8 dafür zu bauen.
git clone https://github.com/pemistahl/lingua.git
cd lingua
./gradlew build
Aus dem Projekt können mehrere JAR -Archive erstellt werden.
./gradlew jar lingua-1.2.2.jar./gradlew sourcesJar lingua-1.2.2-sources.jar./gradlew jarWithDependencies lingua-1.2.2-with-dependencies.jar Diese JAR -Datei kann in Projekte ohne Abhängigkeitsmanagementsysteme aufgenommen werden. Es kann auch verwendet werden, um Lingua im Standalone -Modus auszuführen (siehe unten). Lingua kann programmgesteuert in Ihrem eigenen Code oder im eigenständigen Modus verwendet werden.
Die API ist ziemlich einfach und kann sowohl im Kotlin- als auch im Java -Code verwendet werden.
/* 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 " ) Die öffentliche API von Lingua kehrt nie irgendwo null zurück, daher ist es sicher, auch innerhalb des Java -Codes verwendet zu werden.
/* 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" );Standardmäßig gibt Lingua die wahrscheinlichste Sprache für einen bestimmten Eingangstext zurück. Es gibt jedoch bestimmte Wörter, die in mehr als einer Sprache gleich geschrieben werden. Das Wort Prolog ist zum Beispiel sowohl ein gültiges englisches als auch ein französisches Wort. Lingua würde entweder Englisch oder Französisch ausgeben, was im gegebenen Kontext falsch sein könnte. In solchen Fällen ist es möglich, einen minimalen relativen Abstand anzugeben, den die Logarithmus für jede mögliche Sprache erfüllen muss. Es kann auf folgende Weise angegeben werden:
val detector = LanguageDetectorBuilder
.fromAllLanguages()
.withMinimumRelativeDistance( 0.25 ) // minimum: 0.00 maximum: 0.99 default: 0.00
.build() Beachten Sie, dass der Abstand zwischen den Sprachwahrscheinlichkeiten von der Länge des Eingabetxtes abhängt. Je länger der Eingangstext, desto größer ist der Abstand zwischen den Sprachen. Wenn Sie also sehr kurze Textphrasen klassifizieren möchten, setzen Sie den minimalen relativen Abstand nicht zu hoch. Andernfalls werden die meisten Ergebnisse als Language.UNKNOWN zurückgegeben.
Es ist schön, über die wahrscheinlichste Sprache zu wissen, aber wie zuverlässig ist die berechnete Wahrscheinlichkeit? Und wie weniger wahrscheinlich sind die anderen untersuchten Sprachen im Vergleich zum wahrscheinlichsten? Diese Fragen können ebenfalls beantwortet werden:
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
// }Im obigen Beispiel wird eine Karte aller möglichen Sprachen zurückgegeben, sortiert nach ihrem Vertrauenswert in absteigender Reihenfolge. Die Werte, die der Detektor berechnet, sind Teil einer relativen Vertrauensmetrik und nicht einer absoluten. Jeder Wert ist eine Zahl zwischen 0,0 und 1,0. Die wahrscheinlichste Sprache wird immer mit Wert 1.0 zurückgegeben. Alle anderen Sprachen erhalten Werte zugewiesen, die niedriger als 1,0 sind, was bedeutet, wie weniger wahrscheinlich diese Sprachen im Vergleich zur wahrscheinlichsten Sprache sind.
Die nach dieser Methode zurückgegebene Karte enthält nicht notwendigerweise alle Sprachen, aus denen die aufrufende Instanz von LanguageDetector erstellt wurde. Wenn die regelbasierte Engine entscheidet, dass eine bestimmte Sprache wirklich unmöglich ist, ist sie nicht Teil der zurückgegebenen Karte. Ebenso ist die zurückgegebene Karte leer, wenn in den Sprachen des Detektors keine NGRAM -Wahrscheinlichkeiten in den Sprachen des Detektors gefunden werden können. Der Vertrauenswert für jede Sprache, die nicht Teil der zurückgegebenen Karte ist, wird mit 0,0 angenommen.
Standardmäßig lädt Lingua nur diese Sprachmodelle auf Bedarf, die von der regelbasierten Filtermotor als relevant werden. Für Webdienste ist es beispielsweise ziemlich vorteilhaft, alle Sprachmodelle in das Gedächtnis zu bringen, um unerwartete Latenz zu vermeiden und gleichzeitig auf die Serviceantwort zu warten. Wenn Sie den eifrigen Ladenmodus aktivieren möchten, können Sie dies so tun:
LanguageDetectorBuilder .fromAllLanguages().withPreloadedLanguageModels().build() Mehrere Instanzen von LanguageDetector teilen die gleichen Sprachmodelle im Speicher, auf die von den Instanzen asynchron zugegriffen werden.
Die hohe Erkennungsgenauigkeit von Lingua ergibt sich zu den Kosten, die merklich langsamer sind als andere Sprachdetektoren. Die großen Sprachmodelle verbrauchen auch erhebliche Mengen an Gedächtnis. Diese Anforderungen sind möglicherweise nicht möglich für Systeme, die nur geringe Ressourcen betreiben. Wenn Sie meistens lange Texte klassifizieren oder Ressourcen sparen müssen, können Sie einen geringen Genauigkeitsmodus aktivieren, in dem nur eine kleine Teilmenge der Sprachmodelle in den Speicher geladen wird:
LanguageDetectorBuilder .fromAllLanguages().withLowAccuracyMode().build()Der Nachteil dieses Ansatzes ist, dass die Erkennungsgenauigkeit für kurze Texte, die aus weniger als 120 Zeichen bestehen, erheblich sinken wird. Die Erkennungsgenauigkeit für Texte, die länger als 120 Zeichen sind, bleiben jedoch größtenteils unberührt.
Eine Alternative für einen kleineren Speicherpflichtigen und eine schnellere Leistung besteht darin, die Sprachenmenge beim Erstellen des Sprachdetektors zu reduzieren. In den meisten Fällen ist es nicht ratsam, den Detektor aus allen unterstützten Sprachen aufzubauen. Wenn Sie Kenntnisse über die Texte haben, die Sie klassifizieren möchten, können Sie fast immer bestimmte Sprachen als unmöglich oder unwahrscheinlich ausschließen.
Es könnte Klassifizierungsaufgaben geben, bei denen Sie vorher wissen, dass Ihre Sprachdaten zum Beispiel nicht in lateinischer Sprache geschrieben sind (was für eine Überraschung :-). Die Erkennungsgenauigkeit kann in solchen Fällen besser werden, wenn Sie bestimmte Sprachen aus dem Entscheidungsprozess ausschließen oder nur explizit relevante Sprachen enthalten:
// 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 )Innen verwendet Lingua effizient alle Kerne Ihrer CPU, um das Laden der Sprachmodelle und der Spracherkennung selbst zu beschleunigen. Zu diesem Zweck wird ein interner Gabeljoinpool verwendet. Wenn die Bibliothek innerhalb eines Anwendungsservers verwendet wird, wird der verbrauchte Speicher nicht automatisch befreit, wenn die Anwendung abgelaufen ist.
Wenn Sie alle Ressourcen von Lingua befreien möchten, müssen Sie dies manuell erledigen, indem Sie detector.unloadLanguageModels() während des Abgloses anrufen. Dadurch werden alle geladenen Sprachmodelle aus dem Speicher gelöscht, aber der Thread -Pool läuft weiter.
Wenn Sie Lingua ausprobieren möchten, bevor Sie sich entscheiden, ob Sie es verwenden möchten oder nicht, können Sie es in einer Reply ausführen und die Erkennungsergebnisse sofort sehen.
./gradlew runLinguaOnConsole --console=plainjava -jar lingua-1.2.2-with-dependencies.jarDann spielen Sie einfach herum:
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!
Falls Sie etwas zu Lingua beitragen möchten, dann werden Sie dazu ermutigt. Haben Sie Ideen zur Verbesserung der API? Gibt es einige bestimmte Sprachen, die Sie früh unterstützt haben möchten? Oder haben Sie bisher irgendwelche Fehler gefunden? Fühlen Sie sich frei, ein Problem zu öffnen oder eine Pull -Anfrage zu senden. Es wird sehr geschätzt.
Für Pull -Anfragen stellen Sie bitte sicher, dass alle Unit -Tests bestehen und dass der Code gemäß dem offiziellen Kotlin -Style Guide formatiert ist. Sie können dies überprüfen, indem Sie den Kotlin -Linter KtLint mit ./gradlew ktlintCheck ausführen. Die meisten Probleme, die der Linter identifiziert, können durch Ausführen behoben werden ./gradlew ktlintFormat . Alle anderen Probleme, insbesondere Linien, die länger als 120 Zeichen sind, können nicht automatisch behoben werden. In diesem Fall formatieren Sie bitte die jeweiligen Linien von Hand. Sie werden feststellen, dass der Build fehlschlägt, wenn die Formatierung nicht korrekt ist.
Alle Arten von Pull -Anfragen sind willkommen. Die beliebtesten sind neue Sprachzusätze. Wenn Sie neue Sprachen zu Lingua einbringen möchten, wird hier ein detailliertes Handbuch erkrankt, in dem erklärt wird, wie Sie dies erreichen können.
Vielen Dank im Voraus für alle Beiträge, wie klein sie auch sein mögen.
Um die folgenden Schritte auszuführen, benötigen Sie Java 8 oder mehr. Obwohl die Bibliothek selbst auf Java> = 6 ausgeführt wird, verwenden die FilesWriter -Klassen die mit Java 8 eingeführte Java.nio -API.
IsoCode639_1 und IsoCode639_3 und fügen Sie die ISO -Codes der Sprache hinzu. Wikipedia bietet unter anderem eine umfassende Liste.Language der Enum und fügen Sie einen neuen Eintrag für Ihre Sprache hinzu. Wenn die Sprache mit einem Skript geschrieben ist, das noch nicht von Linguas Alphabet Enum unterstützt wird, fügen Sie dort auch einen neuen Eintrag dafür hinzu.Language hinzu. Wenn die Zeichen jedoch in mehr als einer Sprache auftreten , jedoch nicht in allen Sprachen, fügen Sie sie stattdessen in die CHARS_TO_LANGUAGES_MAPPING -Konstante in der Constant hinzu.LanguageModelFilesWriter , um die Sprachmodelldateien zu erstellen. Die für die NGRAM -Wahrscheinlichkeitsschätzung verwendete Trainingsdatendatei ist nicht erforderlich, um ein bestimmtes Format als eine gültige TXT -Datei zu haben./src/main/resources/language-models und legen Sie die generierten Sprachmodelldateien ein. Benennen Sie die Sprachmodelldateien nicht um. Der Name des Unterverzeichnisses muss der ISO 639-1-Code der Sprache sein, der vollständig verringert ist.TestDataFilesWriter , um die für die Generierung der Genauigkeitsbericht verwendeten Testdatendateien zu erstellen. Die Eingabedatei zum Erstellen der Testdaten sollte jeden Satz in einer separaten Zeile haben./src/accuracyReport/resources/language-testdata ein. Benennen Sie die Testdatendateien nicht um./src/accuracyReport/kotlin/com/github/pemistahl/lingua/report/config . Schauen Sie sich die Dateien der anderen Sprachen in diesem Verzeichnis an, um zu sehen, wie die Klasse aussehen muss. Es sollte ziemlich selbsterklärend sein./src/accuracyReport/kotlin/com/github/pemistahl/lingua/report/lingua . Schauen Sie sich die Dateien der anderen Sprachen in diesem Verzeichnis an, um zu sehen, wie die Klasse aussehen muss. Es sollte ziemlich selbsterklärend sein. Wenn eine der anderen Sprachdetektorbibliotheken Ihre Sprache bereits unterstützt, können Sie auch Testklassen für diese hinzufügen. Jede Bibliothek hat zu diesem Zweck ein eigenes Verzeichnis. Wenn Ihre Sprache nicht von den anderen Sprachdetektorbibliotheken unterstützt wird, schließen Sie sie in AbstractLanguageDetectionAccuracyReport aus.linguaSupportedLanguages in /gradle.properties hinzu../gradlew accuracyReport aus../gradlew drawAccuracyPlots./gradlew writeAccuracyTableSchauen Sie sich die geplanten Probleme an.