Скачивание, загрузка и использование предварительно обученных векторов GloVe

Содержание

В этой статье будут рассмотрены следующие темы:
* Загрузка и загрузка предварительно обученных векторов
*
Поиск векторов, похожих на заданный вектор
*
«Математика со словами»
*
Визуализация векторов

В конце доступны дополнительные ресурсы для чтения, в том числе оригинальная газета GloVe.

Краткое введение в GloVe

Glo bal Ve ctors для представления слов или GloVe - это алгоритм неконтролируемого обучения для получения векторных представлений слов. Проще говоря, GloVe позволяет нам использовать корпус текста и интуитивно преобразовать каждое слово в этом корпусе в позицию в многомерном пространстве. Это означает, что похожие слова будут помещены вместе.

Если вам нужно подробное объяснение того, как работает GloVe, ссылки на статьи доступны в конце.

Загрузка предварительно обученных векторов

Перейдите на https://nlp.stanford.edu/projects/glove/.
Затем в разделе Загрузить предварительно обученные векторы слов вы можете выбрать любой из четырех вариантов для разных размеров или наборов обучающих данных.

Я выбрал векторы Wikipedia 2014 + Gigaword 5. Вы можете скачать эти точные векторы на http://nlp.stanford.edu/data/glove.6B.zip (ВНИМАНИЕ: ЭТО СКАЧАТЬ 822 МБ)

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

Импорт

Для этого проекта нам нужно будет использовать Numpy, Scipy, Matplotlib и Sklearn.
Если вам нужно установить что-либо из них, вы можете запустить следующее:

pip install numpy
pip install scipy
pip install matplotlib
pip install sklearn

В зависимости от вашей версии Python вам может потребоваться заменить pip на pip3.

Теперь мы можем импортировать нужные нам детали из этих модулей с помощью:

Загрузка векторов

Прежде чем загружать векторы в код, мы должны понять, как форматируется текстовый файл.
Каждая строка текстового файла содержит слово, за которым следуют числа N. Числа N описывают вектор положения слова. N может варьироваться в зависимости от того, какие векторы вы скачали, для меня N равно 50, поскольку я использую glove.6B.50d.

Вот пример строки из текстового файла, сокращенной до первых трех измерений:

business 0.023693 0.13316 0.023131 ...

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

embeddings_dict = {}

Предполагая, что ваш файл Python находится в том же каталоге, что и векторы GloVe, теперь мы можем открыть текстовый файл, содержащий вложения, с помощью:

with open("glove.6B.50d.txt", 'r', encoding="utf-8") as f:

Примечание: вам нужно будет заменить glove.6B.50d.tx t именем текстового файла, который вы выбрали для векторов.

Оказавшись внутри оператора with, нам нужно перебрать каждую строку в файле и разделить строку по каждому пробелу на каждый из его компонентов.

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

Затем мы можем взять оставшуюся часть строки и преобразовать ее в массив Numpy. Это вектор позиции слова.

Наконец, мы можем обновить наш словарь новым словом и соответствующим ему вектором.

Подведем итоги нашего полного кода для загрузки векторов:

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

Поиск похожих векторов

Еще одна вещь, которую мы можем сделать с векторами GloVe, - это найти слова, наиболее похожие на данное слово. Мы можем сделать это с помощью причудливой однострочной функции следующим образом:

Этот сложный, поэтому давайте разберемся с ним.
sorted принимает на вход итерацию и сортирует ее с помощью ключа. В этом случае итерация, которую мы передаем, - это все возможные слова, которые мы хотим отсортировать. Мы можем получить список таких слов, вызвав embeddings_dict.keys ().

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

scipy имеет функцию измерения евклидова расстояния в модуле пространственный, который мы импортировали ранее. Итак, наш окончательный ключ сортировки превращается в:

lambda word: spatial.distance.euclidean(embeddings_dict[word], embedding)

Теперь, если мы хотим ранжировать все слова по близости к данному слову, скажем «король», мы можем использовать:

