如何计算DataFrame中各客户名称间的余弦相似度矩阵?
生成客户名称相似度矩阵的实现方案
现有代码背景
1. 处理原始数据生成DataFrame
mylist = [ "₹67.00 to Rupam Sweets using Bank Account XXXXXXXX5343<br>11 Feb 2023, 20:42:25", "₹66.00 to Rupam Sweets using Bank Account XXXXXXXX5343<br>10 Feb 2023, 21:09:23", "₹32.00 to Nagori Sajjad Mohammed Sayyed using Bank Account XXXXXXXX5343<br>9 Feb 2023, 07:06:52", "₹110.00 to Vikram Manohar Jsohi using Bank Account XXXXXXXX5343<br>9 Feb 2023, 06:40:08", "₹120.00 to Winner Dinesh Gupta using Bank Account XXXXXXXX5343<br>30 Jan 2023, 06:23:55", ] import pandas as pd df = pd.DataFrame(mylist) df.columns = ["full_text"] ndf = df.full_text.str.split("to", expand=True) ndf.columns = ["amt", "full_text"] ndf2 = ndf.full_text.str.split("using Bank Account XXXXXXXX5343<br>", expand=True) ndf2.columns = ["client", "date"] df = ndf.join(ndf2)[["date", "client", "amt"]]
2. 生成客户名称的Embedding
from openai.embeddings_utils import get_embedding, cosine_similarity import openai openai.api_key = 'xxx' embedding_model = "text-embedding-ada-002" embeddings = df.client.apply(lambda x: get_embedding(x, engine=embedding_model)) df["embeddings"] = embeddings
需求说明
需要生成一个相似度矩阵,矩阵的行和列均为唯一客户名称,单元格值为对应两个客户名称Embedding的余弦相似度分数。
实现方案
步骤1:提取唯一客户及其Embedding
原DataFrame中存在重复客户(如Rupam Sweets出现两次),先去重得到唯一客户列表:
# 获取去重后的客户及对应Embedding unique_clients = df.drop_duplicates(subset='client')[['client', 'embeddings']].reset_index(drop=True)
步骤2:生成相似度矩阵
提供两种实现方式,可根据需求选择:
方式1:循环遍历计算(直观易理解)
import numpy as np # 初始化空的相似度矩阵 similarity_matrix = pd.DataFrame( index=unique_clients['client'], columns=unique_clients['client'], dtype=np.float64 ) # 遍历每对客户计算相似度 for i, row_i in unique_clients.iterrows(): for j, row_j in unique_clients.iterrows(): similarity_score = cosine_similarity(row_i['embeddings'], row_j['embeddings']) similarity_matrix.loc[row_i['client'], row_j['client']] = similarity_score
方式2:向量化计算(高效,适合客户数量较多的场景)
利用numpy矩阵运算实现批量计算,效率更高:
import numpy as np # 将Embedding转换为numpy矩阵 embeddings_matrix = np.array(unique_clients['embeddings'].tolist()) # 计算余弦相似度:点积除以各自L2范数的乘积 norm = np.linalg.norm(embeddings_matrix, axis=1, keepdims=True) cosine_sim_scores = (embeddings_matrix @ embeddings_matrix.T) / (norm @ norm.T) # 转换为DataFrame格式的相似度矩阵 similarity_matrix = pd.DataFrame( cosine_sim_scores, index=unique_clients['client'], columns=unique_clients['client'] )
最终效果
生成的similarity_matrix中,对角线元素为1(客户与自身的相似度),其他单元格为对应两个客户名称的相似度分数,数值越接近1表示名称语义越相似。
内容的提问来源于stack exchange,提问作者shantanuo
相关产品推荐
相关产品推荐

