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

2024-06-09 02:04

本文主要是介绍基于协同过滤推荐的在线课程选修系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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.chinasem.cn/article/1043942

相关文章

Nginx配置系统服务&设置环境变量方式

《Nginx配置系统服务&设置环境变量方式》本文介绍了如何将Nginx配置为系统服务并设置环境变量,以便更方便地对Nginx进行操作,通过配置系统服务,可以使用系统命令来启动、停止或重新加载Nginx... 目录1.Nginx操作问题2.配置系统服android务3.设置环境变量总结1.Nginx操作问题

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

CSS3 最强二维布局系统之Grid 网格布局

《CSS3最强二维布局系统之Grid网格布局》CS3的Grid网格布局是目前最强的二维布局系统,可以同时对列和行进行处理,将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局,本文介... 深入学习 css3 目前最强大的布局系统 Grid 网格布局Grid 网格布局的基本认识Grid 网

前端 CSS 动态设置样式::class、:style 等技巧(推荐)

《前端CSS动态设置样式::class、:style等技巧(推荐)》:本文主要介绍了Vue.js中动态绑定类名和内联样式的两种方法:对象语法和数组语法,通过对象语法,可以根据条件动态切换类名或样式;通过数组语法,可以同时绑定多个类名或样式,此外,还可以结合计算属性来生成复杂的类名或样式对象,详细内容请阅读本文,希望能对你有所帮助...

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图

Java中实现订单超时自动取消功能(最新推荐)

《Java中实现订单超时自动取消功能(最新推荐)》本文介绍了Java中实现订单超时自动取消功能的几种方法,包括定时任务、JDK延迟队列、Redis过期监听、Redisson分布式延迟队列、Rocket... 目录1、定时任务2、JDK延迟队列 DelayQueue(1)定义实现Delayed接口的实体类 (

shell脚本自动删除30天以前的文件(最新推荐)

《shell脚本自动删除30天以前的文件(最新推荐)》该文章介绍了如何使用Shell脚本自动删除指定目录下30天以前的文件,并通过crontab设置定时任务,此外,还提供了如何使用Shell脚本删除E... 目录shell脚本自动删除30天以前的文件linux按照日期定时删除elasticsearch索引s

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

CentOS系统Maven安装教程分享

《CentOS系统Maven安装教程分享》本文介绍了如何在CentOS系统中安装Maven,并提供了一个简单的实际应用案例,安装Maven需要先安装Java和设置环境变量,Maven可以自动管理项目的... 目录准备工作下载并安装Maven常见问题及解决方法实际应用案例总结Maven是一个流行的项目管理工具

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查