[英]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.