利用Tensorflow实现基于矩阵乘法的余弦相似度大规模计算

本文介绍了一种使用TensorFlow解决大规模数据余弦相似度计算的方法。通过将数据拆分并利用GPU资源,实现了在10^4x10^4规模下约20秒的计算时间,显著提高了计算效率。代码示例展示了如何处理新老用户特征数据,最终生成新老用户之间的相似度矩阵。
摘要由CSDN通过智能技术生成

       在推荐系统中,经常会计算用户—用户相似度、用户—产品相似度,而两类业务中都会涉及到很大量级的数据,导致最终的相似度矩阵计算规模更大。

       本文旨在解决高效计算大规模数据的余弦相似度计算问题。

#导入 tensorflow 模块,因部分用到1.x版本的Tensorflow,因此用如下方式导入
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

import numpy as np
import pandas as pd
import math
from datetime import datetime
# 定义余弦相似度函数,便于后续检验结果
def cos_sim(a, b):
    a_norm = np.linalg.norm(a)
    b_norm = np.linalg.norm(b)
    s = a_norm * b_norm
    if s==0:
        cos = 0
    else:
        cos = np.dot(a,b)/s
    return cos
#设定余弦相似度矩阵按多少行进行拆分,40GB内存,6GB显存的机器大概能计算31000*31000的余弦相似矩阵,
#因此大多数分析场景均需要对数据源矩阵进行拆分,实际数值根据机器所承受的最大数值进行设定
BRANCH_C = 10000
#导入处理好的新老用户特征数据
csv_New = pd.read_csv('./df_1_unknown_group.txt', header=None)      #新用户的特征数据集
csv_Old = pd.read_csv('./df_2_ydy_group.txt', header=None)  #老用户的特征数据集
# 随机抽取新用户与老用户各20000条数据
csv_New = csv_New.sample(n=20000)
csv_New.index = range(20000)
csv_Old = csv_Old.sample(n=20000)
csv_Old.index = range(20000)
csv_New
csv_Old

#计算矩阵拆分后需要运算的次数
RunTimes = math.ceil(len(csv_Old)/BRANCH_C )
#初始化缓存结果的矩阵
csv_Result = np.empty(shape=[len(csv_New), 0])
# 开始循环处理
for i in range(RunTimes):
    # 将新用户矩阵与截取的已订购用户的特征矩阵进行拼接
    Branch_M = csv_Old.iloc[(BRANCH_C * i):(BRANCH_C * (i + 1)), :]
    csv_Train = np.concatenate((csv_New, Branch_M), axis=0)
    csv_Train_M, csv_Train_N = csv_Train.shape

    with tf.Session() as sess:
        # 拼接处理后的矩阵长与宽
        M = csv_Train_M
        N = csv_Train_N

        # tensorflow初始化输入矩阵
        input = tf.placeholder(tf.float32, shape=(M, N))
        normalized = tf.nn.l2_normalize(input, dim = 1)

        # 矩阵*自己的转置
        prod = tf.matmul(normalized, normalized, adjoint_b=True)
        dist = 1 - prod

        print(f"({datetime.now()}) Use tensorflow to resolving {i}:")
        # 得到该部分矩阵的相似度矩阵
        TF_Result = 1 - sess.run(dist, feed_dict={input: csv_Train})

        # 删除冗余数据,截取结果矩阵获得新用户与老用户的相似度矩阵
        csv_ResultT = TF_Result[0:len(csv_New), len(csv_New):len(TF_Result)]
        csv_Result = np.concatenate((csv_Result, csv_ResultT), axis=1)

       可以看到,量级为10^4 x 10^4 = 10^8的余弦相似度计算时长约为20秒,相比普通的余弦相似度计算方式,性能提高不少。 

# 总览最终相似度矩阵
pd.DataFrame(csv_Result)

# 任意查看第768位置的新用户与第512位置的老用户的余弦相似度
pd.DataFrame(csv_Result).iloc[768, 512]

 

# 利用定义的余弦相似度函数计算第768位置的新用户与第512位置的老用户的余弦相似度
cos_sim(np.array(csv_New.iloc[768, :]), np.array(csv_Old.iloc[512, :]))

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eureka丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值