簡體   English   中英

DataFrame 中兩列的余弦相似度

[英]Cosine similarity of two columns in a DataFrame

我有一個 dataframe 有 2 列,我想得到每對句子的余弦相似度分數。

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)

上面的代碼不起作用,我仍在嘗試不同的方法,但與此同時,我將不勝感激任何指導,在此先感謝您!

所需的 output:

       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

你需要先將你的句子轉換成一個向量,這個過程被稱為文本向量化 根據您需要的復雜程度、您的語料庫的外觀以及預期的應用,有多種方法可以執行文本矢量化。 最簡單的是我在下面實現的“詞袋”(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)

Output

                                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 ] Le, Q. 和 Mikolov, T.,2014 年 6 月。 句子和文檔的分布式表示。 在機器學習國際會議上(第 1188-1196 頁)。 PMLR。

[ 2 ] Reimers, N. 和 Gurevych, I.,2019。Sentence-bert:使用 siamese bert.networks 的句子嵌入。 arXiv 預印本 arXiv:1908.10084。

[ 3 ] Karpukhin, V.、Oğuz, B.、Min, S.、Lewis, P.、Wu, L.、Edunov, S.、Chen, D. 和 Yih, WT,2020 年。域問答。 arXiv 預印本 arXiv:2004.04906。

[ 4 ] Vaswani, A.、Shazeer, N.、Parmar, N.、Uszkoreit, J.、Jones, L.、Gomez, AN、Kaiser, Ł。 和 Polosukhin, I., 2017。注意力就是你所需要的。 神經信息處理系統的進展,30。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM