基于协同过滤推荐的在线课程选修系统

基于协同过滤推荐的在线课程选修系统

demo

网站查看 http://course.qsxbc.com/all_course/
点我查看
效果
在这里插入图片描述

功能

登录注册、点赞收藏、评分评论,课程推荐,热门课程,个人中心,可视化,后台管理,课程选修

推荐算法

# -*-coding:utf-8-*-
"""
@contact: 微信 1257309054
@file: recommend_user.py
@time: 2024/6/8 16:21
@author: LDC
使用Keras框架实现一个深度学习推荐算法
"""import collections
import math
import os
import django
import operator
import numpy as np
from course.models import *
from k_means_utils import predictos.environ["DJANGO_SETTINGS_MODULE"] = "course_manager.settings"
django.setup()def get_default_recommend(user_id):# 获取默认推荐# 获取用户注册时选择的类别category_ids = []us = UserSelectTypes.objects.get(user_id=user_id)for category in us.category.all():category_ids.append(category.id)course_list = CourseInfo.objects.filter(tags__in=category_ids).distinct().order_by("-collect_num")[:30]return course_listclass UserCf:# 基于用户协同算法来获取推荐列表"""利用用户的群体行为来计算用户的相关性。计算用户相关性的时候我们就是通过对比他们选修过多少相同的课程相关度来计算的举例:--------+--------+--------+--------+--------+|   X    |    Y   |    Z   |    R   |--------+--------+--------+--------+--------+a   |   1    |    1   |    1   |    0   |--------+--------+--------+--------+--------+b   |   1    |    0   |    1   |    0   |--------+--------+--------+--------+--------+c   |   1    |    1   |    0   |    1   |--------+--------+--------+--------+--------+a用户选修了:X、Y、Zb用户选修了:X、Zc用户选修了:X、Y、R那么很容易看到a用户和b、c用户非常相似,给a用户推荐课程R,给b用户推荐课程Y给c用户推荐课程Z这就是基于用户的协同过滤。a用户向量为(1,1,1,0)b用户向量为(1,0,1,0)c用户向量为(1,1,0,1)找a用户的相似用户,则计算a向量与其他向量的夹角即可,夹角越小则说明越相近利用求高维空间向量的夹角,可以估计两组数据的吻合程度"""# 获得初始化数据def __init__(self, data):self.data = data# 计算N维向量的夹角def calc_vector_cos(self, a, b):'''cos=(ab的内积)/(|a||b|):param a: 向量a:param b: 向量b:return: 夹角值'''a_n = np.array(a)b_n = np.array(b)if any(b_n) == 0:return 0cos_ab = a_n.dot(b_n) / (np.linalg.norm(a_n) * np.linalg.norm(b_n))print('值为', cos_ab)return round(cos_ab, 2)# 计算与当前用户的距离,获得最临近的用户def nearest_user(self, username, n=2):distances = {}# 用户,相似度# 遍历整个数据集for user, rate_set in self.data.items():# 非当前的用户if user != username:print('获取{}与{}的向量夹角'.format(username, user))vector_a = tuple(self.data[username].values())vector_b = tuple(self.data[user].values())distance = self.calc_vector_cos(vector_a, vector_b)# 计算两个用户的相似度distances[user] = distance# 排序,按向量夹角由小到到排序closest_distance = sorted(distances.items(), key=operator.itemgetter(1), reverse=True)# 最相似的N个用户closest_users = []for cd in closest_distance:if cd[1] == 1:closest_users.append(cd)else:if len(closest_users) >= n:breakclosest_users.append(cd)print("closest user:", closest_users)return closest_users# 给用户推荐课程def recommend(self, username, n=1):recommend = set()nearest_user = self.nearest_user(username, n)  # 获取最相近的n个用户for user_id, _ in nearest_user:for usercourse in UserCourse.objects.filter(user_id=user_id):if usercourse.course.id not in self.data[username].keys():recommend.add(usercourse.course.id)return recommend# 用户推荐
def recommend_by_user_id(user_id, is_mix=False):# 通过用户协同算法来进行推荐current_user = User.objects.get(id=user_id)# 如果当前用户没有选修过课程,则按照收藏量降序返回if current_user.usercourse_set.count() == 0:if is_mix:return []return get_default_recommend(user_id)data = {}course_ids = []other_user_ids = set()# 把该用户选修过的课程变成向量字典:{'用户id': {'课程1id': 1, '课程2id': 1...}}for u_course in current_user.usercourse_set.all():# 遍历用户选修过的课程if not data:data[current_user.id] = {u_course.course.id: 1}  # 已选课程,设置值为1else:data[current_user.id][u_course.course.id] = 1course_ids.append(u_course.course)# 获取其他选修过该课程的用户idfor usercourse in UserCourse.objects.filter(course=u_course.course):if usercourse.user.id != current_user.id:other_user_ids.add(usercourse.user.id)# 把选修过其中课程的用户选修过的课程变成向量字典:{'用户2id': {'课程1id': 0, '课程2id': 1...}}for other_user in User.objects.filter(pk__in=other_user_ids):other_user_id = other_user.idfor i in range(len(course_ids)):course = course_ids[i]if UserCourse.objects.filter(user_id=other_user_id, course=course):is_select = 1else:is_select = 0if other_user_id not in data:data[other_user_id] = {course.id: is_select}  # 已选课程,设置值为1,未选课程设置为0else:data[other_user_id][course.id] = is_selectuser_cf = UserCf(data=data)recommend_ids = user_cf.recommend(current_user.id, 1)if not recommend_ids:# 如果没有找到相似用户则按照收藏量降序返回if is_mix:return []return get_default_recommend(user_id)if is_mix:return list(recommend_ids)return CourseInfo.objects.filter(is_show=True, id__in=recommend_ids).order_by('-select_num')# 物品推荐
class ItemCf:# 基于物品协同算法来获取推荐列表'''1.构建⽤户–>物品的对应表2.构建物品与物品的关系矩阵(同现矩阵)3.通过求余弦向量夹角计算物品之间的相似度,即计算相似矩阵4.根据⽤户的历史记录,给⽤户推荐物品'''def __init__(self, user_id):self.user_id = user_id  # 用户iddef get_data(self):# 获取用户评分过的课程rate_courses = RateCourse.objects.filter()if not rate_courses:return Falsedatas = {}for rate_course in rate_courses:user_id = rate_course.user_idif user_id not in datas:datas.setdefault(user_id, {})datas[user_id][rate_course.course.id] = rate_course.markelse:datas[user_id][rate_course.course.id] = rate_course.markreturn datasdef similarity(self, data):# 1 构造物品:物品的共现矩阵N = {}  # 喜欢物品i的总⼈数C = {}  # 喜欢物品i也喜欢物品j的⼈数for user, item in data.items():for i, score in item.items():N.setdefault(i, 0)N[i] += 1C.setdefault(i, {})for j, scores in item.items():if j != i:C[i].setdefault(j, 0)C[i][j] += 1print("---1.构造的共现矩阵---")print('N:', N)print('C', C)# 2 计算物品与物品的相似矩阵W = {}for i, item in C.items():W.setdefault(i, {})for j, item2 in item.items():W[i].setdefault(j, 0)W[i][j] = C[i][j] / math.sqrt(N[i] * N[j])print("---2.构造的相似矩阵---")print(W)return Wdef recommand_list(self, data, W, user, k=3, N=10):'''# 3.根据⽤户的历史记录,给⽤户推荐物品:param data: 用户数据:param W: 相似矩阵:param user: 推荐的用户:param k: 相似的k个物品:param N: 推荐物品数量:return:'''rank = {}for i, score in data[user].items():  # 获得⽤户user历史记录,如A⽤户的历史记录为{'唐伯虎点秋香': 5, '逃学威龙1': 1, '追龙': 2}for j, w in sorted(W[i].items(), key=operator.itemgetter(1), reverse=True)[0:k]:  # 获得与物品i相似的k个物品if j not in data[user].keys():  # 该相似的物品不在⽤户user的记录⾥rank.setdefault(j, 0)rank[j] += float(score) * w  # 预测兴趣度=评分*相似度print("---3.推荐----")print(sorted(rank.items(), key=operator.itemgetter(1), reverse=True)[0:N])return sorted(rank.items(), key=operator.itemgetter(1), reverse=True)[0:N]def recommendation(self, k=3, N=10):"""给用户推荐相似课程:param user: 推荐的用户:param k: 相似的k个物品:param N: 推荐物品数量"""data = self.get_data()if not data or self.user_id not in data:# 用户没有评分过任何课程,就返回空列表return []W = self.similarity(data)  # 计算物品相似矩阵sort_rank = self.recommand_list(data, W, self.user_id, k, N)  # 推荐return sort_rankdef recommend_by_item_id(user_id, is_mix=False):# 物品推荐cf_list = ItemCf(user_id).recommendation()  # 物品协同过滤得到的推荐列表course_ids = [s[0] for s in cf_list]if is_mix:return course_idscourse_list = CourseInfo.objects.filter(id__in=course_ids).distinct().order_by("-select_num")if not course_list:# 推荐列表为空if is_mix:return []return get_default_recommend(user_id)return course_list# k-means推荐
def recommend_by_k_mean(user_id, course_id=None, is_mix=False):# 使用机器学习K-means聚类算法推荐用户喜欢的课程try:data = []  # 用户课程类型挑选列表tag_dict = collections.OrderedDict()  # 课程类型字典(有序字典)# 获取所有类型,并设置值为0for tag in Tags.objects.filter():tag_dict[tag.name] = 0# 获取用户喜欢的课程类型us = UserSelectTypes.objects.get(user_id=user_id)for category in us.category.filter():# 在类型字典中设置用户喜欢的类型为1tag_dict[category.name] = 1data.append(list(tag_dict.values()))tag_like_list = predict(data)  # 预测数据if not tag_like_list:# 预测推荐集合为空,则返回用户注册时选择的类别if is_mix:return []return get_default_recommend(user_id)index = 0recommend_tag = []for tag, value in tag_dict.items():if tag_like_list[index] == 1:# 用户喜欢的课程类型recommend_tag.append(tag)index += 1print('推荐的类型', recommend_tag)rank_set = set()  # 推荐课程id集合# 获取各推荐课程类型中排行前三的课程推荐给用户,其中排行按照收藏量来计算for tag in recommend_tag:courses = CourseInfo.objects.filter(tags__name=tag).order_by("-collect_num")[:5]for course in courses:rank_set.add(course.id)print('推荐的列表id', rank_set)if is_mix:return list(rank_set)if rank_set:course_list = CourseInfo.objects.filter(id__in=rank_set).exclude(id=course_id).distinct().order_by("-collect_num")return course_listexcept Exception as e:print('k-means出错', e)# 预测推荐集合为空,则返回用户注册时选择的类别if is_mix:return []return get_default_recommend(user_id)# 混合推荐
def recommend_by_mix(user_id):recommend_user_ids = recommend_by_user_id(user_id, is_mix=True)  # 基于用户推荐print('recommend_user_ids', recommend_user_ids)recommend_item_ids = recommend_by_item_id(user_id, is_mix=True)  # 基于物品推荐print('recommend_item_ids', recommend_item_ids)recommend_kmean_ids = recommend_by_k_mean(user_id, is_mix=True)  # 基于k-means推荐print('recommend_kmean_ids', recommend_kmean_ids)recommend_ids = list(set(recommend_user_ids + recommend_item_ids + recommend_kmean_ids)) # 总的推荐列表print('总的推荐列表', recommend_ids)course_list = CourseInfo.objects.filter(is_show=True, id__in=recommend_ids).order_by('-select_num')if not course_list:# 推荐列表为空return get_default_recommend(user_id)return course_list

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/24774.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python文件:py,ipynb, pyi, pyc, pyd, pyo都是什么文件?

