赞
踩
本项目专注于MovieLens数据集,并采用TensorFlow中的2D文本卷积网络模型。它结合了协同过滤算法来计算电影之间的余弦相似度,并通过用户的交互方式,以单击电影的方式,提供两种不同的电影推荐方式。
首先,项目使用MovieLens数据集,这个数据集包含了大量用户对电影的评分和评论。这些数据用于训练协同过滤算法,以便推荐与用户喜好相似的电影。
其次,项目使用TensorFlow中的2D文本卷积网络模型,这个模型可以处理电影的文本描述信息。模型通过学习电影的文本特征,能够更好地理解电影的内容和风格。
当用户与小程序进行交互时,有两种不同的电影推荐方式:
协同过滤推荐:基于用户的历史评分和协同过滤算法,系统会推荐与用户喜好相似的电影。这是一种传统的推荐方式,通过分析用户和其他用户的行为来推荐电影。
文本卷积网络推荐:用户可以通过点击电影或输入文本描述,以启动文本卷积网络模型。模型会分析电影的文本信息,并推荐与输入的电影或描述相匹配的其他电影。这种方式更注重电影的内容和情节相似性。
综合来看,本项目融合了协同过滤和深度学习技术,为用户提供了两种不同但有效的电影推荐方式。这可以提高用户体验,使他们更容易找到符合他们口味的电影。
本部分包括系统整体结构图和系统流程图。
系统整体结构如图所示。
系统流程如图所示。
模型训练流程如图所示。
服务器运行流程如图所示。
本部分包括Python环境、TensorFlow环境、 后端服务器、Django和微信小程序环境。
本项目包括3个模块:模型训练、后端Django、 前端微信小程序模块,下面分别给出各模块的功能介绍及相关代码。
下载数据集,解压到项目目录下的./ml-1m
文件夹下。数据集分用户数据users.dat、电影数据movies.dat和评分数据ratings.dat。
数据集网站地址为http://files.grouplens.org/datasets/movielens/ml-1m-README.txt对数据的描述。
相关博客:https://blog.csdn.net/qq_31136513/article/details/133124641#1_44
通过研究数据集中的字段类型,发现有一些是类别字段,将其转成独热编码,但是UserID、MovieID的字段会变稀疏,输入数据的维度急剧膨胀,所以在预处理数据时将这些字段转成数字。
相关博客:https://blog.csdn.net/qq_31136513/article/details/133124641#2_123
相关博客:https://blog.csdn.net/qq_31136513/article/details/133125845#3_50
相关博客:https://blog.csdn.net/qq_31136513/article/details/133130704#4_57
本部分包括定义函数张量、生成电影特征矩阵、生成用户特征矩阵。
相关博客:https://blog.csdn.net/qq_31136513/article/details/133130704#5_240
该模块实现了推荐算法的封装与前端数据交互功能。
相关博客:https://blog.csdn.net/qq_31136513/article/details/133131103#2_Django_67
该模块实现用户交互以及与后端数据的传输功能,通过微信开发者平台进行前端开发。
全局配置文件通常以APP开头,包括app.js
、app.json
、app.wxss
等, 这些文件在新建小程序时,由微信开发者平台自动生成。
app.js
相关代码如下:
//app.js App({ onLaunch: function () { console.log("app launch") //展示本地存储能力 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) //登录 wx.login({ success: res => { } }); //获取用户信息 wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { //已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 wx.getUserInfo({ success: res => { //可以将res发送给后台解码出unionId this.globalData.userInfo = res.userInfo //由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 //此处加入callback 以防止类似情况 if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) }, globalData: { userInfo: null, } })
文件app.json为json格式,不能添加注释。pages表示小程序包含的页面,共有三个,一是电影推荐页面movies;二是个人信息页面index;三是用户登录记录logs; window是标题栏设置,可以更改文字类型、背景颜色、标题文字; tabBar是 底部导航栏,可以选择当前页面,包含各页面的路径以及图标,图标可以在阿里巴巴矢量图标库https://www.iconfont.cn/中找到,其他为默认配置。
相关代码如下:
{ "pages": [ "pages/movies/movies", "pages/index/index", "pages/logs/logs" ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "Movies", "navigationBarTextStyle": "black" }, "tabBar": { "list": [ { "pagePath": "pages/movies/movies", "text": "Movies", "iconPath": "/icon/movie.png", "selectedIconPath": "/icon/movie_selected.png" }, { "pagePath": "pages/index/index", "text": "Mine", "iconPath": "/icon/user.png", "selectedIconPath": "/icon/user_selected.png" } ] }, "style": "v2", "sitemapLocation": "sitemap.json" }
文件app.wxss
中描述了小程序的样式表,用于配置全局页面元素样式,app.wxss
相关代码如下:
/**app.wxss**/
@import './weui-miniprogram/weui-wxss/dist/style/weui.wxss';
/*定义了container的样式*/
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 200rpx 0;
box-sizing: border-box;
}
推荐电影页面movies,包含movies.js
、movies.json
、movies.wxml
、movies.wxss
。其中movies.js
记录的是逻辑层; movies.wxml
记录的是视图层; movies.wxss
记录页面元素的样式表;movies.json
类似于app.json
,记录这个页面的相关配置信息。
相关代码如下:
//pages/movies/movies.js Page({ /*页面的初始数据*/ data: { //电影相关信息 movies: null, //推荐方式 recommend_mode: null, //推荐方式选择信息 recommend_mode_list: [{ name: "同类型电影", value: 0, checked: "false" }, { name: "看过这个的还喜欢看", value: 1, checked: "true" }] }, //页面单选按钮逻辑功能函数,选择推荐方式时触发 radioChange: function (e) { //用单选按钮的值给推荐方式变量赋值 this.setData({ recommend_mode: e.detail.value }) console.log(this.data.recommend_mode) }, //推荐同类型电影 post_st_movies: function (event) { var that = this; //向后端服务器发出请求 wx.request({ //这里url填写用户服务器的域名,不显示 url: '', //发送数据为电影的ID data: { movie_id: event.currentTarget.dataset.movie_id, }, //POST方法 method: 'post', header: { 'content-type': 'application/x-www-form-urlencoded' //默认值 }, //成功后执行 success(res) { //更新电影信息 that.setData({ movies: res.data }) console.log(that.data.movies[0].movie_id); } }) }, //推荐看过这个电影的人喜欢的电影 post_of_movies: function (event) { var that = this; //向后端服务器发出请求 wx.request({ //这里url填写用户服务器的域名,不显示 url: '', //发送数据为电影的ID data: { movie_id: event.currentTarget.dataset.movie_id, }, //POST方法 method: 'post', header: { 'content-type': 'application/x-www-form-urlencoded' //默认值 }, //成功后执行 success(res) { //更新电影信息 that.setData({ movies: res.data }) console.log(that.data.movies[0].movie_id); } }) }, //电影推荐按钮的逻辑功能 recommend_movies: function (event) { //如果是0模式 if (this.data.recommend_mode == 0) { this.post_st_movies(event); } //如果是1模式 else if (this.data.recommend_mode == 1) { this.post_of_movies(event); } }, //随机获取电影函数逻辑功能 get_rand_movies: function () { var that = this; //向后端服务器发出请求 wx.request({ //url填写用户服务器的域名,不显示 url: '', data: { }, //GET方法 method: 'get', header: { 'content-type': 'application/x-www-form-urlencoded' //默认值 }, //成功后执行 success(res) { //更新电影信息 that.setData({ movies: res.data }) console.log(that.data.movies[0].movie_id); } }) }, /*生命周期函数--监听页面加载*/ onLoad: function (options) { this.get_rand_movies(); }, /*生命周期函数--监听页面初次渲染完成*/ onReady: function () { }, /* 生命周期函数--监听页面显示*/ onShow: function () { }, /*生命周期函数--监听页面隐藏*/ onHide: function () { }, /*生命周期函数--监听页面卸载*/ onUnload: function () { }, /*页面相关事件处理函数--监听用户下拉动作*/ onPullDownRefresh: function () { }, /*页面上拉触底事件的处理函数*/ onReachBottom: function () { }, /*用户单击右上角分享*/ onShareAppMessage: function () { } }) //文件movies.json代码为空,movies.wxml相关代码如下: <!--pages/movies/movies.wxml--> <!--页面容器--> <view class="container"> <!--页面--> <view class="page-body"> <!--推荐方式选择容器--> <view class="mode-choose-container"> <text>请选择推荐方式:</text> <radio-group class="mode-choose" bindchange="radioChange"> <radio class="radio" wx:for-items="{{recommend_mode_list}}" value="{{item.value}}" > <text>{{item.name}}</text> </radio> </radio-group> </view> <!--电影信息容器--> <view class="movie-container" wx:for="{{[0,1,2,3,4]}}" hover-class='hover_list' data-movie_id="{{movies[index].movie_id}}" bindtap="recommend_movies"> <text>Top {{index+1}}</text> <!--电影名称--> <view class="movie-name-container"> <text class="movie-name"> {{movies[index].movie_name}} </text> </view> <!--电影流派--> <view class="movie-genres-container"> <text class="movie-genres"> {{movies[index].movie_genres}} </text> </view> </view> </view> </view> //movies.wxss相关代码 /* pages/movies/movies.wxss */ .container { /*透明度: 0.1*/ align-items: center; background: #f5f5f5; } .page-body { /*透明度:0.2*/ align-items: center; background: #fefefe; border-style: solid; border-color: #b2b2b2; border-width: thin medium medium thin; border-radius: 50rpx; width: 660rpx; } .mode-choose-container { align-items: center; padding:20rpx; } .movie-container { align-items: center; border-style: solid; border-color: #b2b2b2; border-width: thin medium medium thin; border-radius: 50rpx; margin: 20rpx 15rpx 20rpx 15rpx; padding:20rpx; text-align: center; } .hover_list { opacity: 0.9; background: #f7f7f7; }
这两个页面是新建小程序时系统自动生成的,不做改动。以下个人信息页面由index.js
、index.html
、 index.json
、index.wxss
等文件构成。
index.js
相关代码如下:
//获取应用实例 const app = getApp() Page({ data: { motto: 'Hope you find your peace.', userInfo: {}, hasUserInfo: false, canIUse: wx.canIUse('button.open-type.getUserInfo') }, //事件处理函数 bindViewTap: function() { wx.navigateTo({ url: '../logs/logs' }) }, onLoad: function () { if (app.globalData.userInfo) { this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) } else if (this.data.canIUse){ //由于getUserInfo是网络请求,可能会在Page.onLoad后才返回 //此处加入callback 防止这种情况发生 app.userInfoReadyCallback = res => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { //在没有 open-type=getUserInfo版本的兼容处理 wx.getUserInfo({ success: res => { app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) } }, getUserInfo: function(e) { console.log(e) app.globalData.userInfo = e.detail.userInfo this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) } }) //index.html相关代码 <!--index.wxml--> <view class="container"> <view class="userinfo"> <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button> <block wx:else> <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </block> </view> <view class="usermotto"> <text class="user-motto">{{motto}}</text> </view> </view> //文件index.json为空,index.wxss相关代码 /**index.wxss**/ .userinfo { display: flex; flex-direction: column; align-items: center; } .userinfo-avatar { width: 128rpx; height: 128rpx; margin: 20rpx; border-radius: 50%; } .userinfo-nickname { color: #aaa; } .usermotto { margin-top: 200px; }
以下是用户登录记录页面,由logs.js
、 logs.html
、 logs.json
、logs.wxss
等文件构成。
logs.js
相关代码如下:
//logs.js const util = require('../../utils/util.js') Page({ data: { logs: [] }, onLoad: function () { this.setData({ logs: (wx.getStorageSync('logs') || []).map(log => { return util.formatTime(new Date(log)) }) }) } }) //logs.html相关代码 <!--logs.wxml--> <view class="container log-list"> <block wx:for="{{logs}}" wx:for-item="log"> <text class="log-item">{{index + 1}}. {{log}}</text> </block> </view> //logs.wxss代码如下: .log-list { display: flex; flex-direction: column; padding: 40rpx; } .log-item { margin: 10rpx; } //文件logs.json代码 { "navigationBarTitleText": "查看启动日志", "usingComponents": {} }
基于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相关资料,希望能帮助到所有小伙伴们。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。