find_closest_embeddings(embeddings_dict["king"])

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

find_closest_embeddings(embeddings_dict["king"])[:5]

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

find_closest_embeddings(embeddings_dict["king"])[1:6]

Используя мои векторы, glove.6B.50d,

print(find_closest_embeddings(embeddings_dict["king"])[1:6])

печатает: [«принц», «королева», «дядя», «ii», «внук»]

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

Математика со словами

Теперь, когда мы можем превратить любое слово в вектор, мы можем использовать любую математическую операцию, применимую к векторам, к словам.

Например, мы можем складывать и вычитать два слова вместе, как числа. т.е. веточка-ветка + рука ≈ палец

Приведенный выше код выводит «fingernails» в качестве своего основного результата, что, безусловно, вполне логично.

Визуализация векторов

Ничто не помогает лучше понять данные, чем их визуализация.

Чтобы визуализировать векторы, мы сначала будем использовать метод, известный как t-распределенное стохастическое вложение соседей, также известный как t-SNE. t-SNE позволит нам уменьшить, в моем случае, 50 измерений данных до двух измерений. После этого для построения графика достаточно просто использовать диаграмму рассеяния matplotlib. Если вы хотите узнать больше о t-SNE, в конце есть ссылки на несколько статей.

sklearn, к счастью, имеет класс t-SNE, который может сделать нашу работу более управляемой. Чтобы создать его экземпляр, мы можем использовать:

tsne = TSNE(n_components=2, random_state=0)

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

После инициализации класса t-SNE нам нужно получить список каждого слова и соответствующий ему вектор.

words =  list(embeddings_dict.keys())
vectors = [embeddings_dict[word] for word in words]

Первая строка принимает все ключи embeddings_dict и преобразует их в список.

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

Мы также можем вручную указать слова, чтобы отображались только отдельные слова. т.е. words = [«сестра», «брат», «мужчина», «женщина», «дядя», «тетя»]

После получения всех слов, которые мы хотим использовать, и соответствующих им векторов, теперь нам нужно подогнать класс t-SNE к нашим векторам.
Это можно сделать с помощью:

Y = tsne.fit_transform(vectors[:1000])

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

После того, как класс t-SNE завершит подгонку к векторам, мы можем использовать диаграмму рассеяния matplotlib для построения данных:

plt.scatter(Y[:, 0], Y[:, 1])

Само по себе это не очень полезно, так как это просто набор точек. Чтобы улучшить его, мы можем аннотировать график, перебирая каждую точку XY с меткой и вызывая plt.annotate с этими точками XY и с этим метка. Другие входы функции предназначены для важного форматирования. Аннотация в Матплотлибе

Наконец, мы можем показать сюжет с помощью,

plt.show()

Это может отставать на менее мощных компьютерах, поэтому вы можете либо уменьшить количество отображаемых слов, изменив vectors [: 1000] на что-то более похожее на vectors [: 250] или замените слова списком собственного сочинения.

Полный код для визуализации векторов:

Заключение

Полный код доступен в формате Jupyter Notebook и Python на моем GitHub здесь.

С предварительно обученными векторами GloVe можно сделать очень многое. Для более высокоуровневого использования я бы рекомендовал обратиться к официальному README для обучения ваших собственных векторов.

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

Дальнейшее чтение:

Документы:
Оригинальный документ GloVe: https://nlp.stanford.edu/pubs/glove.pdf
Оригинальный документ t-SNE: http: // jmlr .org / paper / volume9 / vandermaaten08a / vandermaaten08a.pdf

Более подробные пояснения к перчаткам:
* https://mlexplained.com/2018/04/29/paper-dissected- перчатка-глобальные-векторы-за-слово-представление-объяснение /
* https://blog.acolyer.org/2016/04/22 / перчатки-глобальные-векторы-для-слов-представления /

Более подробные объяснения t-SNE:
* https://mlexplained.com/2018/09/14/paper- анализ-визуализация-данные-использование-т-сн-объяснение /
* https://distill.pub/2016/misread-tsne/