Существует ли существующая библиотека Java, которая могла бы сказать мне, содержит ли String текст на английском языке или нет (например, мне нужно различать текст на французском или итальянском языке - функция должна возвращать false для французского и итальянского языков и true для английского языка) ?
Как определить язык текстового документа в Java?
Ответы (6)
Существуют различные методы, и надежный метод будет сочетать в себе различные из них:
- посмотрите на частоты групп из n букв (скажем, групп из 3 букв или триграмм) в вашем тексте и посмотрите, похожи ли они на частоты, найденные для языка, с которым вы тестируете
- посмотрите, соответствуют ли часто встречающиеся слова в данном языке частотам встречаемости в вашем тексте (это лучше работает для более длинных текстов)
- содержит ли текст символы, которые сильно сужают его до определенного языка? (например, если текст содержит перевернутый вопросительный знак, велика вероятность, что это испанский язык)
можете ли вы "приблизительно разобрать" определенные функции в тексте, которые указывают на определенный язык, например если он содержит совпадение со следующим регулярным выражением, вы можете принять это как явный признак того, что язык французский:
\bvous\s+\p{L}+ez\b
Чтобы начать, вот частые триграммы и подсчеты слов для английского, французского и итальянского языков (скопированы и вставлены из какого-то кода - я оставлю их разбор в качестве упражнения):
Locale.ENGLISH,
"he_=38426;the=38122;nd_=20901;ed_=20519;and=18417;ing=16248;to_=15295;ng_=15281;er_=15192;at_=14219",
"the=11209;and=6631;to=5763;of=5561;a=5487;in=3421;was=3214;his=2313;that=2311;he=2115",
Locale.FRENCH,
"es_=38676;de_=28820;ent=21451;nt_=21072;e_d=18764;le_=17051;ion=15803;s_d=15491;e_l=14888;la_=14260",
"de=10726;la=5581;le=3954;" + ((char)224) + "=3930;et=3563;des=3295;les=3277;du=2667;en=2505;un=1588",
Locale.ITALIAN,
"re_=7275;la_=7251;to_=7208;_di=7170;_e_=7031;_co=5919;che=5876;he_=5622;no_=5546;di_=5460",
"di=7014;e=4045;il=3313;che=3006;la=2943;a=2541;in=2434;per=2165;del=2013;un=1945",
(Количество триграмм указано на миллион символов; количество слов на миллион слов. Символ «_» обозначает границу слова.)
Насколько я помню, цифры приведены в Оксфордском справочнике компьютерных лингвистов и основаны на выборке газетных статей. Если у вас есть корпус текстов на этих языках, достаточно легко самостоятельно вывести аналогичные цифры.
Если вам нужен действительно быстрый и грязный способ применения вышеизложенного, попробуйте:
- рассмотрите каждую последовательность из трех символов в вашем тексте (заменив границы слов на «_»)
- для каждой триграммы, которая соответствует одной из частых для данного языка, увеличьте «оценку» этого языка на 1 (более сложно, вы можете взвесить в соответствии с позицией в списке)
- в конце предположим, что это язык с наивысшим баллом
- необязательно, сделайте то же самое для общих слов (объедините баллы)
Очевидно, что затем это можно уточнить, но вы можете обнаружить, что это простое решение достаточно хорошо для того, что вы хотите, поскольку вас в основном интересует «английский или нет».
Вы пробовали Apache Tika. Он имеет хороший API для определения языка, а также может поддерживать другой язык, загружая соответствующий профиль.
Вы можете попробовать сравнить каждое слово со словарем английского, французского или итальянского языков. Имейте в виду, что некоторые слова могут встречаться в нескольких словарях.
Вот интересная запись в блоге, в которой обсуждается эта концепция. Примеры написаны на Scala, но вы сможете применить те же общие концепции к Java.
Если вы смотрите на отдельные символы или слова, это сложная проблема. Однако, поскольку вы работаете с целым документом, может быть некоторая надежда. К сожалению, я не знаю существующей библиотеки для этого.
В общем, для каждого языка потребуется достаточно полный список слов. Затем проверьте каждое слово в документе. Если он появляется в словаре для языка, дайте этому языку «голос». Некоторые слова будут появляться более чем в одном языке, и иногда в документе на одном языке будут использоваться заимствованные слова из другого языка, но документ не должен быть очень длинным, прежде чем вы увидите очень четкую тенденцию к одному языку.
Некоторые из лучших списков слов для английского языка используются игроками Scrabble. Эти списки, вероятно, существуют и для других языков. Необработанные списки может быть трудно найти через Google, но они есть.
Там нет "хорошего" способа сделать это imo. Все ответы могут быть очень сложными по этой теме. Очевидная часть — проверить символы на французском + итальянском, а не на английском, а затем вернуть false.
Однако что, если это французское слово, но без специальных символов? Играйте с мыслью, что у вас есть целое предложение. Вы можете сопоставить каждое слово из словарей, и если в предложении больше французских точек, чем английских, это не английский язык. Это предотвратит общие слова, которые есть во французском, итальянском и английском языках.
Удачи.