Встраивание в перчатки
Чтобы загрузить предварительно обученные вложения GloVe, мы будем использовать пакет с именем torchtext
. Он содержит другие полезные инструменты для работы с текстом, которые мы увидим позже в курсе. Документация по векторам torchtext GloVe доступна по адресу: https://torchtext.readthedocs.io/en/latest/vocab.html#glove
Начните с загрузки набора вложений GloVe. При первом запуске приведенного ниже кода Python загрузит большой файл (862 МБ), содержащий предварительно обученные встраивания.
import torch
import torchtext
glove = torchtext.vocab.GloVe(name="6B", # trained on Wikipedia 2014 corpus of 6 billion words
dim=50) # embedding size = 100
Давайте посмотрим, как выглядит вложение слова car:
glove['cat']
Tensor ([0.4528, -0.5011, -0.5371, -0.0157, 0.2219, 0.5460, -0,6730, -0,6891, 0,6349, -0,1973, 0.6349, -0,1973, 0.3368, 0,7735, 0,9009, 0,3849, 0.3837, 0,2657, -0,0806, 0.6109, -1.2894, 0.2231, -0.6158, 0.2170, 0.3561, 0.2170, 0.3561, 0.4450, 0.6089, -1.1633, -1.1579, 0.3612, 0.1047, -0.7832, 1.4352, 0.1863, -0.2611, 0,8328, -0.2312, 0.3248, 0,1449, -0,4455, 0,3350, -0,9595, -0,0975, 0,4814, -0,4335, 0,6945, 0,9104, -0,2817, 0,4164, -1,2609, 0,7128, 0,2378])
Это факельный тензор размерности (50,). Трудно определить, что означает каждое число в этом вложении, если вообще что-либо. Однако мы знаем, что в этом пространстве вложения есть структура. То есть расстояния в этом пространстве вложения имеют смысл.
Измерение расстояния
Чтобы исследовать структуру пространства вложения, необходимо ввести понятие расстояния. Вы, вероятно, уже знакомы с понятием евклидова расстояния. Евклидово расстояние двух векторов x=[x1,x2,...xn] и y=[y1,y2,...yn] есть просто 2-норма их разности x−y.
Функция PyTorch torch.norm
вычисляет для нас 2-норму вектора, поэтому мы можем вычислить евклидово расстояние между двумя векторами следующим образом:
x = glove['cat']
y = glove['dog']
torch.norm(y - x)
тензор (1,8846)
Косинусное сходство – это альтернативная мера расстояния. Косинусное подобие измеряет угол между двумя векторами и имеет то свойство, что оно учитывает только направление векторов, а не их величины. (Мы будем использовать это свойство в следующем классе.)
x = torch.tensor([1., 1., 1.]).unsqueeze(0)
y = torch.tensor([2., 2., 2.]).unsqueeze(0)
torch.cosine_similarity(x, y) # should be one
тензор([1.])
Косинусное сходство — это мера подобия, а не мера расстояния: чем больше сходство, тем ближе вложения слов друг к другу.
x = glove['cat']
y = glove['dog']
torch.cosine_similarity(x.unsqueeze(0), y.unsqueeze(0))
тензор ([0,9218])
Сходство слов
Теперь, когда у нас есть понятие расстояния в нашем пространстве вложений, мы можем говорить о словах, которые находятся близко друг к другу в пространстве вложений. А пока давайте воспользуемся евклидовыми расстояниями, чтобы посмотреть, насколько разные слова близки к слову кошка.
word = 'cat'
other = ['dog', 'bike', 'kitten', 'puppy', 'kite', 'computer', 'neuron']
for w in other:
dist = torch.norm(glove[word] - glove[w]) # euclidean distance
print(w, float(dist))
собака 1.8846031427383423
велосипед 5.048375129699707
котенок 3.5068609714508057
щенок 3.0644655227661133
воздушный змей 4.210376262664795
компьютер 6.030652046203613
нейрон 6.228669166564941
На самом деле, мы можем просматривать весь наш словарь в поисках слов, наиболее близких к точке в пространстве вложения — например, мы можем искать слова, наиболее близкие к другому слову, такому как кошка.
def print_closest_words(vec, n=5):
dists = torch.norm(glove.vectors - vec, dim=1) # compute distances to all words
lst = sorted(enumerate(dists.numpy()), key=lambda x: x[1]) # sort by distance
for idx, difference in lst[1:n+1]: # take the top n
print(glove.itos[idx], difference)
print_closest_words(glove["cat"], n=10)
собака 1.8846031
кролик 2.4572797
обезьяна 2.8102052
кошки 2.8972247
крыса 2.9455352
зверь 2.9878407
монстр 3.0022194
домашнее животное 3.0396757
змея 3.0617998
щенок 3.0644655
print_closest_words(glove['nurse'])
врач 3.1274529
дантист 3.1306612
медсестры 3,26872
педиатр 3.3212206
советник 3.3987114
print_closest_words(glove['computer'])
компьютеры 2.4362664
программное обеспечение 2.926823
технология 3.190351
электронный 3.5067408
вычисления 3,5999784
Мы также можем посмотреть, какие слова ближе всего к середине двух слов:
print_closest_words((glove['happy'] + glove['sad']) / 2)
счастливый 1.9199749
чувствует 2,3604643
извините 2.4984782
вряд ли 2.52593
представь 2.5652788
print_closest_words((glove['lake'] + glove['building']) / 2)
окружающие 3.0698414
поблизости 3.1112068
мост 3.1585503
вдоль 3.1610188
берег 3.1618817
Аналогии
Один удивительный аспект векторов GloVe заключается в том, что направления в пространстве вложений могут иметь смысл. Структура векторов GloVe имеет определенную аналогию, подобную этой:
король-мужчина+женщина≈королева
print_closest_words(glove['king'] - glove['man'] + glove['woman'])
королева 2.8391209
принц 3.6610038
Элизабет 3.7152522
дочь 3.8317878
вдова 3.8493774
Мы получаем разумные ответы, такие как королева, трон и имя нашей нынешней королевы.
Мы также можем перевернуть аналогию:
print_closest_words(glove['queen'] - glove['woman'] + glove['man'])
король 2.8391209
принц 3.2508988
корона 3.4485192
рыцарь 3.5587437
коронация 3.6198905
Или попробуйте другую, но родственную аналогию по гендерной оси:
print_closest_words(glove['king'] - glove['prince'] + glove['princess'])
королева 3.1845968
король 3.9103293
невеста 4.285721
леди 4.299571
сестра 4.421178
print_closest_words(glove['uncle'] - glove['man'] + glove['woman'])
бабушка 2.323353
тетя 2.3527892
внучка 2.3615322
дочь 2.4039288
дядя 2.6026237
print_closest_words(glove['grandmother'] - glove['mother'] + glove['father'])
дядя 2.0784423
отец 2.0912483
внук 2.2965577
племянник 2.353551
старший 2.4274695
print_closest_words(glove['old'] - glove['young'] + glove['father'])
отец 4.0326614
сын 4.4065413
дедушка 4.51851
внук 4.722089
дочь 4.786716
Мы можем переместить вложение в сторону добра или зла:
print_closest_words(glove['programmer'] - glove['bad'] + glove['good'])
универсальный 4.381561
креатив 4.5690007
предприниматель 4.6343737
включает 4.7177725
умный 4.7349973
print_closest_words(glove['programmer'] - glove['good'] + glove['bad'])
хакер 3.8383653
глюк 4.003873
составитель 4.041952
взломать 4.047719
серийный номер 4.2250676
Смещение векторов Word
Модели машинного обучения кажутся справедливыми, поскольку модели принимают решения без вмешательства человека. Однако модели могут и действительно изучают любую предвзятость, присутствующую в обучающих данных!
Векторы GloVe кажутся достаточно безобидными: они всего лишь представления слов в некотором пространстве вложений. Тем не менее, мы покажем, что структура векторов GloVe кодирует повседневные предубеждения, присутствующие в текстах, на которых они обучаются.
Начнем с примера аналогии:
врач-мужчина+женщина≈??
Давайте используем векторы GloVe, чтобы найти ответ на приведенную выше аналогию:
print_closest_words(glove['doctor'] - glove['man'] + glove['woman'])
медсестра 3.1355345
беременная 3.7805371
ребенок 3,78347
женщина 3.8643107
мать 3.922231
Аналогия врач-мужчина+женщина≈медсестра очень важна. Просто чтобы убедиться, тот же результат не появится, если мы перевернем термины пола:
print_closest_words(glove['doctor'] - glove['woman'] + glove['man'])
мужчина 3.9335632
коллега 3.975502
сам 3.9847782
брат 3.9997008
другой 4.029071
Подобные гендерные предубеждения мы наблюдаем и в других профессиях.
print_closest_words(glove['programmer'] - glove['man'] + glove['woman'])
вундеркинд 3.6688528
психотерапевт 3.8069527
терапевт 3.8087194
вводит 3.9064546
швед 4.1178856
Помимо первого результата, ни одно из других слов даже не связано с программированием! Напротив, если мы перевернем гендерные термины, мы получим совсем другие результаты:
print_closest_words(glove['programmer'] - glove['woman'] + glove['man'])
настройка 4.002241
новатор 4.0661883
программисты 4.1729574
хакер 4.2256656
гений 4.3644104
Вот результаты для инженера:
print_closest_words(glove['engineer'] - glove['man'] + glove['woman'])
техник 3.6926973
механик 3.9212747
пионер 4.1543956
новаторский 4.1880875
воспитатель 4.2264576
print_closest_words(glove['engineer'] - glove['woman'] + glove['man'])
строитель 4.3523865
механик 4.402976
инженеры 4.477985
работало 4.5281315
замена 4.600204
person
Abhi25t
schedule
29.09.2020
the most word similarity
. Мне интересно, что вы действительно хотите вывести. - person luoshao23   schedule 24.06.2020