首页 > 编程语言 >毕业设计:python考研院校推荐系统 混合推荐 协同过滤推荐算法 爬虫 可视化 Django框架(源码+文档)✅

毕业设计:python考研院校推荐系统 混合推荐 协同过滤推荐算法 爬虫 可视化 Django框架(源码+文档)✅

时间:2024-11-11 09:46:14浏览次数:3  
标签:school jaccard similarities 推荐 用户 源码 user 毕业设计 id

毕业设计:python考研院校推荐系统 混合推荐 协同过滤推荐算法 爬虫 可视化 Django框架(源码+文档)✅

1、项目介绍

技术栈:
Python语言 MySQL数据库 Django框架 协同过滤推荐算法 requests网络爬虫 pyecharts数据可视化 html页面、爬取院校信息:https://yz.chsi.com.cn/sch/(研招网)

2、项目界面

(1)首页院校展示
在这里插入图片描述

(2)数据可视化分析

在这里插入图片描述

(3)院校推荐模块—混合推荐(协同过滤推荐算法)

在这里插入图片描述
(4)院校评分、收藏
在这里插入图片描述

(5)报录比查询

在这里插入图片描述

(6)我的收藏
在这里插入图片描述

(7)后台数据管理
在这里插入图片描述

3、项目说明

在当下的考研热潮中,众多考生面临着选择合适院校的难题,而院校信息的海量性与复杂性使得个性化院校推荐和数据可视化分析成为解决问题的关键。考研院校数据分析与可视化系统的开发,旨在为考生提供一个直观、易用的决策支持工具,通过数据可视化和智能推荐算法,帮助考生更加科学地进行院校选择,从而提高考研的效率和成功率。该系统利用最新的Web技术和数据分析方法,将复杂的院校数据转化为直观的图表和推荐列表,极大地简化了考生的决策过程,具有重要的实用价值和广阔的应用前景。
系统基于Django框架开发,前端采用HTML、CSS、JavaScript,后端应用协同过滤算法进行智能数据处理,通过echarts库实现数据可视化。具体完成了院校查看、数据可视化分析、院校推荐、用户评分和用户收藏等业务功能。这些功能的集成,不仅提高了系统的互动性和个性化服务水平,还使得复杂的数据分析结果以直观的方式呈现给用户,帮助用户深入了解各院校的特色和优势。
通过引入协同过滤算法和数据可视化技术,考研院校数据分析与可视化系统有效解决了考生在选择院校时信息过载和决策困难的问题。系统的智能推荐算法根据用户的历史行为和偏好,精准推荐符合用户需求的院校,而数据可视化的应用则使得复杂的院校信息和用户数据变得易于理解和分析。这些优势不仅为考生提供了便捷高效的院校选择方案,也为高等教育资源的合理分配和利用提供了技术支撑,具有显著的社会效益和经济价值。

关键词:考研院校数据分析与可视化系统;Django;协同过滤算法;echarts;数据可视化

4、核心代码

import random

from django.shortcuts import render
import math
from app01 import models
from app01.models import School, UserScore, User, UserCollection
from app01.utils.pagination import Pagination


def jaccard_similarity(a, b):
    # 计算杰卡德相似度
    # 将布尔向量转换为集合
    set_a = set(i for i, x in enumerate(a) if x)
    # print("set_a:", set_a)
    set_b = set(i for i, x in enumerate(b) if x)
    # print("set_b:", set_b)
    # 计算交集和并集的大小
    intersection = len(set_a.intersection(set_b))
    # print("a和b交集:", set_a.intersection(set_b))
    union = len(set_a.union(set_b))
    # print("a和b并集:", set_a.union(set_b))
    # 计算相似度
    similarity = intersection / union if union else 0
    return similarity

#重载字典计算方法
class MyDict(dict):
    def __add__(self, other):
        res = MyDict(self)
        for key, val in other.items():
            if key in res:
                res[key] += val
            else:
                res[key] = val
        return res

    def __mul__(self, factor):
        res = MyDict()
        for key, val in self.items():
            res[key] = val * factor
        return res

    def __rmul__(self, factor):
        return self.__mul__(factor)


