在好例子网,分享、交流、成长!
您当前所在位置:首页Python 开发实例常用Python方法 → 基于python语言编程的矩阵分解电影推荐算法

基于python语言编程的矩阵分解电影推荐算法

常用Python方法

下载此实例
  • 开发语言:Python
  • 实例大小:5.13KB
  • 下载次数:34
  • 浏览次数:582
  • 发布时间:2019-06-28
  • 实例类别:常用Python方法
  • 发 布 人:CarterDLaw
  • 文件格式:.py
  • 所需积分:2
 相关标签: 算法 语言 python 推荐

实例介绍

【实例简介】一种基于矩阵分解方法的电影推荐算法
【实例截图】

【核心代码】

import numpy as np
from numba import cuda, float64, jit
from scipy import sparse
import os
import time
time_start=time.time()
cuda.select_device(0)


# 使用jit模式加速单一元素乘法运算
@jit(nopython=True)
def multiply(c, d):
    return c * d


# 使用jit模式加速单一元素减法运算
@jit(nopython=True)
def subtract(e, f):
    return e - f


# 使用jit模式加速梯度下降算法
@jit(nopython=True)
def gradient_descent(err, p, la, lr, q):
    return q   ((err * p) - (la * q)) * lr


# Thread Per Block
TPB = int(32)


# 使用cuda.jit模式,用gpu加速矩阵的乘法运算
@cuda.jit
def fast_matmul(a, b, c):
    sa = cuda.shared.array(shape=(TPB, TPB), dtype=float64)
    sb = cuda.shared.array(shape=(TPB, TPB), dtype=float64)

    x, y = cuda.grid(2)

    tx = cuda.threadIdx.x
    ty = cuda.threadIdx.y
    # bpg = cuda.gridDim.x

    if x >= c.shape[0] and y >= c.shape[1]:
        # Quit if (x, y) is outside of valid C boundary
        return

    tmp = 0
    for i in range(hid):
        sa[tx, ty] = a[x, ty   i * TPB]
        sb[tx, ty] = b[tx   i * TPB, y]
        cuda.syncthreads()

        for j in range(TPB):
            tmp  = sa[tx, j] * sb[j, ty]
        cuda.syncthreads()
    c[x, y] = tmp


# Latent Factor Model的随机梯度下降算法
@jit(nopython=True)
def stochastic_loop(q_, p_, i_, j_, err_, la_, lr_, k_):
    for r_ in range(k_):
        q_[i_, r_] = gradient_descent(err_, p_[r_, j_], la_, lr_, q_[i_, r_])
        p_[r_, j_] = gradient_descent(err_, q_[i_, r_], la_, lr_, p_[r_, j_])


# 超参数的设置
iteration = 1000
learning_rate = 0.0002
lambda_ = 0.01
k = 128 # 超参数 factor长度
m = 610
m_ = 640
n = 9742
n_ = 9760


# 读训练数据集,存入稀疏矩阵movie_train中。
row_train = np.array(np.load("train_set.npy")[:,0], dtype='float32')
col_train = np.array(np.load("train_set.npy")[:,1], dtype='float32')
data_train = np.array(np.load("train_set.npy")[:,2], dtype='float32')
movie_train = sparse.coo_matrix((data_train,(row_train,col_train)),shape=(m_,n_)).tocsr()


# 读测试数据集,存入稀疏矩阵movie_test中。
row_test = np.array(np.load("test_set.npy")[:,0], dtype='float32')
col_test= np.array(np.load("test_set.npy")[:,1], dtype='float32')
data_test = np.array(np.load("test_set.npy")[:,2], dtype='float32')
movie_test = sparse.coo_matrix((data_test,(row_test,col_test)),shape=(m_,n_)).tocsr()


# 由于numba中,gpu的加速必须保证TPB * BPG恰好为所求矩阵的二维大小,因此要用a、b扩充矩阵大小
Q = np.random.rand(m,k) * 0.33
P = np.random.rand(k,n) * 0.33
a = np.zeros((30,k))  # 640 - 610 = 30
b = np.zeros((k,18))

'''
# Q与P为原参数矩阵,EXTEND为它们padding后的矩阵,对原矩阵运算没有影响
Q_EXTEND = np.row_stack((Q,a))  # (640,128)
P_EXTEND = np.column_stack((P,b))  # (128,9760)
'''

multiple = np.zeros([m_,n_])
hid = int((k-1)/TPB) 1
blockdim = (TPB, TPB)
griddim1 = (20, 305)

# 恢复上一次训练的参数
Q_EXTEND = np.load("Q.npy")
P_EXTEND = np.load("P.npy")

noise_q = np.random.rand(m_,k) * 0.003
noise_p = np.random.rand(k, n_) * 0.003
Q_EXTEND  = noise_q - np.mean(noise_q)
P_EXTEND  = noise_p - np.mean(noise_p)

compare_train = 0.05
compare_test = 0.10
flag = 0  # 学习速率自适应算法的参数

for t in range(iteration):
    loss_train = 0
    loss_test = 0

    # 确保进入cuda.jit的数据在内存中是连续的
    A = np.ascontiguousarray(Q_EXTEND)
    B = np.ascontiguousarray(P_EXTEND)
    fast_matmul[griddim1, blockdim](A, B, multiple)

    for index, item in enumerate(row_train):
        i = int(item)
        j = int(col_train[index])
        error = movie_train[i, j] - multiple[i, j]
        if index % 10000 == 0:
            print(error)
        loss_train  = np.abs(error)

        # 对Q与P的extend矩阵中每个元素进行随机梯度下降
        stochastic_loop(Q_EXTEND, P_EXTEND, i, j, error, lambda_, learning_rate, k)
    loss_train /= 100685

    for index, item in enumerate(row_test):
        i = int(item)
        j = int(col_test[index])
        loss_test  = np.abs(movie_test[i, j] - multiple[i, j])
    loss_test /= 151
    print('iteration%s, loss_train:%s, loss_test:%s' % (t, loss_train, loss_test))

    # 若几次迭代后,学习情况良好,则适当调高学习速率learning_rate,加快学习速度
    # 及时保存参数矩阵Q与P的EXTEND版本,以便分阶段进行优化
    if compare_train > loss_train and compare_test > loss_test:
        print("learning_rate:%s" % learning_rate)
        flag = flag   1
        if flag == 2 and learning_rate < 0.0005:
            learning_rate = learning_rate   0.00001
            flag = 0
        compare_train = loss_train
        compare_test = loss_test
        np.save("Q.npy", Q_EXTEND)
        np.save("P.npy", P_EXTEND)

    # 若本次迭代使得loss_train与loss_test中一者升高,则必须降低学习速率,避免梯度过大
    else:
        print("Warning! The loss is accumulating!")
        flag = 0
        learning_rate = learning_rate * 0.5
cuda.close()

实例下载地址

基于python语言编程的矩阵分解电影推荐算法

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警