1、Python文件类型介绍 📁 1.1 .py 文件:源代码基础 .py 文件是 Python 最基本的源代码文件格式,用于存储纯文本形式的 Python 代码。它是开发者编写程序的主要场所,包含函数、类、变量定义以及执行逻辑。Python 解释器直接读取…

高考后的职业规划:学习LabVIEW开发前景广阔

在今天的高考后,选择学习LabVIEW开发为未来职业规划将大有可为。LabVIEW以其图形化编程、强大的数据处理和硬件集成功能,广泛应用于工程、科研、自动化测试等领域。掌握LabVIEW开发技能,不仅就业前景广阔,还能参与前沿技术应用&am…

SQL进阶day10————多表查询

目录 1嵌套子查询 1.1月均完成试卷数不小于3的用户爱作答的类别 1.2月均完成试卷数不小于3的用户爱作答的类别 ​编辑1.3 作答试卷得分大于过80的人的用户等级分布 2合并查询 2.1每个题目和每份试卷被作答的人数和次数 2.2分别满足两个活动的人 3连接查询 3.1满足条件…

Linux 35.5 + JetPack v5.1.3@FC-Planner编译安装

Linux 35.5 JetPack v5.1.3FC-Planner编译安装 1. 源由2. 编译&安装Step 1:依赖库安装Step 2:克隆工程Step 3:编译工程Step 4:LKH编译Step 5:安装工程 3. 问题汇总3.1 Killed signal terminated program cc1plus3…

