Косинусное сходство двух столбцов в DataFrame

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

Датафрейм (df)

       A                   B
0    Lorem ipsum ta      lorem ipsum
1    Excepteur sint      occaecat excepteur
2    Duis aute irure     aute irure 

некоторые из фрагментов кода, которые я пробовал:

1. df["cosine_sim"] = df[["A","B"]].apply(lambda x1,x2:cosine_sim(x1,x2))

2. from spicy.spatial.distance import cosine
df["cosine_sim"] = df.apply(lambda row: 1 - cosine(row['A'], row['B']), axis = 1)

Приведенные выше коды не сработали, и я все еще пробую разные подходы, но пока буду признателен за любые рекомендации. Заранее спасибо!

Желаемый результат:

       A                   B                     cosine_sim
0    Lorem ipsum ta      lorem ipsum                 0.8
1    Excepteur sint      occaecat excepteur          0.5
2    Duis aute irure     aute irure                  0.4

Вам нужно преобразовать предложения (строку) в векторы (массивы numpy или аналогичные)

Dani Mesejo 10.01.2023 20:58

Во-первых, почему косинус? (Почему бы не изменить расстояние) Во-вторых, если вам нужен косинус, вам нужна векторизация, также известная как встраивание, каково ваше пространство для встраивания?

Mehdi 10.01.2023 21:38
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно сначала преобразовать ваши предложения в вектор, этот процесс называется векторизацией текста. Существует множество способов векторизации текста в зависимости от требуемого уровня сложности, внешнего вида корпуса и предполагаемого приложения. Самым простым является «Мешок слов» (BoW), который я реализовал ниже. Как только вы поймете, что значит представлять предложение в виде вектора, вы можете перейти к другим, более сложным методам представления лексического сходства. Например:

  • tf-idf взвешивает определенные слова в зависимости от того, как часто они встречаются во многих документах (или предложениях в вашем случае). Вы можете думать об этом как о взвешенном подходе BoW.
  • BM25 исправляет недостаток tf-idf, из-за которого единичные упоминания слов в коротких документах дают высокие оценки «релевантности». Это делается с учетом длины документа.

Переходя к мерам семантического подобия, вы можете использовать такие методы, как Doc2Vec [ 1 ], которые начинают использовать «встраивающие пробелы» для представления семантики текста. Наконец, недавние методы, такие как SentenceBERT [ 2 ] и Dense Passage Retrieval [ 3 ], используют методы, основанные на Transformer (кодировщик-декодер) архитектуре [ 4] чтобы обеспечить возможность формирования «контекстно-зависимых» представлений.

Решение

import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
from numpy.linalg import norm

df = pd.DataFrame({
    "A": [
    "I'm not a party animal, but I do like animal parties.",
    "That must be the tenth time I've been arrested for selling deep-fried cigars.",
    "He played the game as if his life depended on it and the truth was that it did."
    ],
    "B": [
    "The mysterious diary records the voice.",
    "She had the gift of being able to paint songs.",
    "The external scars tell only part of the story."
    ]
    })

# Combine all to make single corpus of text (i.e. list of sentences)
corpus = pd.concat([df["A"], df["B"]], axis=0, ignore_index=True).to_list()
# print(corpus)  # Display list of sentences

# Vectorization using basic Bag of Words (BoW) approach
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
# print(vectorizer.get_feature_names_out())  # Display features
vect_sents = X.toarray()

cosine_sim_scores = []
# Iterate over each vectorised sentence in the A-B pairs from the original dataframe
for A_vect, B_vect in zip(vect_sents, vect_sents[int(len(vect_sents)/2):]):
    # Calculate cosine similarity and store result
    cosine_sim_scores.append(np.dot(A_vect, B_vect)/(norm(A_vect)*norm(B_vect)))
# Append results to original dataframe
df.insert(2, 'cosine_sim', cosine_sim_scores)
print(df)

Выход

                                A                                         B  cosine_sim
0  I'm not a party animal, but...          The mysterious diary records ...    0.000000
1  That must be the tenth time...   She had the gift of being able to pa...    0.084515
2  He played the game as if hi...  The external scars tell only part of ...    0.257130

Рекомендации

[1] Ле, К. и Миколов, Т., 2014, июнь. Распределенные представления предложений и документов. В Международной конференции по машинному обучению (стр. 1188-1196). ПМЛР.

[2] Реймерс, Н. и Гуревич, И., 2019. Sentence-bert: вложения предложений с использованием сиамских bert-сетей. Препринт arXiv arXiv: 1908.10084.

[3] Карпухин В., Огуз Б., Мин С., Льюис П., Ву Л., Эдунов С., Чен Д. и Йих В. Т., 2020. Поиск плотных проходов для ответов на открытые вопросы. Препринт arXiv arXiv: 2004.04906.

[4] Васвани А., Шазир Н., Пармар Н., Ушкорейт Дж., Джонс Л., Гомес А.Н., Кайзер Л. и Полосухин И., 2017. Внимание — это все, что вам нужно. Достижения в области нейронных систем обработки информации, 30.

Другие вопросы по теме

Не удается загрузить из AutoTokenizer.from_pretrained — TypeError: повторяющееся имя файла (sentencepiece_model.proto)
Создание набора данных Tensorflow и применение слоя TextVectorization с использованием метода карты
Как разбить большой сжатый текстовый файл на небольшие текстовые файлы
Ошибка snscrape - твиттер вылетает после долгого времени, выдавая ошибку «215»
При извлечении текстовых данных из файлов в разных подкаталогах возникает ошибка «ValueError: подстрока не найдена»
Извлечение текстовых данных между ключевыми словами в строке
Разделить несколько предложений в фрейме данных pandas
Как добавить пороговое значение к значениям TF-IDF в разреженной матрице
Не знаете, как разрешить сообщение об ошибке языка из API Google на естественном языке: «Язык sq не поддерживается для анализа document_sentiment»
Как вы определяете ключевое слово в предложении независимо от формы времени в python?