Главная > AJAX, Data Mining, Open Source, PHP, Разное, Стартапы > Автоматическое определение языка произвольного текста на РНР — библиотека PHPLangautodetect

Автоматическое определение языка произвольного текста на РНР — библиотека PHPLangautodetect

15 июня 2008

Приветствуем наших читателей. Знаете, работа с стартапе, который пытается создать что-то новое и уникальное на рынке очень захватывает. И не только открывающимися возможностями, но и часто нетривиальными задачами и вопросами, которые ставятся перед создателями и которые раньше никто не решал. Вот один из таких вопросов как раз вчера появился передо мной: дано нам произвольную строку текста, заведомо известно, что она может быть двух, а в некоторых случаях и трёхязычной, то есть там смешанный текст из нескольких языков. Необходимо прозрачно для пользователя определить язык, на котором написан текст.

На самом деле задача не такая и редкая - подобная функциональность есть и в текстовых редакторах, и в переключателе клавиатуры PuntoSwitcher, да и в системах машинного перевода такой функционал востребован, не говоря уже про системы поиска информации. Кстати, именно в контексте создания специализированного поисковика и классификатора текстов и появилась такая проблема. Необходимо было получить такую возможность в собственной программе на платформе РНР и при этом не задействовать сторонние сервисы - подобная возможность в виде веб-сервиса присутствует в Google Language API (мы уже исследовали этот сервис), однако она выполняется удалённо и имеет некоторые существенные для нас ограничения, в частности, процедура опознания языка выполняется с существенной задержкой и асинхронна по своей природе. Кроме этого очень хотелось иметь полный контроль над процессом и иметь возможность его гибко настраивать, чего, увы, нет в сторонних сервисах. Поэтому пришлось подумать и попробовать реализовать собственными силами, результат же представляем вашему вниманию.

Сначала немного теории. Сразу следует сказать, что сам процесс автоматического определения языка неточен и принципиально является вероятностным. То есть всегда результат даётся с какой-либо вероятностью, особенно это касается языков, которые имеют очень схожий либо даже идентичный алфавит (в написании), однако различны. При этом мы ещё и зависим от длины строки исследуемого текста - чем меньше у нас материала для исследования, тем сложнее или даже невозможно является такое определение. Ведь для статистики необходимо иметь больше поле для подсчёта параметров, а в короткой строке мы не можем получить достаточно материала для идентификации, особенно при анализе языков, которые имеют в своей основе одинаковый алфавит. В таком тексте банально может просто не встречаться уникальных букв и оно будет определено как слово другого языка. Поэтому первым ограничением метода анализа используемого алфавита является длина текста - чем он больше, тем точнее анализ. Приведу пример: слово "rappel". На каком оно языке? На английском? Оно означает "спускаться на верёвке". Но такое же слово есть и в немецком языке! И там оно означает "(внезапное) помешательство, приступ бешенства".

Этот метод имеет две разновидности. Вариант использования "процента использования алфавита" использует подсчёт количества использованных уникальных символов алфавита в тексте и расчёт % от  общего объёма. Второй изменяет количество символов из текста, которое совпадает с алфавитом, при этом некоторые символы могут попадать в разные алфавиты и засчитываться обоим языкам.

Второй метод основан на использовании заранее сформированных правил, которые устанавливают идентичность текста при помощи уникальных или типичных для грамматики языка последовательностей букв (например, артикли в английском, буквы "ъ" и "ё" в русском или "є" в украинском). Такие правила для n-грамм могут разрабатываться лингвистами и позволяют быстрее и точнее определить язык текста, однако также не дают гарантированного результата. Их то сначала нужно создать, а значит владеть языком на достаточном уровне, да и не так много уникальных характерных последовательностей в разных языках. Хотя, если вы заранее знаете, какие языки вам надо определять, то между ними может быть больше уникальных сочетаний, чем если использовать все языки. Если у вас только русский и английский, то таких буквосочетаний явно больше, чем в паре немецкий-английский.

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

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

Библиотека работает с текстами в кодировке UTF-8, поэтому требует модуля mb_strings и первым делом приводит полученную строку к стандартной форме, пытаясь её перекодировать, потом удаляет лишние знаки и проверяет длину. Минимальный объём текста 50 символов, максимальный - 1680, это примерно равно одной стандартной странице формата А4.

Вы можете задать различные варианты детектирования. Библиотека может использовать анализ алфавитов, при этом смотреть или на общий объем текста, или же на процент используемых букв каждого алфавита. Порог принятия решения также настраивается, по умолчанию это 75% (в зависимости от подсчёта, это или 75% букв алфавита или же в тексте общее количество символов этого языка больше 75%).   Также есть возможность использовать эвристические правила для уточнения результата, при этом можно настроить приоритет - если правило не подтвердит результат анализа по статистике, то более верным считать результат работы правил или же следует довериться статистике. Для более быстрой работы, особенно на больших объёмах текста или большом количестве языков можно использовать только правила, их то обычно намного меньше, чем символов в алфавитах. Кстати, настраивается и использование правил - для получения результата можно использовать как совпадение с одним из правил, или же требовать совпадения со всеми правилами одного языка, однако это применимо только для длинных текстов и всегда будет вероятность ошибки.

Возвращает библиотека после детектирования или значение false, что означает невозможность определения или же то, что используемого языка нет в базе данных. В случае успеха мы получаем массив с двух буквенным кодом языка (для примера: "en", "ru" или "ua"), а также дополнительные сведения - полное название языка и, в качестве бонуса, ссылку на статью о языке в Wikipedia.org (конечно, на этом же языке).

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