def cosine_similarity(v1, v2):
    # 计算余弦相似度
    numerator = sum([a * b for a, b in zip(v1, v2)])  # 两向量的内积作为分子
    denominator = math.sqrt(sum([a ** 2 for a in v1])) * math.sqrt(sum([b ** 2 for b in v2]))  # 两向量模长的乘积作为分母
    if denominator > 0:
        return numerator / denominator
    else:
        return 0


# 基于用户收藏计算当前用户与其他用户的杰卡德相似度
def user_jaccard_similarity_collections(user_id, default_similarity_jaccard=0):
    # 获取当前用户的收藏数据
    user_collections = UserCollection.objects.filter(user_id=user_id).values('school_id', 'collection')
    # 获取当前用户收藏的学校id
    user_collections_school_id = [user_collection['school_id'] for user_collection in user_collections]
    # print("当前用户收藏情况:")
    # print(user_collections_school_id)
    # print("基于用户收藏的邻居用户收藏情况:")
    # 构造当前用户收藏向量
    user_collection_vector = [0 for i in range(999)]
    for school_id in user_collections_school_id:
        user_collection_vector[school_id] = 1

    similarities_jaccard = {}  # 定义字典来存放与当前用户相似用户的id和相似度
    for user in User.objects.exclude(id=user_id):
        # 获取当前用户与其他用户共同收藏的物品的id
        collections = user.usercollections.filter(school_id__in=user_collections_school_id).values('school_id')
        if collections:  # 如果当前用户与该用户有共同收藏的学校,则计算当前用户与该用户的相似度,这里使用杰卡德
            # 获取该用户所有的收藏情况:(school_id)
            collections = user.usercollections.filter().values('school_id')
            collections_school_id = [(collection['school_id']) for collection in collections]
            # print(collections_school_id)
            # 构造该用户收藏向量:collection_vector
            collection_vector = [0 for i in range(999)]
            for school_id in collections_school_id:
                collection_vector[school_id] = 1
            #     collection_vector[0] = user.id
            # print(collection_vector)
            # 计算两用户之间的杰卡德相似度
            similarity_jaccard = jaccard_similarity(user_collection_vector, collection_vector)
            if similarity_jaccard > default_similarity_jaccard:
                similarities_jaccard[user.id] = similarity_jaccard
    return similarities_jaccard


# 基于用户收藏计算当前用户对邻居收藏院校的jaccard兴趣度
def user_recommendations_jaccard_collections(user_id, similarities, similarities_jaccard):
    # 获取当前用户的收藏数据
    user_collections = UserCollection.objects.filter(user_id=user_id).values('school_id', 'collection')
    # 获取当前用户收藏的学校id
    user_collections_school_id = [user_collection['school_id'] for user_collection in user_collections]
    recommendations_jaccard = {}
    # print("邻居用户已收藏的学校中目标用户未收藏的学校:",
    #       UserCollection.objects.filter(user_id__in=similarities).exclude(
    #           school_id__in=user_collections_school_id).values_list('school_id', flat=True).distinct())
    # 邻居用户已收藏的学校中目标用户未收藏的学校
    for school_id in UserCollection.objects.filter(user_id__in=similarities).exclude(
            school_id__in=user_collections_school_id).values_list('school_id', flat=True).distinct():
        # 获取收藏了当前物品的用户:用户id和收藏情况(collection = 1)
        item_collections = UserCollection.objects.filter(school_id=school_id).values('user_id', 'collection')
        # 初始化一个空列表
        weighted_scores = []
        # 遍历 item_ratings 中的每一条记录
        for collection in item_collections:
            # 如果该收藏记录对应的用户在 similarities_jaccard 字典中,则计算该收藏记录对该物品的权重得分
            if collection['user_id'] in similarities_jaccard:
                # 获取该收藏记录对应用户与目标用户的相似度
                similarity = similarities_jaccard[collection['user_id']]
                # 计算该收藏记录对该物品的权重得分
                weighted_score = similarity * collection['collection']
                # 将该权重得分添加到列表中
                weighted_scores.append(weighted_score)
        numerator = sum(weighted_scores)
        denominator = sum(similarities_jaccard.values())
        if denominator > 0:
            recommendations_jaccard[school_id] = round(numerator / denominator, 2)
    # print("邻居用户已收藏的学校中目标用户未收藏的学校:", UserCollection.objects.filter(user_id__in=similarities).exclude(
    #     school_id__in=user_collections_school_id).values_list('school_id', flat=True).distinct())
    # print("基于用户收藏的兴趣度得分情况:",recommendations_jaccard)
    return recommendations_jaccard


