Как определить расстояние Левенштейна для китайских иероглифов?

Мы разрабатываем систему для нечеткого сопоставления более чем 50 международных языков с использованием стандарта символов Unicode UTF-8, UTF-16 и UTF-32. До сих пор мы могли использовать расстояние Левенштейна для обнаружения ошибок в написании слов с расширенными символами немецкого языка Unicode.

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


person Frank    schedule 12.09.2012    source источник
comment
Да, ханжи хранятся в базовой многоязычной плоскости, поэтому просто используйте char16_t, и он должен быть достаточно большим, чтобы вместить их все.   -  person obataku    schedule 12.09.2012
comment
Однако обратите внимание, что это не даст вам «похожие персонажи», а только «похожие фразы».   -  person nneonneo    schedule 12.09.2012
comment
@OP Вы уверены, что тег «c++» правильный?   -  person jogojapan    schedule 12.09.2012
comment
@oldrind, спасибо за ответ. Мы попробуем char16_t.   -  person Frank    schedule 12.09.2012
comment
@nnneonnro, спасибо за ответ. Я ценю ваше разъяснение по поводу «похожих фраз».   -  person Frank    schedule 12.09.2012
comment
@jogojapan, я выбрал тег c++, потому что мы реализуем нашу систему на c++. Спасибо.   -  person Frank    schedule 12.09.2012
comment
Ради максимальной корректности: Есть Ханзи, которые не представлены Базовой Многоязычной Плоскостью (т.е. они должны быть либо закодированы как UCS-4, либо как последовательность двух 16-битных символов в UTF-16). Они редки даже в китайском, но встречаются. С этим связан прекрасный вопрос: stackoverflow.com/questions/5567249/   -  person jogojapan    schedule 12.09.2012


Ответы (2)


Во-первых, просто поясню: китайский иероглиф как таковой не эквивалентен немецкому или английскому слову. Большинство вещей, которые вы считаете словами (используя семантическое или синтаксическое определение слова), состоят из 1-3 символов. К таким последовательностям символов легко применить расстояние Левенштейна, представив их как последовательности кодовых точек UCS-2 или UCS-4. Поскольку большинство слов короткие (особенно слова длиной 1 или 2 символа), их использование может быть ограничено.

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

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

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

  • Вам нужно расположить штрихи или компоненты в порядке. Очевидным кандидатом является канонический порядок черт иероглифа, описанный в lexica, и даже есть веб-сайты со словарями с анимированными диаграммами порядка штрихов. Однако известные мне источники данных (для японского) генерируют эти анимации как последовательности растровой графики; Я никогда не видел считываемых человеком или машиной кодов, которые представляли бы последовательность штрихов (или даже имена отдельных штрихов) в форме, пригодной для расчета расстояния редактирования.

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


Быстрый ответ на комментарий Ларсмана ниже: в стандарте Unicode определены две связанные концепции (ниже я ссылаюсь на версия 6.0, глава 12):

  1. #P8# <блочная цитата> #P9# #P10#
  2. Последовательности идеографического описания (раздел 12.2): Unicode определяет кодовые точки для основных компонентов символов (большинство из них в любом случае могут сами использоваться как отдельные символы), и существуют кодовые точки, используемые для склеивания их вместе для формирования последовательности компонентов, описывающих композиция более сложного характера. Таким образом, это работает аналогично объединению символов, но есть важные отличия:

    1. The order of components is not uniquely defined
    2. Для таких последовательностей нет определения механизма рендеринга.
    3. Отсутствует сопоставление обычных символов с соответствующими последовательностями идеографического описания (хотя в Стандарте упоминается, что такие сопоставления в некоторой степени существуют в источниках, которые они использовали для составления набора символов Хань).

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

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

person jogojapan    schedule 12.09.2012
comment
(Здесь нуб азиатских языков, спрашиваю из любопытства) Нет ли какой-либо нормализации Unicode, которая дает какое-то базовое разложение символа? - person Fred Foo; 12.09.2012
comment
@larsmans Интересный момент. Я добавил несколько ссылок, о которых я знаю. - person jogojapan; 12.09.2012
comment
Очаровательный! Я понимаю, почему для китайцев сложно определить расстояние редактирования. Но разве проблема порядка не решается легко, просто навязывая произвольный, например. на основе кодовых точек? - person Fred Foo; 12.09.2012
comment
@larsmans Хм ... если мы предположим, что каждый компонент на самом деле имеет кодовую точку (если мы спустимся на уровень штриха, что может быть не так), то все же порядок, основанный на кодовых точках, может недостаточно хорошо отражать то, что как выглядит персонаж (и наша мера расстояния редактирования должна учитывать это, я полагаю). Например, 坂 и 板 подобны (их правые части идентичны), но если мы разложим их, скажем, на 土+反 и 木+反 соответственно, то порядок должен быть таким. Но порядок, основанный на кодовых точках, может изменить второй на 反+木, тем самым излишне увеличивая расстояние редактирования. - person jogojapan; 12.09.2012
comment
Верно, это будет вставка и удаление вместо замены. Спасибо за разъяснения и +1 к ответу. - person Fred Foo; 12.09.2012

Я написал пакет Python fuzzychinese для исправления опечаток в китайских словах.

Как сказал @jogojapan, если вы действительно хотите рассчитать расстояние Левенштейна, имеет смысл использовать структуры подсимволов, такие как радикалы или штрихи. Вы можете использовать классы Stroke() или Radical() из fuzzychinese, чтобы разбить символы, а затем вычислить расстояние Левенштейна.

Однако я не уверен, что расстояние Левенштейна хорошо работает для исправления орфографических ошибок в китайских словах. В пакете, который я написал, я вычислил вектор tf–idf для штрихов n-грамм и использовал косинусное сходство для сопоставления слов.

person Lala La    schedule 14.11.2019