Я надеялся немного подумать о сохранении данных n- граммы. В моем проекте я пытаюсь решить лингвистические проблемы, когда я знаю все ( n -1) элементы данных и хочу статистически угадать мой n, используя линейную интерполяцию по всем применимым n- диаграммам. (Да, есть тегер, который назначает теги известным словам в соответствии с его лексиконом, и дерево суффиксов, которое пытается угадать вид слова для неизвестных слов; обсуждаемый здесь компонент n -gram будет решен с целью устранения неоднозначности.)
Мой первоначальный подход состоял бы в том, чтобы просто сохранить все наблюдаемые n- грамм (для n = 1,3), то есть данные монограммы, биграммы, триграммы, в соответствующих базах данных SQL и назвать их день. Но требования моего проекта могут измениться, чтобы включить другие длины вектора ( n ), и я хотел бы, чтобы мое приложение адаптировалось к 4-граммовому без большой работы (обновление схемы, обновление кода приложения и т. Д.); в идеале я бы просто сказал, чтобы мое приложение теперь работало с 4-граммами без особого (или вообще) значительного изменения кода и обучения его данных из заданного источника данных.
Подводя итог всем требованиям:
- Возможность хранить данные n- граммы (изначально для n = {1, 2, 3}
- Возможность изменения того, какие типы n- диаграмм следует использовать (между запусками приложения)
- Возможность ( пере ) обучения данных n- граммы (между запусками приложения)
Возможность запрашивать хранилище данных (например, если я наблюдал A, B, C, я хотел бы знать наиболее часто наблюдаемый элемент для того, что может последовать, используя мои обученные 4-, 3-, 2-, 1-граммовые наборы данных )
Скорее всего, приложение будет загружено для чтения, наборы данных, скорее всего, не будут переучиваться так часто
- В решении используется .NET Framework (до 4.0)
Какой дизайн лучше подходит для такой задачи?
- Фиксированная таблица, управляемая сервером SQL (MSSQL, MySQL, ...) для каждого n (например, выделенные таблицы для биграмм, триграмм и т. Д.)
- Или решение для базы данных документов NoSQL, в котором в качестве ключа документа хранятся первые n -1, а сам документ содержит n- ое значение и наблюдаемые частоты?
- Или что-то другое?
источник
Ответы:
Учитывая, что вы не будете знать оптимальный диапазон N, вы определенно захотите его изменить. Например, если ваше приложение прогнозирует вероятность того, что определенный текст является английским, вы, вероятно, захотите использовать N-граммы символов для N 3..5. (Это то, что мы обнаружили экспериментально.)
Вы не поделились информацией о вашем приложении, но проблема достаточно ясна. Вы хотите представить N-граммовые данные в реляционной базе данных (или решении на основе документов NoSQL). Прежде чем предлагать собственное решение, вы можете взглянуть на следующие подходы:
Теперь, не прочитав ни одной из вышеуказанных ссылок, я предлагаю простой подход к реляционной базе данных, использующий несколько таблиц, по одной для каждого размера N-граммы. Вы можете поместить все данные в одну таблицу с максимально необходимыми столбцами (т.е. хранить биграммы и триграммы в ngram_4, оставляя последние столбцы пустыми), но я рекомендую разбить данные на части. В зависимости от вашего механизма базы данных, одна таблица с большим количеством строк может негативно повлиять на производительность.
Далее я дам вам запрос, который вернет наиболее вероятное следующее слово для всех ваших таблиц ngram. Но сначала, вот некоторые примеры данных, которые вы должны вставить в приведенные выше таблицы:
Чтобы запросить наиболее вероятное следующее слово, вы должны использовать такой запрос.
Если вы добавите больше таблиц ngram, вам нужно будет добавить еще одно предложение UNION к вышеуказанному запросу. Вы можете заметить, что в первом запросе я использовал word1 = @ word3. И во втором запросе word1 = @ word2 AND word2 = @ word3. Это потому, что нам нужно выровнять три слова в запросе для данных ngram. Если мы хотим получить наиболее вероятное следующее слово для последовательности из трех слов, нам нужно сравнить первое слово в данных биграммы с последним словом из слов в последовательности.
Вы можете настроить весовые параметры по своему желанию. В этом примере я предположил, что старшие порядковые n граммов будут более надежными.
PS Я бы структурировал программный код для обработки любого количества таблиц ngram_N через конфигурацию. Вы можете декларативно изменить программу на использование диапазона N-грамм N (1..6) после создания таблиц ngram_5 и ngram_6.
источник
ngram_2
, фразаbuilding with
имеет частоту 0,5. Тот же вопрос@bigramWeight
, что это? Я думаю, что поле freq будет обновляться каждый раз, когда мы обновляем базу данных. Т.е. если пользователь введет больше строки, частота для этой строки будет пересчитана? 0,5 - это 0,5 процента общего времени использования или частоты появления каждой фразы?Вопреки тому, что предлагают другие, я бы посоветовал избегать любых структур данных, более сложных, чем хэш-карта или хранилище значений ключей.
Помните о ваших требованиях к доступу к данным: a) 99% запросов - запросите ngram "aaa-bbb-ccc" и получите значение (или 0); b) 1% запросов - добавьте / обновите число определенных ngram; c) нет (с).
Самый эффективный способ - получить его одним поиском. Вы можете использовать за пределами (или экранированный) разделитель, чтобы объединить полный n-грамм в одну строку (например, «alpha | beta | gamma» для 3-граммы, «alpha» для униграммы и т. Д.) И просто получить это ( по хэшу этого). Вот как это делает довольно много программного обеспечения НЛП.
Если ваши данные ngram малы (скажем, <1 ГБ) и помещаются в памяти, то я бы предложил использовать эффективную структуру памяти в программе (хеш-карты, деревья, попытки и т. Д.), Чтобы избежать накладных расходов; и просто сериализовать / десериализовать в плоские файлы. Если ваши данные ngram составляют терабайты или больше, вы можете выбрать хранилища ключей-значений NoSQL, разделенные на несколько узлов.
Для повышения производительности вы можете захотеть заменить все слова везде целочисленными идентификаторами, чтобы ваш основной алгоритм вообще не видел (медленных) строк; тогда немного по-другому реализовать ту же идею.
источник
Не самая эффективная, но простая и встроенная в базу данных, как вы хотите:
У wordpos должны быть индексы на документе и поз.
биграммы это:
Затем вы можете считать () и группировать свой путь к частотам и прочее.
Чтобы перейти на триграммы, легко сгенерировать эту строку, чтобы включить слово 3.
Я сделал это раньше на самом деле (хотя SQL там, вероятно, немного ржавый). Я остановился на наборе плоских файлов, которые можно было легко найти, а затем стереть с диска. Вид зависит от вашего оборудования, как сделать это лучше.
источник
Пытаясь улучшить простой поиск в моих приложениях по биграммам и триграммам из униграмм, по сути, я понял ваш вопрос.
Если одним из требований является возможность запроса распределенной файловой системы или базы данных, то это может быть также интересно для вас: в статье Pibiri и Venturini 2018 «Эффективная обработка массивных наборов данных N-граммы» описывается эффективный способ хранения данных N-граммы в сроки выполнения и пространство. Они предложили свою реализацию на https://github.com/jermp/tongrams
Каждое «n» из n-граммов хранится в отдельной таблице, доступ к которой осуществляется с помощью минимальной идеальной хеш-функции с очень быстрым выбором и запросом. Таблицы статичны и построены по основному коду с использованием ввода в формате текстовых файлов Google n-грамм.
Я еще не использовал этот код, но есть много способов, которыми вы могли бы с вашими открытыми требованиями о том, откуда ваши запросы.
Один из способов: если .NET-эквивалент сервлета используется с базой данных или хранилищем данных, и если вам необходимо сэкономить место для хранения, то сохранение каждой таблицы ngram в двоичном виде в базе данных / хранилище данных в виде таблицы - это один вариант (одна база данных / datastore таблица для результирующего статического файла эффективного кода ngram для всех 1 граммов, еще один для всех 2 граммов и т. д.). Запросы будут выполняться путем вызова эффективного n-граммового кода (обернутого, чтобы быть доступным для вашего сервлета). Это обходной путь для создания распределенной базы данных, которая использует эффективный n-граммовый код для доступа к файлам в распределенной файловой системе. Обратите внимание, что каждая двоичная таблица базы данных / хранилища данных имеет ограничение на размер файла базовой файловой системы.
источник