Напоследок одно замечание о скорости. Самым быстрым вариантом будет использовать только правила, так как их всегда меньше, чем букв и внутри библиотеки мы будем использовать более короткие циклы. В частности, чем длиннее текст и чем больше языков мы определили в базе для поиска, тем быстрее будет вариант только с правилами. Поэтому, для оптимизации вам лучше всего заранее ограничить набор языков самыми вероятными  и удалить те, что вам не нужны - так сократится значительное число циклов и алгоритм будет работать быстрее. Также можно убрать проверку и декодирование строки, если вы уверены, что у вас в системе на вход алгоритма будет подаваться только гарантировано уже преобразованные к кодировке UTF-8 строки.

Официальный сайт проекта: http://code.google.com/p/phplangautodetect/

Лицензия: GNU General Public License v3

Автор: Александр Лозовюк (aleks_raiden, aleks.raiden@gmail.com)

Язык/платформа: PHP 5 (требует модуль mb_strings)

В дистрибутив включён простейший скрипт для экспериментов, он-лайн последняя версия здесь.

Исходный текст с комментариями и замечаниями по реализации описанных выше алгоритмов.

  • http://php.southpark.com.ua/2007/language-detection/
    Определение языка и кодировки. Поддерживается более 50 языков.

    Пользуйтесь на здоровье 😀

  • AleksWhite

    Владимир Лучанинов:
    Это правильно… Но!

    Задача в том чтобы защититься от дурака 🙂 …

    Например, русский пользователь вводя английский или укораинский язык забывает указать на каком языке он ввел.
    А поисковая система «перебрав» текст с определенной долей вероятности сказала бы какой все таки язык используется.

  • Ну может комута эта прога действительно нужна, хотя не назвал бы её незаменимой.

  • Игорь, а чем заменить можно? Честно, я с радостью заменю, так как в моем текущем проекте такой функционал очень и очень нужен.

    • Сергей

      Вот несколько подобных программ. И судя по их количеству эта тема довольно востребована.

      Модуль определения языка текста «МОЯТ» (разработчик С.Н.Калегин)

      Guesser (разработчик компания Flarus)

      Automatic language identifier (разработчик исследовательский центр T-Labs)

      Полиглот 3000 (П3000) (разработчик компания Likasoft)

      Language Identifier by Henrik Falck (разработчик Генрих Фальк)

      PHPLangautodetect (разработчик Александр Лозовюк)

      и т.д.

  • Задача интересная и не тривиальная. Но на столько ли она важна? При работе с многоязыковым сайтом пользователь указывает на каком языке он хочет работать. Поиск информаци также ведётся на языке пользователя. Наполнение контента происходит на нескольких, заведомо известных, языках. Так есть ли смысл определять язык если мы и так знаем, что пользователь работает в китайской секции сайта? Если рассматривать вариант пауков которые лазят по множеству сайтов, то им необходимо определять какой язык сайта, с чем они хорошо справляются. А если писать свой паук, то ИМХО не на ПХП его писать, не та скорость обработки.

    • Сергей

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

  • Ну вы не совсем правы. Сайты и многоязычные сайты лишь частный, очень частный пример. К тому же, не всегда на языке пользователя все ведётся.

    Наполнение также ведётся далеко не всегда на известном языке. Конечно, можно заставить пользователя выбирать, но не всегда можно и нужно.

    Поиск это также далеко не только пауки и веб-поиск. У нас встроенный поисковик, и там необходим такой функционал, при этом подготовка поиска ведётся на РНР, сам сервер или РНР или внешний, на Java, поэтому нам нужно ДО поиска определить язык текста.
    И ещё с десяток задач, в основном в области лингвистики и обработки информации, где такое требуется, те задачи, которые работают без участия пользователя.

  • Прикольно!
    Нужно на днях попробовать проверить информацию Не раз брался за реализацию, но до оконченного решения процесс разработки так и не доходил. Может на тот раз 🙂

  • на вашем блоге всегда можна найти чегото интересного я захожу к вам раза три в год и всегда приятно удивляюсь,а данная инфа мне кокраз очень кстати 😉

  • Ага, мне эта информация какраз попалась очень вовремя.

  • Автору +1. Инфа пригодилась, спс.

  • Спасибою. Искал такой классик, что бы ссылки проверять и сайты распихивать по языкам.

  • Сергей

    Почти начал делать что-то подобное в своем проекте, как рад что не убил время а нашел этот пост.

    еще не проверил насколько оно пригодно, но из описания — то что нужно.

    Спасибо

    • Сергей

      Прога хорошая. Но принцип идентификации языка в корне ошибочный, так как смешивает понятия языка и письменности. Сами знаки (буквы) никакого отношения к языку не имеют! Например, латиницей пишут и французы, и поляки, и вьетнамцы и ещё сотни народов на своих языках, а буквы одни и те же. К тому же, часто люди пишут нетипичной письменностью. Например, латинским буквами по-русски или русскими (кириллицей) по-арабски. В этом случае данным способом ничего определить не получится.
      Короче, идея хорошая, но с точки зрения лингвистики провальная. Однако вполне подойдёт для тестовых и учебных программ.

  • рад, что кому-то пригодилось!

  • Litochkamodern

    Люди! у меня такая проблема ищу свои корн,а точнее корни прабабушки
    не знаю её национальность ,но знаю на слух фразу с её родного языка
    звучит так:шигир му чим сим зо !
    Кто знает помогите (очень важно)

Developers.org.ua