# 基于用户评分计算当前用户和其他用户的余弦相似度
def user_cosine_similarity_ratings(user_id, default_similarity_cosine=0):
    # 获取当前用户评分数据
    user_ratings = UserScore.objects.filter(user_id=user_id).values('school_id', 'score')
    user_ratings_school_id = [user_rating['school_id'] for user_rating in user_ratings]
    # 获取当前用户评分学校的评分情况:(school_id,score)
    user_ratings_school = [(user_rating['school_id'], user_rating['score']) for user_rating in user_ratings]
    # print("当前用户评分情况:")
    # print(user_ratings_school)
    # print("基于用户评分的邻居用户评分情况:")
    # 构造当前用户评分向量:user_rating_vector
    user_rating_vector = [0 for i in range(999)]
    for school_id, score in user_ratings_school:
        user_rating_vector[school_id] = score
        # 根据评分情况计算所有用户的相似度:如果两用户之间没有共同评分的学校,则相似度为0
    similarities_cosine = {}
    for user in User.objects.exclude(id=user_id):
        # 获取当前用户与其他用户共同评价的物品的评分数据
        ratings = user.userscores.filter(school_id__in=user_ratings_school_id).values('school_id', 'score')
        if ratings:  # 如果当前用户与该用户有共同评分的学校,则计算当前用户与该用户的相似度,这里使用余弦相似度
            # 获取该用户所有的评分学校的评分情况:(school_id,score)
            ratings = user.userscores.filter().values('school_id', 'score')
            ratings_school = [(rating['school_id'], rating['score']) for rating in ratings]
            # print(ratings_school)
            # 构造该用户评分向量:rating_vector
            rating_vector = [0 for i in range(999)]
            for school_id, score in ratings_school:
                rating_vector[school_id] = score
            # print(rating_vector)
            # 计算两用户之间的余弦相似度
            similarity_cosine = cosine_similarity(user_rating_vector, rating_vector)
            if similarity_cosine > default_similarity_cosine:
                similarities_cosine[user.id] = similarity_cosine
    return similarities_cosine


# 基于用户评分计算当前用户对邻居评分院校的cosine兴趣度
def user_recommendations_cosine_ratings(user_id, similarities, similarities_cosine):
    # 获取当前用户评分数据
    user_ratings = UserScore.objects.filter(user_id=user_id).values('school_id', 'score')
    user_ratings_school_id = [user_rating['school_id'] for user_rating in user_ratings]

    # 根据相似度值为用户推荐物品
    recommendations_cosine = {}  # 定义字典存放物品id和物品相似度

    # 邻居用户已评分的学校中目标用户未评分的学校
    for school_id in UserScore.objects.filter(user_id__in=similarities).exclude(
            school_id__in=user_ratings_school_id).values_list('school_id', flat=True).distinct():
        # 获取评价了当前物品的用户和评分数据
        item_ratings = UserScore.objects.filter(school_id=school_id).values('user_id', 'score')
        # print("item_ratings:", item_ratings)
        # 初始化一个空列表
        weighted_scores = []
        # 遍历 item_ratings 中的每一条记录
        for rating in item_ratings:
            # 如果该评分记录对应的用户在 similarities 字典中,则计算该评分记录对该物品的权重得分
            if rating['user_id'] in similarities_cosine:
                # 获取该评分记录对应用户与目标用户的相似度
                similarity = similarities_cosine[rating['user_id']]
                # 计算该评分记录对该物品的权重得分
                weighted_score = similarity * rating['score']
                # 将该权重得分添加到列表中
                weighted_scores.append(weighted_score)
        numerator = sum(weighted_scores)
        denominator = sum(similarities_cosine.values())
        if denominator > 0:
            recommendations_cosine[school_id] = round(numerator / denominator, 2)
    # print("邻居用户已评分的学校中目标用户未评分的学校:", UserScore.objects.filter(user_id__in=similarities).exclude(
    #     school_id__in=user_ratings_school_id).values_list('school_id', flat=True).distinct())
    # print("基于用户评分的兴趣度得分情况:", recommendations_cosine)
    return recommendations_cosine

