Подтвердить что ты не робот

Как определить, на каком языке написан текстовый файл?

Предположим, что у нас есть текстовый файл с содержимым: "Je suis un beau homme..."

другой с: "Я храбрый человек"

третий с текстом на немецком языке: "Гуттен Морген. Ви-гет?"

Как написать функцию, которая сообщила бы нам: с такой вероятностью текст в первом файл находится на английском языке, во втором - французский и т.д.

Приветствуются ссылки на книги и готовые решения. Я пишу на Java, но при необходимости могу изучить Python.

Мои комментарии

  • Есть один небольшой комментарий, который мне нужно добавить. Текст может содержать фразы на разных языках, как часть целого или в результате ошибки. В классической литературе у нас есть много примеров, потому что члены аристократии были многоязычны. Таким образом, вероятность лучше описывает ситуацию, так как большинство частей текста находятся на одном языке, а другие могут быть написаны в другом.
  • API Google - подключение к Интернету. Я бы предпочел не использовать удаленные функции/службы, поскольку мне нужно сделать это самостоятельно или использовать загружаемую библиотеку. Я бы хотел провести исследование по этой теме.
4b9b3361

Ответ 1

Существует пакет под названием JLangDetect, который, как представляется, делает именно то, что вы хотите:

langof("un texte en français") = fr : OK
langof("a text in english") = en : OK
langof("un texto en español") = es : OK
langof("un texte un peu plus long en français") = fr : OK
langof("a text a little longer in english") = en : OK
langof("a little longer text in english") = en : OK
langof("un texto un poco mas largo en español") = es : OK
langof("J'aime les bisounours !") = fr : OK
langof("Bienvenue à Montmartre !") = fr : OK
langof("Welcome to London !") = en : OK
// ...

Изменить: как отметил Кевин, в Nutch project есть аналогичная функциональность, предоставляемая пакетом org.apache.nutch.analysis.lang.

Ответ 3

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

Однако одно предложение очень вероятно слишком короткое, чтобы дать какие-либо полезные статистические меры. Возможно, вам повезет с соответствующими отдельными словами со словарем.

Ответ 4

NGramJ кажется немного более современным:

http://ngramj.sourceforge.net/

Он также имеет ориентированные на символы и байты профили, поэтому он также должен иметь возможность идентифицировать набор символов.

Для документов на нескольких языках вам необходимо идентифицировать набор символов (ICU4J имеет CharsetDetector, который может это сделать), затем разделите текст на что-то резонансное, как несколько разрывов строк, или абзацы, если текст выделен.

Ответ 5

Попробуйте Nutch Идентификатор языка. Он обучается с n-граммовыми профилями языков, а профиль доступных языков соответствует входному тексту. Интересно то, что вы можете добавить больше языков, если вам нужно.

Ответ 6

Посмотрите цепи Маркова.

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

Ответ 7

Хотя более сложное решение, чем вы ищете, вы можете использовать Vowpal Wabbit и обучать его предложениями с разных языков.

В теории вы можете вернуть язык для каждого предложения в своих документах.

http://hunch.net/~vw/

(Не обманывайте себя "онлайн" в субтитрах проекта - это просто математика для обучения, не имея всего учебного материала в памяти)

Ответ 8

Если вас интересует механизм, по которому может быть обнаружен язык, я отсылаю вас к следующей статье статьи (основанной на python), которая использует (очень) наивный метод, но представляет собой хорошее введение в эту проблему в частности и машинное обучение (просто большое слово) в целом.

Для java-реализаций JLangDetect и Nutch, как это было предложено другими плакатами, довольно хороши. Также посмотрите Lingpipe, JTCL и NGramJ.


Для проблемы, когда у вас несколько языков на одной странице, вы можете использовать детектор границ предложения, чтобы нарезать страницу на предложения, а затем попытаться определить язык каждого предложения. Предполагая, что предложение содержит только один (основной) язык, вы все равно должны получать хорошие результаты с любой из вышеперечисленных реализаций.

Примечание: детектор границы предложения (SBD) теоретически специфичен для языка (проблема куриного яйца, так как вам нужна одна для другой). Но для латинских языков (английский, французский, немецкий и т.д.), Которые в основном используют периоды (помимо восклицательных знаков и т.д.) Для ограничения предложения, вы получите приемлемые результаты, даже если вы используете SBD, предназначенный для английского языка. Я написал основанный на правилах английский SBD, который отлично поработал для французского текста. Для реализации взгляните на OpenNLP.

Альтернативным вариантом использования SBD является использование скользящего окна из 10 токенов (с разделителями пробелов) для создания псевдопредложения (PS) и попытки определить границу, на которой изменяется язык. Это имеет тот недостаток, что если весь ваш документ имеет n токенов, вы будете выполнять приблизительно n-10 операций классификации по строкам длиной 10 токенов каждый. В другом подходе, если среднее предложение имеет 10 токенов, вы выполнили бы приблизительно n/10 операций классификации. Если n = 1000 слов в документе, вы сравниваете 990 операций против 100 операций: разность по порядку величины.


Если у вас короткие фразы (менее 20 символов), точность определения языка плохо в моем опыте. В частности, в случае правильных существительных, а также существительных, которые одинаковы на разных языках, таких как "шоколад". Например. Является ли "Нью-Йорк" английским словом или французским словом, если оно появляется во французском предложении?

Ответ 9

У вас есть подключение к Интернету, если вы это сделаете, тогда API Google Language идеально подходит для вас.

// This example request includes an optional API key which you will need to
// remove or replace with your own key.
// Read more about why it useful to have an API key.
// The request also includes the userip parameter which provides the end
// user IP address. Doing so will help distinguish this legitimate
// server-side traffic from traffic which doesn't come from an end-user.
URL url = new URL(
    "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&"
    + "q=Paris%20Hilton&key=INSERT-YOUR-KEY&userip=USERS-IP-ADDRESS");
URLConnection connection = url.openConnection();
connection.addRequestProperty("Referer", /* Enter the URL of your site here */);

String line;
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while((line = reader.readLine()) != null) {
 builder.append(line);
}

JSONObject json = new JSONObject(builder.toString());
// now have some fun with the results...

Если у вас нет других методов.

Ответ 10

Модели bigram хорошо работают, просты в написании, просты в обучении и требуют лишь небольшого количества текста для обнаружения. Идентификатор языка nutch - это реализация Java, которую мы нашли и используем с тонкой оболочкой.

У нас были проблемы с моделью bigram для смешанного CJK и английского текста (т.е. твит в основном японский, но имеет одно английское слово). Это очевидно в ретроспективе, если посмотреть на математику (у японцев много других персонажей, поэтому вероятность любой пары невелика). Я думаю, вы могли бы решить это с помощью более сложного лог-линейного сравнения, но я обманул и использовал простой фильтр, основанный на наборах символов, которые уникальны для определенных языков (т.е. Если он содержит только унифицированный Хань, то он китайский, если он содержит некоторые Японская кана и унифицированный Хан, затем она японская).