栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

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

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

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

#导入 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, :]))

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/302806.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号