Структура данных для многоязычного словаря? - PullRequest
10 голосов
/ 15 августа 2011

Сводка в одну строку: предлагает оптимальную структуру (скорость поиска / компактность) данных для многоязычного словаря, представляющего преимущественно индоевропейские языки (список внизу).

Допустим, вы хотите создать некоторую структуру (-и) данных для реализации многоязычного словаря, скажем, самых популярных европейских языков (N ~ 40) в Интернете, ранжируя выбор языка по количеству веб-страниц. (приблизительный список языков, приведенный внизу этого вопроса). Цель состоит в том, чтобы сохранить рабочий словарный запас каждого языка (то есть 25 000 слов для английского языка и т. Д.). Исключены собственные существительные. Не уверен, сохраняем ли мы множественное число, спряжения глаголов, префиксы и т. Д. Или добавляем специфичные для языка правила того, как они образованы из существительных в единственном числе или основ глагола. Также вы можете выбрать способ кодирования и обработки акцентов, дифтонгов и специальных символов для конкретного языка, например, возможно, где это возможно, мы транслитерируем вещей (например, романизируем немецкий ß как 'ss', затем добавляем правило для его преобразования). Очевидно, что если вы решите использовать 40-100 символов и три, существует слишком много ветвей, и большинство из них пустые.

Определение задачи: Какую бы структуру данных вы не использовали, вы должны выполнить оба следующих действия:

  1. Основная операция при поиске состоит в том, чтобы быстро получить указание «Да, это допустимое слово в языках A, B и F, но не в C, D или E». Так, если N = 40 языков , ваша структура быстро возвращает 40 логических значений.
  2. Дополнительная операция - вернуть некоторый указатель / объект для этого слова (и всех его вариантов) для каждого языка (или ноль, если он был недействительным). Этот указатель / объект может быть определен пользователем, например, часть речи и словарное определение / тезаурус сравним / список переводов на другие языки / ... Он может быть специфичным для конкретного языка или независимым от языка, например общее определение pizza )

И основной показатель для эффективности - это компромисс между а) компактностью (для всех N языков) и б) скоростью поиска . Время вставки не важно.

Итак:

  1. Каковы возможные структуры данных, как они ранжируются на скорость поиска / кривая компактности?
  2. У вас есть единая структура для всех N языков или раздел, например германские языки в одну подструктуру, славянский в еще один? или просто N отдельных структур (которые позволят вам Хаффман-кодировать)?
  3. Какое представление вы используете для символов, ударений и специальных символов для конкретного языка?
  4. В идеале, дать ссылку на алгоритм или код, особенно. Python или еще C. -

(Я проверил SO, и были связанные вопросы, но не этот точный вопрос. Конечно, не ищу базу данных SQL. Одна статья 2000 года, которая может быть полезной: "Оценка использования английского и неанглийского языка на WWW "- Grefenstette & Nioche . И один список многоязычных словарей ) Ресурсы: два онлайн-многоязычных словаря: Interglot (en / ge / nl / fr / sp / se) и LookWayUp (en <-> fr / ge / sp / nl / pt) .


Языки для включения:

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

Вероятно, включают русский, славянский, турецкий, исключая арабский, иврит, иранский, индийский и т. Д. Возможно, включите и малайскую семью. Скажи мне, что достижимо.

Ответы [ 4 ]

4 голосов
/ 15 августа 2011

Я не уверен, будет ли это работать для вашей конкретной проблемы, но вот одна мысль, о которой стоит подумать.

Структура данных, которая часто используется для быстрых и компактных представлений языка, является минимальнойгосударственный DFA для языка.Вы можете сконструировать это, создав три языка для языка (который сам является автоматом для распознавания строк в языке), а затем используя канонические алгоритмы для построения DFA с минимальным состоянием для языка.Это может потребовать огромного количества времени на предварительную обработку, но как только вы построите автомат, у вас будет чрезвычайно быстрый поиск слов.Вы бы просто начали с начального состояния и следовали за помеченными переходами для каждой буквы.Каждое состояние может кодировать (возможно) 40-битное кодирование значения для каждого языка, независимо от того, соответствует ли состояние слову в этом языке.

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

