当前位置:   article > 正文

毕业设计——基于卷积神经网络(CNN)进行影评特征分析的电影推荐系统设计与实现(融合PMF模型进行推荐)

毕业设计——基于卷积神经网络(CNN)进行影评特征分析的电影推荐系统设计与实现(融合PMF模型进行推荐)

源码私信获取

基于卷积神经网络(CNN)进行影评特征分析的电影推荐系统设计与实现(融合PMF模型进行推荐)

随着大数据时代的到来,电影推荐系统成为了满足用户个性化需求的关键技术之一。在这样的背景下,结合卷积神经网络(CNN)和概率矩阵分解(PMF)模型的电影推荐系统应运而生,为用户提供了更为精准、高效的电影推荐服务。

首先,卷积神经网络(CNN)作为一种深度学习模型,在图像处理和自然语言处理等领域取得了显著成果。在电影推荐系统中,CNN的应用主要体现在影评特征分析上。影评中蕴含着丰富的用户情感和电影特征,对于推荐算法来说具有极高的价值。传统的影评特征提取方法往往依赖于人工定义的规则或模板,不仅效率低下,而且难以适应复杂的文本变化。而CNN通过卷积层对影评进行局部特征的提取,并通过池化层对特征进行聚合和降维,从而实现对影评数据的自动特征提取。这种特征提取方式不仅提高了效率,而且能够更准确地捕捉影评中的关键信息。

具体来说,基于CNN的影评特征分析可以分为以下几个步骤:首先,将影评文本转化为词向量表示;然后,利用CNN的卷积和池化操作提取影评中的关键特征;最后,将提取到的特征用于后续的推荐算法中。通过这种方式,可以充分利用影评中的信息,提高推荐算法的准确性。

然而,仅仅依靠CNN进行特征提取并不足以满足所有推荐需求。在实际应用中,还需要结合其他算法来进一步提升推荐效果。概率矩阵分解(PMF)模型就是一种有效的推荐算法,它能够将用户-物品矩阵分解为两个低维矩阵,其中一个矩阵表示用户的偏好,另一个矩阵表示物品的属性。通过这种方式,PMF模型能够实现个性化的推荐。

将CNN与PMF模型相结合,可以充分发挥两者的优势。一方面,CNN能够自动提取影评中的关键特征,为PMF模型提供更为丰富、准确的数据支持;另一方面,PMF模型能够根据用户的偏好和物品的属性进行个性化推荐,提高推荐的准确性。

在实际的系统设计与实现过程中,还需要考虑一些技术细节和挑战。例如,如何选择合适的CNN结构和参数以优化特征提取效果?如何有效地结合CNN和PMF模型以提高推荐准确性?如何处理数据稀疏性和冷启动问题?这些问题都需要在实际应用中进行深入研究和探索。

总的来说,基于卷积神经网络(CNN)进行影评特征分析的电影推荐系统设计与实现(融合PMF模型进行推荐)是一种具有广阔应用前景的技术。通过结合CNN和PMF模型的优势,可以为用户提供更为精准、高效的电影推荐服务。未来随着深度学习技术的不断发展,这种推荐系统的性能和应用范围还将得到进一步提升和拓展。

模型构建部分源码:

coding:utf-8

import os
import time

from util import eval_RMSE
import math
import numpy as np
from text_analysis.cnn_model import CNN
from torch.autograd import Variable
import torch

‘’’
‘’’

def ConvMF(res_dir, train_user, train_item, valid_user, test_user,
R, CNN_X, vocab_size, if_cuda, init_W=None, give_item_weight=True,
max_iter=50, lambda_u=1, lambda_v=100, dimension=50,
dropout_rate=0.2, emb_dim=200, max_len=300, num_kernel_per_ws=100):
# explicit setting
a = 1
b = 0

num_user = R.shape[0]
num_item = R.shape[1]
PREV_LOSS = 1e-50
if not os.path.exists(res_dir):
    os.makedirs(res_dir)
f1 = open(res_dir + '/state.log', 'w')
# state.log record

Train_R_I = train_user[1]  # 6040
Train_R_J = train_item[1]  # 3544
Test_R = test_user[1]
Valid_R = valid_user[1]

if give_item_weight is True:
    item_weight = np.array([math.sqrt(len(i))
                            for i in Train_R_J], dtype=float)
    item_weight *= (float(num_item) / item_weight.sum())
else:
    item_weight = np.ones(num_item, dtype=float)