【Unity】 HTFramework框架(五十一)代码片段执行器

更新日期:2024年6月8日。 Github源码:[点我获取源码] Gitee源码:[点我获取源码] 索引 Code Snippet Executer 代码片段执行器使用 Code Snippet Executer打开 Code Snippet Executer动态执行(代码片段)静态执行&#x…

MySQL——C语言连接数据库

MySQL Connection ​ 连接数据库的客户端除了命令行式的还有图形化界面版本,网页版本,当然也包括语言级别的库或者是包,能够帮助我们直接连接数据库; 一、语言连接库下载 方式一:不建议使用,需要自己配置…

记录项目使用ts时引入js文件后导致项目运行空白问题

主要原因: 使用ts后开启了eslint检测,而js压缩文件引入的位置在eslint检测的文件内。导致eslint检测认为该文件为很大的文件,或eslint认为此文件内存在无法处理的语法结构等问题。 解决方法: 1、把文件移到eslint检测外的文件引入…

R语言数据探索和分析23-公共物品问卷分析

第一次实验使用最基本的公共物品游戏,不外加其他的treatment。班里的学生4人一组,一共44/411组。一共玩20个回合的公共物品游戏。每回合给15秒做决定的时间。第十回合后,给大家放一个几分钟的“爱心”视频(链接如下)&a…

