基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(四)

2023-09-21 20:38:33


在这里插入图片描述

前言

本项目专注于MovieLens数据集,并采用TensorFlow中的2D文本卷积网络模型。它结合了协同过滤算法来计算电影之间的余弦相似度,并通过用户的交互方式,以单击电影的方式,提供两种不同的电影推荐方式。

首先,项目使用MovieLens数据集,这个数据集包含了大量用户对电影的评分和评论。这些数据用于训练协同过滤算法,以便推荐与用户喜好相似的电影。

其次,项目使用TensorFlow中的2D文本卷积网络模型,这个模型可以处理电影的文本描述信息。模型通过学习电影的文本特征,能够更好地理解电影的内容和风格。

当用户与小程序进行交互时,有两种不同的电影推荐方式:

  1. 协同过滤推荐:基于用户的历史评分和协同过滤算法,系统会推荐与用户喜好相似的电影。这是一种传统的推荐方式,通过分析用户和其他用户的行为来推荐电影。

  2. 文本卷积网络推荐:用户可以通过点击电影或输入文本描述,以启动文本卷积网络模型。模型会分析电影的文本信息,并推荐与输入的电影或描述相匹配的其他电影。这种方式更注重电影的内容和情节相似性。

综合来看,本项目融合了协同过滤和深度学习技术,为用户提供了两种不同但有效的电影推荐方式。这可以提高用户体验,使他们更容易找到符合他们口味的电影。

总体设计

本部分包括系统整体结构图和系统流程图。

系统整体结构图

系统整体结构如图所示。
在这里插入图片描述

系统流程图

系统流程如图所示。

在这里插入图片描述

模型训练流程如图所示。

在这里插入图片描述

服务器运行流程如图所示。

在这里插入图片描述

运行环境

本部分包括Python环境、TensorFlow环境、 后端服务器、Django和微信小程序环境

模块实现

本项目包括3个模块:模型训练、后端Django、 前端微信小程序模块,下面分别给出各模块的功能介绍及相关代码。

1. 模型训练

下载数据集,解压到项目目录下的./ml-1m文件夹下。数据集分用户数据users.dat、电影数据movies.dat和评分数据ratings.dat。

1)数据集分析

数据集网站地址为http://files.grouplens.org/datasets/movielens/ml-1m-README.txt对数据的描述。

相关博客:https://blog.csdn.net/qq_31136513/article/details/133124641#1_44

2)数据预处理

通过研究数据集中的字段类型,发现有一些是类别字段,将其转成独热编码,但是UserID、MovieID的字段会变稀疏,输入数据的维度急剧膨胀,所以在预处理数据时将这些字段转成数字。

相关博客:https://blog.csdn.net/qq_31136513/article/details/133124641#2_123

3)模型创建

相关博客:https://blog.csdn.net/qq_31136513/article/details/133125845#3_50

4)模型训练

定义超参数,相关代码如下:

#训练迭代次数
num_epochs = 5
#每个Batch大小
batch_size = 256
#丢弃率
dropout_keep = 0.5
#学习率
learning_rate = 0.0001
#每n 个batches 显示信息
show_every_n_batches = 20
#保存路径
save_dir = './save'
#定义取得batch的函数
def get_batches(Xs, ys, batch_size):
    for start in range(0, len(Xs), batch_size):
        end = min(start + batch_size, len(Xs))
        yield Xs[start:end], ys[start:end]
#定义保存参数的函数
import pickle
def save_params(params):
    #保存参数到文件中
    pickle.dump(params, open('params.p', 'wb'))
def load_params():
    #从文件中加载参数
    return pickle.load(open('params.p', mode='rb'))