pre_val_eval = 1e10
best_tr_eval, best_val_eval, best_te_eval = 1e10, 1e10, 1e10

# dimension: 用户和物品的隐特征维数
# emb_dim: 词向量的维数
# if_cuda: 是否用GPU训练CNN
cnn_module = CNN(dimension, vocab_size, dropout_rate,
                 emb_dim, max_len, num_kernel_per_ws, if_cuda, init_W)

# 返回CNN的output
# size of V is (num_item, dimension)
if if_cuda:
    cnn_module = cnn_module.cuda()
theta = cnn_module.get_projection_layer(CNN_X)
U = np.random.uniform(size=(num_user, dimension))
V = theta

endure_count = 5
count = 0
# max_iter is 50
for iteration in range(max_iter):
    loss = 0
    tic = time.time()
    print("%d iteration\t(patience: %d)" % (iteration, count))

    VV = b * (V.T.dot(V)) + lambda_u * np.eye(dimension)
    sub_loss = np.zeros(num_user)

    for i in range(num_user):
        idx_item = train_user[0][i]
        V_i = V[idx_item]
        R_i = Train_R_I[i]
        A = VV + (a - b) * (V_i.T.dot(V_i))
        B = (a * V_i * np.tile(R_i, (dimension, 1)).T).sum(0)

        U[i] = np.linalg.solve(A, B)

        sub_loss[i] = -0.5 * lambda_u * np.dot(U[i], U[i])

    loss = loss + np.sum(sub_loss)

    sub_loss = np.zeros(num_item)
    UU = b * (U.T.dot(U))
    for j in range(num_item):
        idx_user = train_item[0][j]
        U_j = U[idx_user]
        R_j = Train_R_J[j]

        tmp_A = UU + (a - b) * (U_j.T.dot(U_j))
        A = tmp_A + lambda_v * item_weight[j] * np.eye(dimension)
        B = (a * U_j * np.tile(R_j, (dimension, 1)).T
             ).sum(0) + lambda_v * item_weight[j] * theta[j]
        V[j] = np.linalg.solve(A, B)

        sub_loss[j] = -0.5 * np.square(R_j * a).sum()
        sub_loss[j] = sub_loss[j] + a * np.sum((U_j.dot(V[j])) * R_j)
        sub_loss[j] = sub_loss[j] - 0.5 * np.dot(V[j].dot(tmp_A), V[j])

    loss = loss + np.sum(sub_loss)

    # 用V训练CNN模型,更新V
    cnn_module.train(CNN_X, V)
    theta = cnn_module.get_projection_layer(CNN_X)

    # 这部分添加计算CNN模型的损失
    # cnn_loss = history.history['loss'][-1]

    # loss -= 0.5 * lambda_v * cnn_loss * num_item

    tr_eval = eval_RMSE(Train_R_I, U, V, train_user[0])
    val_eval = eval_RMSE(Valid_R, U, V, valid_user[0])
    te_eval = eval_RMSE(Test_R, U, V, test_user[0])

    # 计算一次迭代的时间
    toc = time.time()
    elapsed = toc - tic

    # 计算Loss下降率
    converge = abs((loss - PREV_LOSS) / PREV_LOSS)

    # 存储效果最好的模型参数
    if val_eval < pre_val_eval:
        torch.save(cnn_module, res_dir+'CNN_model.pt')
        best_tr_eval, best_val_eval, best_te_eval = tr_eval, val_eval, te_eval
        np.savetxt(res_dir + '/U.dat', U)
        np.savetxt(res_dir + '/V.dat', V)
        np.savetxt(res_dir + '/theta.dat', theta)
    else:
        count += 1

    pre_val_eval = val_eval

    print("Elpased: %.4fs Converge: %.6f Train: %.5f Valid: %.5f Test: %.5f" % (
        elapsed, converge, tr_eval, val_eval, te_eval))
    f1.write("Elpased: %.4fs Converge: %.6f Train: %.5f Valid: %.5f Test: %.5f\n" % (
        elapsed, converge, tr_eval, val_eval, te_eval))

    # 超过五次则退出迭代训练
    if count == endure_count:
        print("\n\nBest Model: Train: %.5f Valid: %.5f Test: %.5f" % (
            best_tr_eval, best_val_eval, best_te_eval))
        f1.write("\n\nBest Model: Train: %.5f Valid: %.5f Test: %.5f\n" % (
            best_tr_eval, best_val_eval, best_te_eval))
        break

    PREV_LOSS = loss

f1.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/346437
推荐阅读
相关标签
  

闽ICP备14008679号