两个长度不同的数据框中列之间的余弦相似度?

5
我可以帮助您进行翻译。下面是您需要翻译的内容:

我有一个df1和一个df2中的文本列。 df2的长度将与df1的长度不同。 我想要计算df1 [text]中的每个条目与df2 [text]中的每个条目的余弦相似度,并为每次匹配给出一个分数。

示例输入

df1                           
mahesh                 
suresh


df2                                                                                  
surendra    
mahesh    
shrivatsa    
suresh    
maheshwari

示例输出

mahesh    surendra       30
mahesh    mahesh         100
mahesh    shrivatsa      20
mahesh    suresh         60
mahesh    maheshwari     80
suresh    surendra       70
suresh    mahesh         60
suresh    shrivatsa      40
suresh    suresh         100
suresh    maheshwari     30

当我尝试使用tf-idf方法将这两列进行相似性匹配时,我遇到了问题(获取密钥错误),因为这些列的长度不同。 是否有其他方法可以解决这个问题... 非常感谢任何帮助。 我搜索了很多资料,并发现在几乎所有情况下,人们都是将第一个文档与同一语料库中的其他文档进行比较。 在这里,就像将语料库1中的每个文档与语料库2中的每个文档进行比较。


你是如何计算字符串的余弦相似度的? - ignoring_gravity
1个回答

9

有许多不同的字符串距离度量方法。虽然我建议研究一下 strsim 库,但我不能确定如何在这种情况下使用余弦相似度。

我将举一个例子,说明我如何使用适合短字符串的 Jaro-Winkler 度量方法来解决此问题。

此外,我将包括尝试使用 cosine similarity 的示例,给出该库文档中的示例。这可能完全错误,但应该能让您了解如何从两个不同长度的列的笛卡尔积中制作数据帧,以及如何将 strsim 的算法应用于存储在 pd.DataFrame 中的数据。


数据准备

import pandas as pd

from similarity.jarowinkler import JaroWinkler
from similarity.cosine import Cosine


df1 = pd.DataFrame({
    "name": ["mahesh", "suresh"]
})

df2 = pd.DataFrame({
    "name": ["mahesh", "surendra", "shrivatsa", "suresh", "maheshwari"]
})

df = pd.MultiIndex.from_product(
    [df1["name"], df2["name"]], names=["col1", "col2"]
).to_frame(index=False)

返回:

     col1        col2
0  mahesh      mahesh
1  mahesh    surendra
2  mahesh   shrivatsa
3  mahesh      suresh
4  mahesh  maheshwari
5  suresh      mahesh
6  suresh    surendra
7  suresh   shrivatsa
8  suresh      suresh
9  suresh  maheshwari

Jaro-Winkler:

jarowinkler = JaroWinkler()
df["jarowinkler_sim"] = [jarowinkler.similarity(i,j) for i,j in zip(df["col1"],df["col2"])]

返回:

    col1    col2        jarowinkler_sim
0   mahesh  mahesh      1.0
1   mahesh  surendra    0.4305555555555555
2   mahesh  shrivatsa   0.5185185185185185
3   mahesh  suresh      0.6666666666666666
4   mahesh  maheshwari  0.9466666666666667
5   suresh  mahesh      0.6666666666666666
6   suresh  surendra    0.8333333333333334
7   suresh  shrivatsa   0.611111111111111
8   suresh  suresh      1.0
9   suresh  maheshwari  0.48888888888888893


余弦相似度:


cosine = Cosine(2)
df["p0"] = df["col1"].apply(lambda s: cosine.get_profile(s)) 
df["p1"] = df["col2"].apply(lambda s: cosine.get_profile(s)) 
df["cosine_sim"] = [cosine.similarity_profiles(p0,p1) for p0,p1 in zip(df["p0"],df["p1"])]

df.drop(["p0", "p1"], axis=1)

返回:

    col1    col2        cosine_sim
0   mahesh  mahesh      0.9999999999999998
1   mahesh  surendra    0.0
2   mahesh  shrivatsa   0.15811388300841897
3   mahesh  suresh      0.3999999999999999
4   mahesh  maheshwari  0.7453559924999299
5   suresh  mahesh      0.3999999999999999
6   suresh  surendra    0.5070925528371099
7   suresh  shrivatsa   0.15811388300841897
8   suresh  suresh      0.9999999999999998
9   suresh  maheshwari  0.29814239699997197


感谢政治学家, 当我尝试使用大量数据(两列均为50K +)进行df = pd.MultiIndex.from_product([df1["name"], df2["name"]], names=["col1", "col2"]).to_frame(index=False)时,会出现内存错误。 是否有优化的方法来处理大量数据? - Python Learner
@pythonlearner 有重复的吗?你可以尝试过滤它们。如果这样不起作用,你也可以尝试使用迭代.product函数来避免完全使用pandas。 - help-ukraine-now

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接