Хранение ngram модели python
Я реализую языковую модель как личный вызов, как часть простого веб-приложения. Тем не менее, я избегал использования NLTK, однако столкнулся с MemoryError с достаточно большим корпусом (словарь около 50000 и количество триграмм было около 440000 - я использовал стандартный словарь python и после пробного массива numpy сохранял все вероятности слова-нграммы в качестве матрицы). Поэтому кажется, что решение состоит в том, чтобы использовать более эффективную структуру данных, что было упомянуто здесь для обучения языковой модели с использованием Google Ngrams или для хранения модели на диске. В целом, не могли бы вы порекомендовать, какой подход может быть лучше для хранения модели ngram (в памяти или на диске) и после ее использования в качестве части веб-приложения?
1 ответ
Вы не первый, кто попробовал языковую модель N-грамм, и не последний.
Как отмечается в другом решении, мы можем хранить большой словарь в древовидной структуре, чтобы все n-граммы, которые разделяют первые k слов (k Если вы априори сохранили n-граммы в этом формате, часто бывает целесообразно его обрезать. То есть, если вы добавите в модель переменную count, мы сможем удалять элементы с низкой частотой. Если ваши данные беспорядочные, то низкочастотные n-граммы часто соответствуют неправильно написанным словам или ошибкам в реальном слове. Даже с учетом эффективности древовидной структуры трудно эффективно расширить вышеперечисленное для n-граммов для n > 3, если у вас нет небольшого словаря, такого как символы. Для умеренно высоких значений n, таких как n=6, популярное решение использует (модифицированное) сглаживание Кнезера-Нея. Библиотека вроде эффективен и имеет интерфейс Python. Хотя для больших корпусов по-прежнему рекомендуется обрезка при построении вашей собственной модели, а также сжатие, подобное Trie, для создания двоичного файла из модели ARPA. Это дает логарифмические вероятности в качестве оценки. Моя первая 6-граммовая модель была 11Гб из корпуса 7Гб. Я обрезал и сжал это, чтобы получить разумную модель на 400 МБ. После загрузки он был очень быстрым. Разумно сконцентрировав свой корпус, должно быть легко получить модель, которая работает для веб-приложения. Аналогичные чисто основанные на Python методы для интерполяции на основе Кнезера-Нея доступны через установку pip. Канонический документ для самостоятельной реализации модели можно найти здесь: Эмпирическое исследование методов сглаживания для языкового моделирования Для очень больших n, где вышеперечисленные методы не работают, вы можете использовать свой корпус для создания встраивания и использовать рекуррентную нейронную сеть, такую как сеть на основе LSTM или GRU, для вывода либо логарифмических вероятностей кортежа, либо самих вероятностей. Это не так сложно, если у вас есть ручка Keras или Pytorch. Что-то вроде структуры двухслойного LSTM с вниманием должно работать хорошо. Существует множество вещей, которые можно было бы сделать в направлении нейронной сети для кодирования n-граммов.
Я разделю свой ответ на две части, первая из которых заключается в том, что хранить его в виде словарей - плохая идея, а вторая - оптимальная структура данных для хранения нграмм.
Рассмотрите возможность хранения в словаре следующих слов: "Bond", "Boat", "Build", размер словаря, содержащего эти ключи, хэшированные до некоторого целого числа, будет приблизительно пропорционален количеству слов + их символов. Таким образом, технически мы тратим дополнительное место для хранения определенных писем, которые могут повторяться. Теперь проблема становится очевидной, мы тратим много дополнительной памяти на хранение частей строк, которые нам не нужно повторно хранить.
Остается вопрос, какова идеальная структура данных, которая может быть использована здесь. Реквизиты для этой структуры данных:
- Эффективное хранение
- Извлечение значений (примерно постоянное время)
Если мы рассмотрим, какая структура данных соответствует этим требованиям, то сразу же приходит на ум Trie или, точнее, Prefix Trie. Присущая структура Trie полезна, потому что мы экономим место на отдельных символах, которые мы могли бы хранить несколько раз. С небольшим набором слов, как в моем примере выше, проблема не очень большая. Однако, поскольку длина нашего набора слов увеличивается, мы скоро исчерпаем пространство, используя Хэш-таблицу / словарь.
Надеюсь, это помогло.