Как построить векторы слов особого случая

Использование предварительно обученных векторов слов — это хорошо и прекрасно и приносит огромную пользу вашим моделям, например, Google word2vec содержит 3 миллиона уникальных слов (словарный запас), которые были обучены на миллиардах текстов. Эти векторы слов удивительно тонко настроены и представляют семантическое значение слов с чрезвычайно высокой точностью. Я имею в виду, что они находятся на самом современном уровне, почему мы должны думать о создании собственных векторов слов?

Почему вы должны создавать свои собственные векторы слов

Представьте себе следующий сценарий

Вы — ярый поклонник фэнтези, и у вас есть конкретная серия романов [Malazan book of the Fallen], от которой вы и ваши товарищи настолько без ума, что вы все не можете дождаться, чтобы выразить свои эмоции автору [Стивену Эриксону] о том, что вы все думаете об этих книгах. В классической попытке произвести впечатление на других ваших хардкорных фанатов и показать, что вы — фанат книги номер один, вы решили построить модель чувств, которая сможет анализировать их отзывы и точно распознавать их эмоциональное состояние, а затем переводить его в пять лаконичных слов (Очень хорошо, Хорошо, Хорошо, Плохо, Очень плохо).

В своем энтузиазме вы решили использовать google word2vec (ведь в нем 3 миллиона слов), после чего обнаружили очень очевидную ошибку. Вы и ваши товарищи по несчастью часто используете в своих рецензиях слова, которых нет в 3-миллионном словаре google word2vec (что!!! но книга была написана на английском языке), такие слова как Bugg, Gothos, Seguleh и т.д., (я думаю, что более 1 миллиарда текстов, на которых тренировался google word2vec, не содержали этих слов). Даже с этими загадочными словами, содержащими богатые смысловые значения (например, «дыхание Гуда» может означать «вау», «удивительно», «шок» и т.д. в зависимости от контекста), вы все равно думаете, что сможете построить достаточно точную модель с помощью остальных слов, которые можно найти в словаре google word2vec.

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

Ладно, хватит пугать вас, но что это за ошибки? В данном контексте НЛП это то, что я буду называть _неправильно понятыми ошибками_, они возникают в результате того, что значение слова резко меняется, когда оно помещается в другой мир, вы поймете это гораздо лучше на примере. Например, возьмем слово «гореть», это слово в реальности означает, когда что-то в какой-то момент воспламенилось огнем или вот-вот воспламенится, но в мире Малазана это слово имеет совершенно другое значение и никак не связано с ним, это имя бога. Ниже приведены примеры слов с их различным значением.

Слова Значение в реальном мире Значение в Малазанском мире
Капот Металлический кожух двигателя автомобиля или ткань. Имя бога смерти.
Высокий кулак Взятые вместе, они ничего не значат, но взятые отдельно, они означают разные вещи. В основном они воспринимаются как одно слово, которое означает ранг в военной структуре.
Любезно По-доброму Имя солдата (который даже не является добрым).
Водолазы Тот, кто погружается глубоко под воду. Перевертыш, превращающийся из одного существа в несколько.
Curdle Молоко, которое портится Имя давно умершего Солетакена (дракона).

Теперь вы видите, как подобные заблуждения могут внести ужасные ошибки в вашу модель, мало того, есть также слова, которые сами по себе ничего не значат или значат совершенно другое в мире Малазана, но должны быть объединены с другим словом, прежде чем значение слова будет раскрыто, например, Т’лан Имасс, Высший маг, Высший кулак, Ампелас Коренной и т.д.

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

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

Построение векторов Word2Vec

Мы закончили с частью построения word2vec, теперь переходим к части кодирования. Давайте импортируем все необходимые модули, необходимые для построения модели.

Этот проект требует, чтобы вы прошли через детектор построения модели фразы, так как это необходимое условие.

import glob
import numpy as np

from gensim.models import callbacks
from gensim.models.word2vec import Word2Vec
from gensim.models.callbacks import CallbackAny2Vec
from gensim.models.phrases import Phrases

%run utils.py
Вход в полноэкранный режим Выход из полноэкранного режима

В приведенном выше коде нет ничего нового, кроме маленькой инструкции в строке 9 %run utils.py эта инструкция выполняет коды, найденные в файле*utils.py* в текущем пространстве имен. Этот файл содержит очень полезный общий инструмент, который подает данные в нашу модель при обучении без необходимости загружать весь текстовый файл в память, он был определен, когда мы строили модель детектора фраз. Определение его здесь снова займет ненужное место и отвлечет нас от нашей цели, поэтому перейдите сюда, чтобы посмотреть, как он был определен.

def load_phrase_detector_model(fname, reduce_size=False):
    """Load a phrase detector model from disk.

    Parameters:
    fname: str
        path to the pretrained phrase detector model

    reduce_size: bool
        should be False if the full sized model was saved
        during training of the phrase detector model, then it would 
        be reduced in size when loaded, else it should False

        will raise an AttributeError if set to True and the phrase 
        detector model is not a full sized model
    """
    phrases = Phrases.load(fname)

    print(f"Loading complete")
    return phrases.freeze() if reduce_size else phrases

# load a phrase detector model
phrase_model_path = "malaz_phrase_detector"
phrases = load_phrase_detector_model(phrase_model_path, reduce_size=True)

sentences_iterator = CustomPathLineSentences('Books', include_phrase=True,
                                             phrase_model=phrases)
Вход в полноэкранный режим Выход из полноэкранного режима

Если модель детектора фраз передана пользовательскому итератору, то по мере прохождения предложений он объединяет любые комбинации слов, составляющие обнаруженную в предложении фразу, в одно слово и возвращает измененное предложение (например, «High Fist» в «High_Fist»).

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

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

Текстовые файлы должны иметь ту же структуру, которая описана в проекте детектора фраз.

model_path = "malaz_word2vec.bin"

class CustomCallback(CallbackAny2Vec):
    """Create a custom callback that save the model 
    at the end of each epoch and at the end of training,
    while also reporting the current epoch value."""

    def __init__(self):
        self.__epoch_trained = 0

    def on_epoch_end(self, model):
        model.save(model_path)
        self.__epoch_trained += 1
        print(self.__epoch_trained, end=' | ')

    def on_train_end(self, model):
        model.save(model_path)
Вход в полноэкранный режим Выход из полноэкранного режима
epochs = 1000
vector_size = 300
min_count = 3
num_workers = 4
window_SIZE = 5
subsampling = 1e-3

model = Word2Vec(workers=num_workers,
                 vector_size=vector_size,
                 min_count=min_count,
                 window=window_size,
                 sample=subsampling)

# build word vector vocabulary
model.build_vocab(sentences_iterator)

# training word2vec
model.train(sentences_iterator, total_examples=model.corpus_count,
            epochs=epochs, compute_loss=True,
            callbacks=[CustomCallback()])

# just for precaution sake
model.save(model_path)
Войти в полноэкранный режим Выйти из полноэкранного режима

Это может занять минуты или часы в зависимости от вашего компьютера, я проспал после 4 часов, а он все еще был на 300 эпохах. Вот почему я сохраняю его после каждой эпохи и когда он, наконец, завершает обучение [во время, когда я, вероятно, спал] и снова (чтобы быть вдвойне уверенным, что он был сохранен). С помощью этого простого вектора слов можно построить довольно сложную модель анализа настроений вокруг этого автора, но точность резко упадет, если добавить другого автора.

Бог любит тебя!

Оцените статью
Procodings.ru
Добавить комментарий