0 项目说明
基于Django与协同过滤的电影推荐系统
提示:适合用于课程设计或毕业设计,工作量达标,源码开放
1 主要实现
电影推荐系统——实现用户登录、评分、推荐,采用协同过滤算法
2 系统流程
用户注册、登录系统,对看过的电影进行评分,点击提交评分按钮,再点击查看推荐按钮即可看见推荐的电影列表。项目主页以及推荐结果如下:
3 使用方法
1.首先将项目克隆到本地,用Pycharm打开movierecommend文件夹,并install项目依赖
2.将用到的csv文件导入mysql数据表中,详见数据库建表 ,配置好数据库;注意数据库相关代码(settings.py、views.py)可能都要进行修改以符合实际情况;(本项目端口号为3307,用户为root,密码为admin,database为MovieData);
3.命令行执行:
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
点击http://127.0.0.1:8000/ 即可查看注册登录以及评分页面。
注意登录后点击电影海报下面的星星对该电影评分,之后还要点击左上角的“提交评分”按钮才能将该评分数据存入mysql中,否则代码会报错。
3.1 项目依赖
1.Python3.6+django1.11 (python3.5亦可)
2.MySQL5.6
3.Jquery+CSS3+Html5
3.2 数据库建表处理
1.在MySQL中创建一个database,取好名字,比如MovieData;
2.在该数据库中创建moviegenre3和users_resulttable两张表,建表命令行如下:
CREATE TABLE moviegenre3(imdbId INT NOT NULL PRIMARY KEY,title varchar(300),poster varchar(600));
3.通过命令行或者navicat等工具将项目data文件夹下的两张csv表分别导入上面创建好的两张table中。由于moviegenre3.csv中的超链接较复杂,建议使用navicat工具导入;users_resulttable表可以使用下面命令行导入:
load data infile "E:/MovieRecommend/data/users_resulttable.csv" into table users_resulttable fields terminated by ',' lines terminated by '\n' (userId,imdbId,rating);
注意,此表没有主键,增加主键操作为:
alter table users_resulttable add column id int auto_increment PRIMARY KEY;
4 项目源码
from django.shortcuts import render, redirect,HttpResponseRedirect
from .forms import RegisterForm
from users.models import Resulttable,Insertposter
from django.db import models
def register(request):
# 只有当请求为 POST 时,才表示用户提交了注册信息
if request.method == 'POST':
form = RegisterForm(request.POST)
# 验证数据的合法性
if form.is_valid():
# 如果提交数据合法,调用表单的 save 方法将用户数据保存到数据库
form.save()
# 注册成功,跳转回首页
return redirect('/')
else:
# 请求不是 POST,表明用户正在访问注册页面,展示一个空的注册表单给用户
form = RegisterForm()
# 渲染模板
# 如果用户正在访问注册页面,则渲染的是一个空的注册表单
# 如果用户通过表单提交注册信息,但是数据验证不合法,则渲染的是一个带有错误信息的表单
return render(request, 'users/register.html', context={'form': form})
def index(request):
return render(request, 'users/..//index.html')
# 为啥?
def check(request):
return render((request, 'users/..//index.html'))
# def showregist(request):
# pass
def showmessage(request):
usermovieid = []
usermovietitle = []
data=Resulttable.objects.filter(userId=1001)
for row in data:
usermovieid.append(row.imdbId)
try:
conn = get_conn()
cur = conn.cursor()
#Insertposter.objects.filter(userId=USERID).delete()
for i in usermovieid:
cur.execute('select * from moviegenre3 where imdbId = %s',i)
rr = cur.fetchall()
for imdbId,title,poster in rr:
usermovietitle.append(title)
print(title)
# print(poster_result)
finally:
conn.close()
return render(request, 'users/message.html', locals())
# USERID = 1002
def recommend1(request):
USERID = int(request.GET["userIdd"]) + 1000
Insertposter.objects.filter(userId=USERID).delete()
#selectMysql()
read_mysql_to_csv('users/static/users_resulttable.csv',USERID) #追加数据,提高速率
ratingfile = os.path.join('users/static', 'users_resulttable.csv')
usercf = UserBasedCF()
userid = str(USERID)#得到了当前用户的id
print(userid)
usercf.generate_dataset(ratingfile)
usercf.calc_user_sim()
usercf.recommend(userid) #得到imdbId号
#先删除所有数据
try:
conn = get_conn()
cur = conn.cursor()
#Insertposter.objects.filter(userId=USERID).delete()
for i in matrix:
cur.execute('select * from moviegenre3 where imdbId = %s',i)
rr = cur.fetchall()
for imdbId,title,poster in rr:
#print(value) #value才是真正的海报链接
if(Insertposter.objects.filter(title=title)):
continue
else:
Insertposter.objects.create(userId=USERID, title=title, poster=poster)
# print(poster_result)
finally:
conn.close()
#results = Insertposter.objects.all() #从这里传递给html= Insertposter.objects.all() # 从这里传递给html
results = Insertposter.objects.filter(userId=USERID)
return render(request,'users/movieRecommend.html', locals())
# return render(request, 'users/..//index.html', locals())
def recommend2(request):
# USERID = int(request.GET["userIddd"]) + 1000
USERID = 1001
Insertposter.objects.filter(userId=USERID).delete()
#selectMysql()
read_mysql_to_csv2('users/static/users_resulttable2.csv',USERID) #追加数据,提高速率
ratingfile2 = os.path.join('users/static', 'users_resulttable2.csv')
itemcf = ItemBasedCF()
#userid = '1001'
userid = str(USERID)#得到了当前用户的id
print(userid)
itemcf.generate_dataset(ratingfile2)
itemcf.calc_movie_sim()
itemcf.recommend(userid) #得到imdbId号
#先删除所有数据
try:
conn = get_conn()
cur = conn.cursor()
#Insertposter.objects.filter(userId=USERID).delete()
for i in matrix2:
cur.execute('select * from moviegenre3 where imdbId = %s',i)
rr = cur.fetchall()
for imdbId,title,poster in rr:
#print(value) #value才是真正的海报链接
if(Insertposter.objects.filter(title=title)):
continue
else:
Insertposter.objects.create(userId=USERID, title=title, poster=poster)
# print(poster_result)
finally:
conn.close()
results = Insertposter.objects.filter(userId=USERID) #从这里传递给html= Insertposter.objects.all() # 从这里传递给html
return render(request, 'users/movieRecommend2.html',locals())
# return HttpResponseRedirect('movieRecommend.html', locals())
def insert(request):
# MOVIEID = int(request.GET["movieId"])
global USERID
USERID = int(request.GET["userId"])+1000
# USERID = {{}}
RATING = float(request.GET["rating"])
IMDBID = int(request.GET["imdbId"])
Resulttable.objects.create(userId=USERID, rating=RATING,imdbId=IMDBID)
#print(USERID)
# return HttpResponseRedirect('/')
return render(request, 'index.html',{'userId':USERID,'rating':RATING,'imdbId':IMDBID})
5 最后
**项目分享: ** https://gitee.com/asoonis/htw