#作图
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as plt
import time
import datetime
#记录损失,用于画图
losses = {'train':[], 'test':[]}
with tf.Session(graph=train_graph) as sess:
    #搜集数据给TensorBoard使用
    #跟踪渐变值和稀疏度
    grad_summaries = []
    for g, v in gradients:
        if g is not None:
            grad_hist_summary = tf.summary.histogram("{}/grad/hist".format(v.name.replace(':', '_')), g)
            sparsity_summary = tf.summary.scalar("{}/grad/sparsity".format(v.name.replace(':', '_')), tf.nn.zero_fraction(g))
            grad_summaries.append(grad_hist_summary)
            grad_summaries.append(sparsity_summary)
    grad_summaries_merged = tf.summary.merge(grad_summaries)
    #输出文件夹
    timestamp = str(int(time.time()))
    out_dir = os.path.abspath(os.path.join(os.path.curdir, "runs", timestamp))
    print("Writing to {}\n".format(out_dir))
    #损失与精度的总结
    loss_summary = tf.summary.scalar("loss", loss)
    #训练的总结
    train_summary_op = tf.summary.merge([loss_summary, grad_summaries_merged])
    train_summary_dir = os.path.join(out_dir, "summaries", "train")
    train_summary_writer = tf.summary.FileWriter(train_summary_dir, sess.graph)
    #测试总结
    inference_summary_op = tf.summary.merge([loss_summary])
    inference_summary_dir = os.path.join(out_dir,"summaries","inference")
    inference_summary_writer = tf.summary.FileWriter(inference_summary_dir, sess.graph)
    #变量初始化
    sess.run(tf.global_variables_initializer())
    #模型保存
    saver = tf.train.Saver()
    for epoch_i in range(num_epochs):
    #将数据集分成训练集和测试集,随机种子不固定
        train_X,test_X, train_y, test_y = train_test_split(features,  
                                                     targets_values,  
                                                     test_size = 0.2,  
                                                     random_state = 0)  
    #分开batches
        train_batches = get_batches(train_X, train_y, batch_size)
        test_batches = get_batches(test_X, test_y, batch_size)
    #训练的迭代,保存训练损失
        for batch_i in range(len(train_X) // batch_size):
            x, y = next(train_batches)
            categories = np.zeros([batch_size, 18])
            for i in range(batch_size):
                categories[i] = x.take(6,1)[i]
            titles = np.zeros([batch_size, sentences_size])
            for i in range(batch_size):
                titles[i] = x.take(5,1)[i]
            #传入数据
            feed = {
                uid: np.reshape(x.take(0,1), [batch_size, 1]),
                user_gender: np.reshape(x.take(2,1), [batch_size, 1]),
                user_age: np.reshape(x.take(3,1), [batch_size, 1]),
                user_job: np.reshape(x.take(4,1), [batch_size, 1]),
                movie_id: np.reshape(x.take(1,1), [batch_size, 1]),
                movie_categories: categories,  #x.take(6,1)
                movie_titles: titles,  #x.take(5,1)
                targets: np.reshape(y, [batch_size, 1]),
                dropout_keep_prob: dropout_keep, #dropout_keep
                lr: learning_rate}
            #计算结果
            step, train_loss, summaries, _ = sess.run([global_step, loss, train_summary_op, train_op], feed)  #cost
            losses['train'].append(train_loss)
            #保存记录
            train_summary_writer.add_summary(summaries, step)
            #每多少个batches显示一次
            if (epoch_i * (len(train_X) // batch_size) + batch_i) % show_every_n_batches == 0:
         time_str = datetime.datetime.now().isoformat()
       print('{}: Epoch {:>3} Batch {:>4}/{}   train_loss = {:.3f}'.format(
                    time_str,
                    epoch_i,
                    batch_i,
                    (len(train_X) // batch_size),
                    train_loss))
        #使用测试数据的迭代
        for batch_i  in range(len(test_X) // batch_size):
            x, y = next(test_batches)
            categories = np.zeros([batch_size, 18])
            for i in range(batch_size):
                categories[i] = x.take(6,1)[i]
            titles = np.zeros([batch_size, sentences_size])
            for i in range(batch_size):
                titles[i] = x.take(5,1)[i]
            #传入数据
            feed = {
                uid: np.reshape(x.take(0,1), [batch_size, 1]),
                user_gender: np.reshape(x.take(2,1), [batch_size, 1]),
                user_age: np.reshape(x.take(3,1), [batch_size, 1]),
                user_job: np.reshape(x.take(4,1), [batch_size, 1]),
                movie_id: np.reshape(x.take(1,1), [batch_size, 1]),
                movie_categories: categories,  #x.take(6,1)
                movie_titles: titles,  #x.take(5,1)
                targets: np.reshape(y, [batch_size, 1]),
                dropout_keep_prob: 1,
                lr: learning_rate}
            #计算结果
            step, test_loss, summaries = sess.run([global_step, loss, inference_summary_op], feed)  #cost
            #保存测试损失
            losses['test'].append(test_loss)
            inference_summary_writer.add_summary(summaries, step)  
            #每多少个batches显示一次
            time_str = datetime.datetime.now().isoformat()
            if (epoch_i * (len(test_X) // batch_size) + batch_i) % show_every_n_batches == 0:
                print('{}: Epoch {:>3} Batch {:>4}/{}   test_loss = {:.3f}'.format(
                    time_str,
                    epoch_i,
                    batch_i,
                    (len(test_X) // batch_size),
                    test_loss))
    #保存模型
    saver.save(sess, save_dir)
    print('Model Trained and Saved')

其中,一个batch就是在一次前向/后向传播过程用到的训练样例数量,训练5轮,每轮第一个batch_size 为3125,作为训练集,训练步长为20,第二个batch_ size为781 ,作为测试集,训练步长为20。

训练集训练结果如图所示。
在这里插入图片描述

测试集训练结果如图所示。
在这里插入图片描述

通过观察训练集和测试集损失函数的大小来评估模型的训练程度,进行模型训练的进一步决策。一般来说,训练集和测试集的损失函数不变且基本相等为模型训练的较佳状态。可以将训练过程中保存的损失函数以图片的形式表现出来,方便观察。

相关代码如下:

#保存参数
save_params((save_dir))
load_dir = load_params()
#作图画出训练损失
plt.figure(figsize=(8, 6))
plt.plot(losses['train'], label='Training loss')
plt.legend()
plt.xlabel("Batches")
plt.ylabel("Loss")
_ = plt.ylim()
#作图画出测试损失
plt.figure(figsize=(8,6))
plt.plot(losses['test'], label='Test loss')
plt.legend()
plt.xlabel("Batches")
plt.ylabel("Loss")
_ = plt.ylim()

5)获取特征矩阵

本部分包括定义函数张量、生成电影特征矩阵、生成用户特征矩阵。

(1)定义函数用于获取保存的张量

相关代码如下:

def get_tensors(loaded_graph):
    #使用get_tensor_by_name()函数从loaded_graph模块中获取张量
    uid = loaded_graph.get_tensor_by_name("uid:0")
    user_gender = loaded_graph.get_tensor_by_name("user_gender:0")
    user_age = loaded_graph.get_tensor_by_name("user_age:0")
    user_job = loaded_graph.get_tensor_by_name("user_job:0")
    movie_id = loaded_graph.get_tensor_by_name("movie_id:0")
  movie_categories=loaded_graph.get_tensor_by_name("movie_categories:0")
    movie_titles = loaded_graph.get_tensor_by_name("movie_titles:0")
    targets = loaded_graph.get_tensor_by_name("targets:0")
    dropout_keep_prob = loaded_graph.get_tensor_by_name("dropout_keep_prob:0")
    lr = loaded_graph.get_tensor_by_name("LearningRate:0")
    inference = loaded_graph.get_tensor_by_name("inference/ExpandDims:0")
    movie_combine_layer_flat = loaded_graph.get_tensor_by_name("movie_fc/Reshape:0")
    user_combine_layer_flat = loaded_graph.get_tensor_by_name("user_fc/Reshape:0")
    return uid, user_gender, user_age, user_job, movie_id, movie_categories, movie_titles, targets, lr, dropout_keep_prob, inference, movie_combine_layer_flat, user_combine_layer_flat
(2)生成电影特征矩阵

相关代码如下:

loaded_graph = tf.Graph()
movie_matrics = []
with tf.Session(graph=loaded_graph) as sess: 
    #载入保存好的模型
    loader = tf.train.import_meta_graph(load_dir + '.meta')
    loader.restore(sess, load_dir)
    #调用函数提取tensors
    uid, user_gender, user_age, user_job, movie_id, movie_categories, movie_titles, targets, lr, dropout_keep_prob, _, movie_combine_layer_flat, __ = get_tensors(loaded_graph)  
    for item in movies.values:
        categories = np.zeros([1, 18])
        categories[0] = item.take(2)
        titles = np.zeros([1, sentences_size])
        titles[0] = item.take(1)
        feed = {
            movie_id: np.reshape(item.take(0), [1, 1]),
            movie_categories: categories,
            movie_titles: titles,
            dropout_keep_prob: 1}
        movie_combine_layer_flat_val = sess.run([movie_combine_layer_flat], feed)
        #添加进一个list中
        movie_matrics.append(movie_combine_layer_flat_val)
#保存成.p文件
pickle.dump((np.array(movie_matrics).reshape(-1, 200)), open('movie_matrics.p', 'wb'))
#读取文件
movie_matrics = pickle.load(open('movie_matrics.p', mode='rb'))
(3)生成用户特征矩阵

相关代码如下:

loaded_graph = tf.Graph()
users_matrics = []
with tf.Session(graph=loaded_graph) as sess:
    #载入保存好的模型
    loader = tf.train.import_meta_graph(load_dir + '.meta')
    loader.restore(sess, load_dir)
    #调用函数提取张量
    uid, user_gender, user_age, user_job, movie_id, movie_categories, movie_titles, targets, lr, dropout_keep_prob, _, __,user_combine_layer_flat = get_tensors(loaded_graph)  #loaded_graph
    for item in users.values:
        feed = {
            uid: np.reshape(item.take(0), [1, 1]),
            user_gender: np.reshape(item.take(1), [1, 1]),
            user_age: np.reshape(item.take(2), [1, 1]),
            user_job: np.reshape(item.take(3), [1, 1]),
            dropout_keep_prob: 1}
    user_combine_layer_flat_val=sess.run([user_combine_layer_flat], feed)  
        #添加进一个list中
        users_matrics.append(user_combine_layer_flat_val)
#保存成.p文件
pickle.dump((np.array(users_matrics).reshape(-1, 200)), open('users_matrics.p', 'wb'))
#读取文件
users_matrics = pickle.load(open('users_matrics.p', mode='rb'))

完成模型训练生成preprocess.pmovie_matrics.pusers_matrics.p数据文件。这三个文件会放进后端Django框架中,以便调用。

相关其它博客

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(一)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(二)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(三)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(五)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(六)

基于TensorFlow+CNN+协同过滤算法的智能电影推荐系统——深度学习算法应用(含微信小程序、ipynb工程源码)+MovieLens数据集(七)

工程源代码下载

详见本人博客资源下载页


其它资料下载

如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。

更多推荐

nlp自然语言处理

NLPnlp自然语言处理(不一定是文本,图形也可以)接入深度学习(向量处理),需要把文字等内容转换成向量输入深度学习分为有监督和无监督学习两类,对应分类和生成算法都是向量输入词嵌入(映射到向量)词嵌入最简单的模型是one-hot,但数据计算量太大,所以后续更多的是减少数据量和建立关联性one-hot,最简单分类(单位矩

5G技术与教育的融合:挑战与机遇

5G技术与教育的融合:挑战与机遇摘要:本文旨在探讨5G技术在教育领域的应用及其对教育产业的潜在影响。首先,我们将简要介绍5G技术和现代教育技术的背景和现状。接着,我们将详细讲解5G技术在教育领域的应用,包括教学场景、互动模式和教育内容等方面,并通过实际案例进行分析。随后,我们将对5G技术在教育中的优缺点进行深入探讨,提

解锁前端Vue3宝藏级资料 第五章 Vue 组件应用 1( Props )

本章带领大家理解组件、props、emits、slots、providers/injects,Vue插件等Vue组件使用的基础知识。5.1组件注册5.2Props5.2.1组件之间如何传值5.2.2参数绑定v-bind5.2.3参数类型5.2.4props默认与必填5.2.5验证设置5.2.6useAttrs属性设置第

大数据名词——MPP(Massively Parallel Processing)数据集市

MPP(MassivelyParallelProcessing)数据集市是指一种基于大规模并行处理的数据存储和分析平台,旨在支持高效的数据处理和查询。MPP数据集市通常由多个节点组成,每个节点都具备计算和存储能力,并且可以同时处理大量的数据。MPP数据集市的主要特点包括以下几个方面:1.并行处理能力:MPP数据集市使用

知识产权之围:跨境电商卖家的法律防线

在当今数字化全球市场中,跨境电商是企业扩大国际业务的重要途径。然而,随着全球贸易的复杂化,知识产权问题已成为跨境电商卖家必须面对的挑战之一。本文将通过一个具体案例来探讨知识产权的重要性以及跨境电商卖家如何建立法律防线来保护自己的创意和品牌。Sophia'sBoutique的知识产权之困Sophia是一位富有创造力的跨境

Springboot项目升级2.2.x升至2.7.x

依赖管理spring-boot-starter-parent升级为2.7.1<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><!--升级为2.7.x的版本--><v

压力测试:Jmeter自动化测试详解

1、Jmeter的安装与部署1.1环境要求jdk1.8、配置jdk环境变量(JAVA_HOME:C:\ProgramFiles\Java\jdk1.8.0_101Path:;%JAVA_HOME%\bin;CLASSPATH:%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar)1.2安装

半导体IC电子器件需要老化吗?

前言本文表明,基于初始时刻故障率的时间导数的浴盆曲线(BTC)可以被视为老化测试(BI​​T)是否应该进行的合适标准。进行。还表明,上述标准实际上是产品制造商从众多供应商处收到的批量生产组件的随机统计故障率(SFR)的方差,这些供应商对可靠性的承诺是未知的,并且它们的随机SFR因此,可能会在一个非常大的范围内变化,从零

国内首家!阿里云 Elasticsearch 8.9 版本释放 AI 搜索新动能

简介:阿里云作为国内首家上线Elasticsearch8.9版本的厂商,在提供ElasticsearchRelevanceEngine™(ESRE™)引擎的基础上,提供增强AI的最佳实践与ES本身的混合搜索能力,为用户带来了更多创新和探索的可能性。近年来,人工智能的快速发展和广泛应用在各个行业中都取得了显著的成果。在搜

2023年中国研究生数学建模竞赛D题解题思路

为了更好的帮助大家第一天选题,这里首先为大家带来D题解题思路,分析对应赛题之后做题阶段可能会遇到的各种难点。稍后会带来D题的详细解析思路,以及相关的其他版本解题思路成品论文等资料。赛题难度评估:A、B>C>E、F>D选题人数评估:D>E、F>C>A、BD题区域双碳目标与路径规划研究以当下热门话题双碳碳中和为命题背景设置

内网穿透的应用-Cloudreve搭建云盘系统,并实现随时访问

文章目录1、前言2、本地网站搭建2.1环境使用2.2支持组件选择2.3网页安装2.4测试和使用2.5问题解决3、本地网页发布3.1cpolar云端设置3.2cpolar本地设置4、公网访问测试5、结语1、前言自云存储概念兴起已经有段时间了,各互联网大厂也纷纷加入战局,一时间公有云盘遍地开花。但一段时间后,公有云盘潜在的

热文推荐