繁体   English   中英

测量组之间的平均余弦相似度

[英]Measuring average cosine similarity between the groups

我有以下数据框:

Group        Vector
1            [1 1 0 1 0 0]
1            [1 0 0 1 0 0]
1            [1 0 0 1 1 1]
1            [0 0 0 1 0 1]
2            [0 0 0 1 0 1]
2            [0 0 0 1 0 1]
2            [0 1 1 1 0 1]
2            [1 1 0 0 0 1]

如何计算组内的平均余弦相似度? 这是预期的结果(注意我为计算补了数字)

Group        Vector            Average_Similarity
1            [1 1 0 1 0 0]      0.34
1            [1 0 0 1 0 0]      0.34
1            [1 0 0 1 1 1]      0.34
1            [0 0 0 1 0 1]      0.34
2            [0 0 0 1 0 1]      0.48
2            [0 0 0 1 0 1]      0.48
2            [0 1 1 1 0 1]      0.48
2            [1 1 0 0 0 1]      0.48

假设我们从您的示例中读取数据,例如:

from ast import literal_eval
df = pd.read_clipboard(sep="|", converters = {"Vector":literal_eval})
df
   Group              Vector
0      1  [1, 1, 0, 1, 0, 0]
1      1  [1, 0, 0, 1, 0, 0]
2      1  [1, 0, 0, 1, 1, 1]
3      1  [0, 0, 0, 1, 0, 1]
4      2  [0, 0, 0, 1, 0, 1]
5      2  [0, 0, 0, 1, 0, 1]
6      2  [0, 1, 1, 1, 0, 1]
7      2  [1, 1, 0, 0, 0, 1]

然后尝试:

from scipy.spatial.distance import pdist

df["Average_Similarity"] = df.groupby("Group")["Vector"].transform(
    lambda group: pdist(group.to_list(), metric="cosine").mean()
)
df

   Group              Vector  Average_Similarity
0      1  [1, 1, 0, 1, 0, 0]            0.380615
1      1  [1, 0, 0, 1, 0, 0]            0.380615
2      1  [1, 0, 0, 1, 1, 1]            0.380615
3      1  [0, 0, 0, 1, 0, 1]            0.380615
4      2  [0, 0, 0, 1, 0, 1]            0.365323
5      2  [0, 0, 0, 1, 0, 1]            0.365323
6      2  [0, 1, 1, 1, 0, 1]            0.365323
7      2  [1, 1, 0, 0, 0, 1]            0.365323

你可以做一个 groupby 申请

from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

df.groupby('group').apply(lambda x: cosine_similarity(np.array([i for i in x['vec']])))

group
1    [[1.0000000000000002, 0.816496580927726, 0.577...
2    [[0.9999999999999998, 0.9999999999999998, 0.70...

重建您的 DataFrame 以便将向量中的每个值放入其自己的单元格中。 然后我们在组内自我合并并使用索引去重复比较(即我们只比较 1 到 3 而不是 1 到 3 和 3 到 1)。

然后我们计算所有行的余弦相似度和组内的平均值。

df = pd.concat([df['Group'], pd.DataFrame(df['Vector'].tolist())], axis=1).reset_index()

m = (df.merge(df, on='Group').query('index_x > index_y')
       .drop(columns=['index_x', 'index_y'])
       .set_index('Group'))

X = m.filter(like='_x')
X.columns = X.columns.str.strip('_x')

Y = m.filter(like='_y')
Y.columns = Y.columns.str.strip('_y')

m['cos'] = 1-(X*Y).sum(1).div((np.sqrt((X**2).sum(1))*np.sqrt((Y**2).sum(1))), axis=0)

m.groupby(level=0)['cos'].mean()

Group
1    0.380615
2    0.365323
Name: cos, dtype: float64

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM