在数据框中计算组中两列的余弦相似度
calculate cosine similarity for two columns in a group by in a dataframe
我有一个数据框df
:
AID VID FID APerc VPerc
1 A X 0.2 0.5
1 A Z 0.1 0.3
1 A Y 0.4 0.9
2 A X 0.2 0.3
2 A Z 0.9 0.1
1 B Z 0.1 0.2
1 B Y 0.8 0.3
1 B W 0.5 0.4
1 B X 0.6 0.3
我想计算所有 AID
和 VID
对的值 APerc
和 VPerc
的余弦相似度。所以上面的结果应该是:
AID VID CosSim
1 A 0.997
2 A 0.514
1 B 0.925
我知道如何分组:df.groupby(['AID','VID'])
而且我知道如何为整列生成余弦相似度:
from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity(df['APerc'], df['VPerc'])
鉴于我有一个非常大的文件,最好和最快的方法是什么。
Pairwise cosine_similarity
专为二维数组设计,因此您需要在前后进行一些整形。取而代之的是,使用 scipy 的 cosine
距离:
from scipy.spatial.distance import cosine
df.groupby(['AID','VID']).apply(lambda x: 1 - cosine(x['APerc'], x['VPerc']))
Out:
AID VID
1 A 0.997097
B 0.924917
2 A 0.514496
dtype: float64
在形状为 (10k, 5) 的 df 上计时,scipy 为 2.87 毫秒,sklearn 为 4.08 毫秒。相当一部分 4.08 毫秒可能是由于它输出的警告,因为在亚历山大的版本中它下降到 3.31 毫秒。我怀疑在单个二维数组上调用时 sklearn 版本会变得更快。
不确定它是否是最快的,groupby.apply
通常是这样做的方式:
(df.groupby(['AID','VID'])
.apply(lambda g: cosine_similarity(g['APerc'], g['VPerc'])[0][0]))
#AID VID
#1 A 0.997097
# B 0.924917
#2 A 0.514496
#dtype: float64
扩展@Psidom 的解决方案,在计算之前将系列转换为 numpy 数组 cosine_similarity
并重塑:
(df.groupby(['AID','VID'])
.apply(lambda g: cosine_similarity(g['APerc'].values.reshape(1, -1),
g['VPerc'].values.reshape(1, -1))[0][0]))
我有一个数据框df
:
AID VID FID APerc VPerc
1 A X 0.2 0.5
1 A Z 0.1 0.3
1 A Y 0.4 0.9
2 A X 0.2 0.3
2 A Z 0.9 0.1
1 B Z 0.1 0.2
1 B Y 0.8 0.3
1 B W 0.5 0.4
1 B X 0.6 0.3
我想计算所有 AID
和 VID
对的值 APerc
和 VPerc
的余弦相似度。所以上面的结果应该是:
AID VID CosSim
1 A 0.997
2 A 0.514
1 B 0.925
我知道如何分组:df.groupby(['AID','VID'])
而且我知道如何为整列生成余弦相似度:
from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity(df['APerc'], df['VPerc'])
鉴于我有一个非常大的文件,最好和最快的方法是什么。
Pairwise cosine_similarity
专为二维数组设计,因此您需要在前后进行一些整形。取而代之的是,使用 scipy 的 cosine
距离:
from scipy.spatial.distance import cosine
df.groupby(['AID','VID']).apply(lambda x: 1 - cosine(x['APerc'], x['VPerc']))
Out:
AID VID
1 A 0.997097
B 0.924917
2 A 0.514496
dtype: float64
在形状为 (10k, 5) 的 df 上计时,scipy 为 2.87 毫秒,sklearn 为 4.08 毫秒。相当一部分 4.08 毫秒可能是由于它输出的警告,因为在亚历山大的版本中它下降到 3.31 毫秒。我怀疑在单个二维数组上调用时 sklearn 版本会变得更快。
不确定它是否是最快的,groupby.apply
通常是这样做的方式:
(df.groupby(['AID','VID'])
.apply(lambda g: cosine_similarity(g['APerc'], g['VPerc'])[0][0]))
#AID VID
#1 A 0.997097
# B 0.924917
#2 A 0.514496
#dtype: float64
扩展@Psidom 的解决方案,在计算之前将系列转换为 numpy 数组 cosine_similarity
并重塑:
(df.groupby(['AID','VID'])
.apply(lambda g: cosine_similarity(g['APerc'].values.reshape(1, -1),
g['VPerc'].values.reshape(1, -1))[0][0]))