Word2vec в фрейме данных pandas

#python #pandas #nlp #word2vec

#python #pandas #nlp #word2vec

Вопрос:

Я пытаюсь применить word2vec для проверки сходства двух столбцов в каждой строке моего набора данных.

Например:

 Sent1                                     Sent2
It is a sunny day                         Today the weather is good. It is warm outside
What people think about democracy         In ancient times, Greeks were the first to propose democracy  
I have never played tennis                I do not know who Roger Feder is 
  

Чтобы применить word2vec, я считаю следующее:

 import numpy as np

words1 = sentence1.split(' ')
words2 = sentence2.split(' ')
#The meaning of the sentence can be interpreted as the average of its words
sentence1_meaning = word2vec(words1[0])
count = 1
for w in words1[1:]:

    sentence1_meaning = np.add(sentence1_meaning, word2vec(w))
    count  = 1
sentence1_meaning /= count

sentence2_meaning = word2vec(words1[0])
count = 1

for w in words1[1:]:
    sentence1_meaning = np.add(sentence1_meaning, word2vec(w))
    count  = 1
sentence1_meaning /= count

sentence2_meaning = word2vec(words2[0])
count = 1
sentence2_meaning = word2vec(words2[0])
count = 1
for w in words2[1:]:
    sentence2_meaning = np.add(sentence2_meaning, word2vec(w))
    count  = 1
sentence2_meaning /= count

#Similarity is the cosine between the vectors
similarity = np.dot(sentence1_meaning, sentence2_meaning)/(np.linalg.norm(sentence1_meaning)*np.linalg.norm(sentence2_meaning))
  

Однако это должно работать для двух предложений, не входящих в фрейм данных pandas.

Не могли бы вы сказать мне, что мне нужно сделать для применения word2vec в случае фрейма данных pandas, чтобы проверить сходство между sent1 и sent2? Я хотел бы получить новый столбец для результатов.

Комментарии:

1. Есть предложения в столбце. Вычислить word2vec представление предложения. Вычислите [квадратную] матрицу попарных расстояний.

Ответ №1:

У меня нет word2vec обученных и доступных, поэтому я покажу, как делать то, что вы хотите, с фиктивным word2vec , со словами, преобразованными в предложения по tfidf весам.

Шаг 1. Подготовка данных

 from sklearn.feature_extraction.text import TfidfVectorizer
df = pd.DataFrame({"sentences": ["this is a sentence", "this is another sentence"]})

tfidf = TfidfVectorizer()
tfidf_matrix = tfidf.fit_transform(df.sentences).todense()
vocab = tfidf.vocabulary_
vocab
{'this': 3, 'is': 1, 'sentence': 2, 'another': 0}
  

Шаг 2. Создайте фиктивный word2vec (размером с наш vocab)

 word2vec = np.random.randn(len(vocab),300)
  

Шаг 3. Вычислите столбец, содержащий word2vec для предложений:

 sent2vec_matrix = np.dot(tfidf_matrix, word2vec) # word2vec here contains vectors in the same order as in vocab
df["sent2vec"] = sent2vec_matrix.tolist()
df

sentences   sent2vec
0   this is a sentence  [-2.098592110459085, 1.4292324332403232, -1.10...
1   this is another sentence    [-1.7879436822159966, 1.680865619703155, -2.00...
  

Шаг 4. Вычислите матрицу подобия

 from sklearn.metrics.pairwise import cosine_similarity
similarity = cosine_similarity(df["sent2vec"].tolist())
similarity
array([[1.        , 0.76557098],
       [0.76557098, 1.        ]])
  

Для вашей word2vec работы вам нужно будет слегка настроить шаг 2, чтобы word2vec он содержал все слова vocab в том же порядке (как указано по значению или в алфавитном порядке).

Для вашего случая это должно быть:

 sorted_vocab = sorted([word for word,key in vocab.items()])
sorted_word2vec = []
for word in sorted_vocab:
    sorted_word2vec.append(word2vec[word])
  

Комментарии:

1. Привет, Сергей Бушманов, большое спасибо за ваш ответ. У меня был бы вопрос: то, что вы показали, это весь код для замены моего, или это просто что-то для интеграции в мой? Я рассматриваю тексты из двух разных столбцов, и я хотел бы сравнить для каждой строки предложение в Sent1 и предложение в Sent2. Для моего понимания (но, вероятно, я неправильно понял) ваш код сравнивает две строки в одном столбце. Не могли бы вы сообщить мне, если я неправильно понял, что вы мне показали? Большое спасибо

2. Я предлагаю изменить ваш подход к наличию только одного столбца с предложениями (т. Е. Изменить Код youts на мой). Если вы все еще настаиваете на том, чтобы текст содержался в 2 столбцах df, вы все равно можете подать cosine_similarity заявку, но то, как вы это делаете, слишком сложно для меня. Я бы сделал всего 3 вещи: определил sent2vec функцию, применил ее к обоим столбцам, применил cosine_similarity между 2 столбцами. Но, честно говоря, я никогда не видел, чтобы это делалось таким образом.

3. Спасибо за ваши советы, Сергей. То, что я пытался сделать, это сравнить сходство между текстами, один в col1 и другой в col2, а не в строках. Вы можете думать об этом, например, как о заголовках и корпусе статьи. Я выберу ваш подход, но важно сохранить сравнение между двумя столбцами, а не строками, поскольку для меня они означают разные вещи.