#补充推荐结果
def recommendations_supply(user_id, top_items: [tuple], top_n):
    print("top_items:", top_items)
    user_ratings = UserScore.objects.filter(user_id=user_id).values('school_id', 'score')
    user_ratings_school_id = [user_rating['school_id'] for user_rating in user_ratings]
    # 获取当前用户的收藏数据
    user_collections = UserCollection.objects.filter(user_id=user_id).values('school_id', 'collection')
    # 获取当前用户收藏的学校id
    user_collections_school_id = [user_collection['school_id'] for user_collection in user_collections]
    if len(top_items) < top_n:
        rest = top_n - len(top_items)
        exists_school_id = list(
            [top_item[0] for top_item in top_items]) + user_ratings_school_id + user_collections_school_id
        rest_id = set()
        while len(rest_id) < rest:
            random_id = random.randint(1, 855)
            if random_id not in exists_school_id:
                rest_id.add(random_id)
        recommendations_id = [item[0] for item in top_items] + list(rest_id)
    else:
        recommendations_id = [item[0] for item in top_items][:top_n]
    return recommendations_id


def user_based_recommend(request, default_similarity_jaccard=0, default_similarity_cosine=0, alpha=10):
    alpha_user = request.GET.get('alpha_user', '')
    if alpha_user != '':
        alpha_user = int(float(alpha_user))
        if 0 <= alpha_user <= 10:
            alpha = alpha_user
        elif alpha_user < 0:
            alpha_user = 0
        elif alpha_user > 10:
            alpha_user = 10
    alpha = alpha / 10
    # print("推荐依据:评分情况:{0},收藏情况:{1}".format(alpha, 1 - alpha))
    top_n = 12
    # 获取当前用户id
    user_id = list(request.session.values())[0].get('id')
    similarities_cosine = user_cosine_similarity_ratings(user_id, default_similarity_cosine=default_similarity_cosine)
    similarities_jaccard = user_jaccard_similarity_collections(user_id,
                                                               default_similarity_jaccard=default_similarity_jaccard)
    # print("similarities_cosine:", similarities_cosine)
    # print("similarity_jaccard:", similarities_jaccard)
    similarities = alpha * MyDict(similarities_cosine) + (1 - alpha) * MyDict(similarities_jaccard)
    # print("similarities:", similarities)

    # 测试:打印基于用户评分的用户相似度矩阵:
    # print("基于用户评分的用户相似度矩阵:")
    # print("user_id:", [i for i in similarities_cosine])
    # print("similarity:", [round(i, 2) for i in similarities_cosine.values()])

    # 测试:打印基于用户收藏的用户相似度矩阵:
    # print("基于用户收藏的用户相似度矩阵:")
    # print("user_id:", [i for i in similarities_jaccard])
    # print("similarity:", [round(i, 2) for i in similarities_jaccard.values()])

    # 根据相似度值为用户推荐物品
    # # 打印推荐字典
    recommendations_cosine = user_recommendations_cosine_ratings(user_id=user_id, similarities=similarities,
                                                                 similarities_cosine=similarities_cosine)
    recommendations_jaccard = user_recommendations_jaccard_collections(user_id=user_id, similarities=similarities,
                                                                       similarities_jaccard=similarities_jaccard)
    print("当alpha=0.5时基于评分的兴趣度得分情况:\n", recommendations_cosine)
    print("当alpha=0.5时基于收藏的兴趣度得分情况:\n", recommendations_jaccard)
    #
    # 测试:打印目标用户对于邻居用户中未评分学校的兴趣度得分
    recommendations = alpha * MyDict(recommendations_cosine) + (1 - alpha) * MyDict(recommendations_jaccard)

    recommendations = dict(filter(lambda item: item[1] > 0, recommendations.items()))
    print("当alpha=0.5时的加权兴趣度得分情况:\n", recommendations)

    # 返回前 top_n 个物品
    top_items = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)
    # print("Top items:", top_items)

    # 如果返回的数量不够top_n,就去随机补充一些没有被推荐和没有被当前用户评分过的学校id,补充至top_n个,返回top_n个被推荐学校的id
    # 如果够,直接返回top_n个被推荐学校的id
    recommendations_id = recommendations_supply(user_id=user_id, top_items=top_items, top_n=top_n)

    # 从数据库中根据id找到被推荐的学校,打乱顺序返回
    recommended_schools = models.School.objects.filter(id__in=recommendations_id).order_by('?')
    # 不打乱顺序,得分较高的排在前面
    # recommended_schools = models.School.objects.filter(id__in=[item[0] for item in top_items])
    # 2.实例化分页对象
    page_object = Pagination(request, recommended_schools, page_size=12)

    context = {
        "alpha": alpha_user,
        "a5": "active",
        "title": "基于用户推荐",
        "link": "https://yz.chsi.com.cn/",
        "recommended_schools": page_object.page_queryset,
        "page_string": page_object.html()  # 生成页码
    }
    return render(request, 'recommend_base.html', context)