物证管理系统|DW-S404实现物证科学化管理

随着社会的进步和科技的发展,信息化和数字化已经成为各个行业的必然趋势。在众多领域中,物证管理系统逐渐受到广泛的关注和应用。 物证是公安机关处理案件的关键凭证,针对过去物证管理分散、损毁遗失等严重问题,集驰电子JIONCH推…

红队神器Evil-winrm的使用

前言 Evil-winrm 工具最初是由 Hackplayers 团队开发的。开发该工具的目的是尽可能简化渗透测试,尤其是在 Microsoft Windows 环境中。 Evil-winrm 使用 PowerShell 远程协议 (PSRP),且系统和网络管理员经常使用Windows Remote Management 协议进行上传和…

DDei在线设计器-DDeiCore-布局插件

DDei-Core-布局 如需了解详细的API教程以及参数说明,请参考DDei文档 标准布局 经典的框架结构布局,包含了顶部菜单栏、控件工具项、画布、属性面板和底部工具栏等功能面板,通过插件配置可以调整每个部分的顺序和内容。 效果截图 使用方式…

基于JSP技术的文物管理系统

你好呀,我是计算机学长猫哥!如果有相关需求,文末可以找到我的联系方式。 开发语言:Java 数据库:MySQL 技术:JSP技术 工具:IDEA/Eclipse、Navicat、Maven 系统展示 首页 管理员界面 用户前台…

【庞加莱几何-02】反演定理和证明

文章目录 一、说明二、 inversion和 reflection三、圆反演的定义四、广义的圆反演成圆 关键词:inversion、reflection 一、说明 这里是庞加莱几何的第二篇文章,是庞加莱基本几何属性的研究。本篇主要说清楚,什么是反演,在反演情况…

【面试官】知道synchronized锁升级吗

一座绵延在水上的美术馆——白鹭湾巧克力美术馆。它漂浮于绿水之上,宛如一条丝带轻盈地伸向远方 文章目录 可重入锁synchronized实现原理 synchronized缺点保存线程状态锁升级锁升级优缺点 1. 可重入锁 面试官:知道可重入锁有哪些吗? 可重入意味着获取…

HTTPS缺失?如何轻松解决IP地址访问时的“不安全”警告

一、问题现象 如果访问网站时出现以下任何一种情况,则说明该网站需要立即整改: 1.浏览器地址栏那里出现“不安全”字样; 2.小锁标志被红叉()、斜线(\)等标志为不可用;…

sub_mch_id 与 sub_appid 不匹配怎么解决

小程序在支付的时候,有时候会碰到:sub_mch_id 与 sub_appid 不匹配的问题。这个问题意味着小程序微信支付时所使用的 sub_mch_id(子商户号)和 sub_appid(小程序的appId)不对应。下面就具体介绍如何核对是否…

武汉理工大学嵌入式系统应用之临时抱佛脚复习

其实大学很多课程的期末冲刺复习非常简单,就是在大脑中构建一个redis数据库就行了,缓存下一大堆键值对,然后考试的时候输出,很没意思。 嵌入式系统的定义 以应用为中心,以计算机技术为基础,软件硬件可裁剪…

LabVIEW控制PLC的实现方式

LabVIEW与PLC的结合可以充分发挥两者的优点,实现更高效、灵活和可靠的自动化控制系统。本文将详细介绍LabVIEW控制PLC的实现方式,包括通信接口、数据交换、编程方法及实际应用案例,帮助用户理解并应用这一技术。 通信接口 常见通信协议 La…

LabVIEW与PLC的区别

LabVIEW和PLC是工业自动化领域中常见的两种控制和测控方案,各自有独特的优点和适用场景。本文将从多角度比较两者,帮助用户在选择控制系统时做出更明智的决策。 技术背景 LabVIEW LabVIEW是由National Instruments公司开发的图形化编程环境&#xff0…

ChatGPT-4o, 腾讯元宝,通义千问对比测试中文文化

国内的大模型应用我选择了国内综合实力最强的两个,一个是腾讯元宝,一个是通义千问。其它的豆包,Kimi,文心一言等在某些领域也有强于竞品的表现。 问一个中文文化比较基础的问题,我满以为中文文化chatGPT不如国内的大模型。可事实…