Как определить язык текстового документа в Java?

Существует ли существующая библиотека Java, которая могла бы сказать мне, содержит ли String текст на английском языке или нет (например, мне нужно различать текст на французском или итальянском языке - функция должна возвращать false для французского и итальянского языков и true для английского языка) ?


person Community    schedule 10.01.2009    source источник
comment
Проверьте этот вопрос.   -  person Federico A. Ramponi    schedule 10.01.2009


Ответы (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 (более сложно, вы можете взвесить в соответствии с позицией в списке)
  • в конце предположим, что это язык с наивысшим баллом
  • необязательно, сделайте то же самое для общих слов (объедините баллы)

Очевидно, что затем это можно уточнить, но вы можете обнаружить, что это простое решение достаточно хорошо для того, что вы хотите, поскольку вас в основном интересует «английский или нет».

person Neil Coffey    schedule 10.01.2009

Вы пробовали Apache Tika. Он имеет хороший API для определения языка, а также может поддерживать другой язык, загружая соответствующий профиль.

person Ajit    schedule 23.09.2013

Вы можете попробовать сравнить каждое слово со словарем английского, французского или итальянского языков. Имейте в виду, что некоторые слова могут встречаться в нескольких словарях.

person z -    schedule 10.01.2009

Вот интересная запись в блоге, в которой обсуждается эта концепция. Примеры написаны на Scala, но вы сможете применить те же общие концепции к Java.

person mipadi    schedule 10.01.2009

Если вы смотрите на отдельные символы или слова, это сложная проблема. Однако, поскольку вы работаете с целым документом, может быть некоторая надежда. К сожалению, я не знаю существующей библиотеки для этого.

В общем, для каждого языка потребуется достаточно полный список слов. Затем проверьте каждое слово в документе. Если он появляется в словаре для языка, дайте этому языку «голос». Некоторые слова будут появляться более чем в одном языке, и иногда в документе на одном языке будут использоваться заимствованные слова из другого языка, но документ не должен быть очень длинным, прежде чем вы увидите очень четкую тенденцию к одному языку.

Некоторые из лучших списков слов для английского языка используются игроками Scrabble. Эти списки, вероятно, существуют и для других языков. Необработанные списки может быть трудно найти через Google, но они есть.

person erickson    schedule 10.01.2009

Там нет "хорошего" способа сделать это imo. Все ответы могут быть очень сложными по этой теме. Очевидная часть — проверить символы на французском + итальянском, а не на английском, а затем вернуть false.

Однако что, если это французское слово, но без специальных символов? Играйте с мыслью, что у вас есть целое предложение. Вы можете сопоставить каждое слово из словарей, и если в предложении больше французских точек, чем английских, это не английский язык. Это предотвратит общие слова, которые есть во французском, итальянском и английском языках.

Удачи.

person Filip Ekberg    schedule 10.01.2009
comment
Удачи. это лучший и, к сожалению, самый точный совет по этой проблеме. - person Esko; 10.01.2009