3 голосов
/ 13 мая 2012

Я не буду выигрывать очки здесь, но кое-что.

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

Сначала сформулируйте свои первые требования в документе и запрограммируйте прототип интерфейса.Задавая структуры данных до алгоритмической концепции, я часто вижу сложную бизнес-логику.Тогда можно было бы начать неправильно, рискуя Feature Creep .Или преждевременная оптимизация, как та латинизация, которая может не иметь никакого преимущества, и двунаправленность бара.

Возможно, вы можете начать с некоторых активных проектов, таких как Reta Vortaro ;его XML может быть неэффективным, но даст вам некоторые идеи для организации.Есть несколько академических лингвистических проектов .Наиболее релевантным аспектом может быть stemming : распознавание greet / grees / greeted / greeter /reeting / greetings (@smci) как принадлежащее к той же (основной) записи.Вы хотите взять уже запрограммированные стеммеры;они часто хорошо проверены и уже применяются в электронных словарях.Я бы посоветовал исследовать эти проекты, не теряя много энергии, импульса для них;просто достаточно, чтобы собрать идеи и посмотреть, где они могут быть использованы.

Структуры данных, которые можно придумать, ИМХО имеют второстепенное значение.Я сначала собрал бы все в четко определенной базе данных , а затем сгенерировал программно используемые структуры данных .Затем вы можете сравнить и измерить альтернативы.И это может быть для разработчика самой интересной частью - создание красивой структуры данных и алгоритма.


Ответ

Требование:

Карта слова в список [язык, определение определения].Список определений.

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

Одно слово может иметь несколько определений (книга = (существительное) материал для чтения, = (глагол) резервное использование местоположения).

Примечания

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

Таким образом, общая абстрактная структура данных будет выглядеть так:

Map<String /*Word*/, List<DefinitionEntry>> wordDefinitions;
Map<String /*Language/Locale/""*/, List<Definition>> definitions;

class Definition {
    String content;
}

class DefinitionEntry {
    String language;
    Ref<Definition> definition;
}

Конкретная структура данных:

WordDefinitions лучше всего использовать с оптимизированной хэш-картой.


Пожалуйста, позвольте мне добавить:

Я наконец-то придумал конкретную структуру данных.Я начал со следующего:

MultiMap от Guava - это то, что мы имеем здесь, но коллекции Trove с примитивными типами - это то, что нужно, если использовать компактное двоичное представление в ядре.

Можно было бы сделать что-то вроде:

import gnu.trove.map.*;

/**
 * Map of word to DefinitionEntry.
 * Key: word.
 * Value: offset in byte array wordDefinitionEntries,
 * 0 serves as null, which implies a dummy byte (data version?)
 * in the byte arrary at [0].
 */
TObjectIntMap<String> wordDefinitions = TObjectIntHashMap<String>();
byte[] wordDefinitionEntries = new byte[...]; // Actually read from file.

void walkEntries(String word) {
    int value = wordDefinitions.get(word);
    if (value == 0)
        return;
    DataInputStream in = new DataInputStream(
        new ByteArrayInputStream(wordDefinitionEntries));
    in.skipBytes(value);
    int entriesCount = in.readShort();
    for (int entryno = 0; entryno < entriesCount; ++entryno) {
        int language = in.readByte();
        walkDefinition(in, language); // Index to readUTF8 or gzipped bytes.
    }
}
1 голос
/ 13 мая 2012

Распространенным решением этой проблемы в области НЛП является конечный автомат.Смотри http://www.stanford.edu/~laurik/fsmbook/home.html.

0 голосов
/ 09 мая 2012

Легко.

Создайте минимальную, идеальную хэш-функцию для ваших данных (объединение всех словарей, создайте хэш автономно) и наслаждайтесь O (1) поиск на всю оставшуюся вечность.

Использует тот факт, что ваши ключи известны статически.Не заботится о ваших акцентах и ​​т. Д. (Нормализуйте их перед хэшированием, если хотите).

...