123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301

标签:school,jaccard,similarities,推荐,用户,源码,user,毕业设计,id
From: https://blog.csdn.net/biyesheji0006/article/details/143673239

相关文章

  • 【源码分析】FutureTask超详细的源码分析
    介绍:FutureTask是一个可取消的异步计算。    1.通过get方法异步的获取任务执行结果    2.通过cancel方法来尝试取消正在执行的任务    3.通过get方法来捕获线程内部执行任务时抛出的异常    那么,大家是否知道上述这些方法的底层呢,为什么get方法能获取......
  • SSM航空票务管理系统-计算机设计毕业源码77189
    目录1绪论1.1选题背景与意义1.2国内外研究现状1.3研究的主要内容1.4论文结构与章节安排2系统分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3法律可行性分析2.2系统流程分析2.2.1数据新增流程2.2.2 数据删除流程2.3 系统功能分析2.3.......
  • asp.net程序设计1945消防宣传网站(源码)
    项目包含:源码、参考论文、讲解视频、说明文档请查看博主个人简介开发环境开发工具:VisualStudio2010或以上版本数据库:SQLServer2005或以上版本开发语言:c#操作系统:windows7或以上浏览器:GoogleChrome(推荐)、Edge、360浏览器消防工作是一项知识性、科学性、社会......
  • java计算机毕业设计电脑销售管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景在当今数字化的时代,电脑销售行业竞争日益激烈。随着市场的不断扩大,电脑产品的种类繁多,销售渠道也日益多样化,传统的管理方式已经难以满足企业高效......
  • java计算机毕业设计大学实验室app(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着大学教育的不断发展,实验室在教学、科研等方面的作用日益凸显。在当今数字化时代,传统的实验室管理方式已难以满足高效、便捷管理的需求。传统......
  • java计算机毕业设计大学生创新实践成果管理与分析推荐系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景在现代高等教育体系中,大学生创新实践活动日益受到重视,其是培养学生创新能力、实践能力和综合素质的关键途径。随着高校教育的不断发展,大学生参与......
  • django违法犯罪防范科普平台系统-计算机毕业设计源码84527
    摘 要本文介绍了一个基于Django的违法犯罪防范科普平台的设计与实现。随着社会的进步和科技的发展,违法犯罪活动呈现多样化和复杂化的趋势,对公众进行违法犯罪防范的科普教育变得尤为重要。该平台利用Django框架提供的高效且可扩展的特性,实现了用户注册与登录、科普文章发布与......
  • 必备的计算机软件专业资料汇总,包括:计算机专业实习报告,计算机毕业设计成品(含源码和论
    大学期间必备的计算机软件专业资料汇总,包括:计算机专业实习报告(58篇)、计算机毕业设计成品(含源码和论文,1900多套,包括C语言/PHP/VB/java/JSP/Andorid/Python/微信小程序等)、HTML+CSS+JS速查参考手册(收藏版)、42套div+css模板专题模板(各风格和行业应用网站模板),等等。此资料仅用于学习参......
  • Django电影推荐系统 豆瓣电影 协同过滤推荐算法 Echarts可视化 爬虫 机器学习 大数据
    博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌>......
  • 大数据毕业设计:Django电影推荐系统 双协同过滤推荐算法 爬虫 豆瓣电影 vue框架 (建议收
    博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌>......