文章目录

  • 0 项目说明
  • 1 主要实现
  • 2 系统流程
  • 3 使用方法
  • 3.1 项目依赖
  • 3.2 数据库建表处理
  • 4 项目源码
  • 5 最后



0 项目说明

基于Django与协同过滤的电影推荐系统

提示:适合用于课程设计或毕业设计,工作量达标,源码开放


1 主要实现

电影推荐系统——实现用户登录、评分、推荐,采用协同过滤算法

2 系统流程

用户注册、登录系统,对看过的电影进行评分,点击提交评分按钮,再点击查看推荐按钮即可看见推荐的电影列表。项目主页以及推荐结果如下:

python中优化协同过滤算法 python协同过滤电影推荐_python


python中优化协同过滤算法 python协同过滤电影推荐_django_02

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 最后