新版本教务管理系统

教务管理系统 选课功能

1.系统功能

1、用户账户管理
2、学生个人信息的查看与修改
3、学生的网上选课与课程的评分
4、教师个人信息的查看与修改
5、教师对学生课程评价结果的查看
6、管理员对学生信息与教师信息的查看与添加
7、管理员对课程的增删改查
8、管理员对课程评价结果的统计与删除。
9、根据学生对课程评分的高低,在学生选课时进行推荐。

2、推荐算法的实现思路

欧氏距离相似性度量

在数学中,欧几里得距离或欧几里得度量是欧几里得空间中两点间“普通”(即直线)距离。使用这个距离,欧氏空间成为度量空间。相关联的范数称为欧几里得范数。
二维空间的公式

基于用户的协同过滤算法

基于一个这样的假设“跟你喜好相似的人喜欢的东西你也很有可能喜欢。”所以基于用户的协同过滤主要的任务就是找出用户的最近邻居,从而根据最近邻居的喜好做出未知项的评分预测。这种算法主要分为3个步骤:

  1. 用户评分
    可以分为显性评分和隐形评分两种。显性评分就是直接给项目评分(例如用户对电影评分),隐形评分就是通过评价或是购买的行为给项目评分 (例如淘宝上购买东西或者评论)。
  2. 寻找最近邻居
    这一步就是寻找与你距离最近的用户,测算距离一般采用以下三种算法:余弦定理相似性度量、欧氏距离相似度度量和杰卡德相似性度量。后面的demo会以欧氏距离相似度度量进行说明。
  3. 推荐
    产生了最近邻居集合后,就根据这个集合对未知项进行评分预测。把评分最高的N个项推荐给用户。

这种算法存在性能上的瓶颈,当用户数越来越多的时候,寻找最近邻居的复杂度也会大幅度的增长。

参考:https://www.jianshu.com/p/d0df3ead55a1

package cn.ltysyn.task;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import cn.ltysyn.bean.Course;
import cn.ltysyn.bean.Student;
import cn.ltysyn.service.ICourseService;
import cn.ltysyn.service.IElectiveService;
import cn.ltysyn.service.IRecommendService;
import cn.ltysyn.service.IStudentService;@Component
public class MyCFRecomment {//获取学生编号@Autowiredprivate IStudentService studentService;//获取课程信息@Autowiredprivate ICourseService courseService;//获取评分的信息@Autowiredprivate IElectiveService electiveService;@Autowiredprivate IRecommendService iRecommendService;//    //创建用户信息
//  //private List<Integer> stuList = new ArrayList<Integer>();
//  private static int[] stuArr = {1,2,3};
//  //创建课程信息
//  private static int[] couArr = {10,20,30};
//  //创建评分的集合 (学生 id , 分数集合)
//  private static Map<Integer,List<CourtsGoal>> goalMap = new HashMap<Integer, List<CourtsGoal>>();@Scheduled(cron = "0 0/10 * * * ?")  public void recommend() {//获取到所有的学生List<Student> selectAllStudent = studentService.selectAllStudent();//获取所有的课程//获取评分信息  根据学生id 和课程id 获取评分信息if(selectAllStudent.size()!=0) {Map<Integer,List<CourtsGoal>> goalMap = new HashMap<Integer, List<CourtsGoal>>();List<Integer> stuList = new ArrayList<Integer>();List<Course> selectAllCourse = (List<Course>) courseService.selectAllCourse();for(Student stu:selectAllStudent) {List<CourtsGoal> courtsGoals = new ArrayList<CourtsGoal>();for(Course cou:selectAllCourse) {CourtsGoal courtsGoal = new CourtsGoal();Integer goal = electiveService.selectByStuAndCourseId(stu.getStuId(),cou.getCourseId());courtsGoal.setCourtsId(cou.getCourseId());courtsGoal.setGoal(goal);courtsGoals.add(courtsGoal);}//获取到学生与课程评分的关系数据goalMap.put(stu.getStuId(), courtsGoals);stuList.add(stu.getStuId());}System.out.println(goalMap);//System.out.println(selectAllCourse);//计算用户相似度Map<Integer,List<List<Object>>> dataMap = calcUserSimilarity(stuList.toArray(),goalMap);//计算课程的推荐度Map<Integer, List<Object>> recommendCourse = calcRecommendCourse(dataMap,goalMap);//处理推荐电影列表Map<Integer, List<Object>> handleRecommendCourse = handleRecommendCourse(recommendCourse,goalMap);//删除所有推荐列表信息delectAllRecommendCourse();//保存推荐列表信息saveRecommendCourse(handleRecommendCourse);//删除重复的推荐信息//repeatRecomendCourse();}else {}}private void repeatRecomendCourse() {// TODO Auto-generated method stubiRecommendService.repeatRecomendCourse();}private void delectAllRecommendCourse() {// TODO Auto-generated method stubiRecommendService.delectAllRecommendCourse();}private void saveRecommendCourse(Map<Integer, List<Object>> handleRecommendCourse) {// TODO Auto-generated method stubiRecommendService.saveRecommendCourse(handleRecommendCourse);}  /** public static void main(String[] args) { System.out.println(goalMap);* //计算用户相似度 Map<Integer,List<List<Object>>> dataMap =* calcUserSimilarity(stuArr,goalMap); //计算课程的推荐度 Map<Integer, List<Object>>* recommendCourse = calcRecommendCourse(dataMap,goalMap); //处理推荐电影列表* handleRecommendCourse(recommendCourse,goalMap); }*/private static Map<Integer, List<Object>> handleRecommendCourse(Map<Integer, List<Object>> recommendCourse,Map<Integer,List<CourtsGoal>> goalMap) {Map<Integer, List<Object>> handleRecommendCourse = new HashMap<Integer, List<Object>>();for(Map.Entry<Integer,List<Object>> reco:recommendCourse.entrySet()) {//拿到推荐列表List<Object> re_l = reco.getValue();List<Object> handleCourse = new ArrayList<Object>();for(Object obj:re_l) {List<CourtsGoal> list = goalMap.get(reco.getKey());for(CourtsGoal c_goal:list) {if(Integer.parseInt(obj.toString())==c_goal.getCourtsId()) {if(c_goal.getGoal()==0) {handleCourse.add(c_goal.getCourtsId());}}}}handleRecommendCourse.put(reco.getKey(), handleCourse);}System.out.println("最终推荐列表"+handleRecommendCourse);return handleRecommendCourse;}/** 计算用户相似度 * 返回最相近的两个*/public static Map<Integer,List<List<Object>>> calcUserSimilarity(Object[] stuArr_p,Map<Integer,List<CourtsGoal>> goalMap_p) {//similarityUsers=new ArrayList();//遍历学生 求出当前学生与其他学生的相似度//相似用户集合Map<Integer,List<List<Object>>> dataMap = new HashMap<Integer, List<List<Object>>>();for(Object stu:stuArr_p) {//取两个相似的List<List<Object>> similarityUsers= new ArrayList();List<List<Object>> userSimilaritys=new ArrayList<List<Object>>();//遍历goalMap_p for(Map.Entry<Integer,List<CourtsGoal>> goal:goalMap_p.entrySet()) {//如果当前的学生 和 存储的 key相等 则跳过if(stu.toString().equals(goal.getKey().toString())) {continue;}List<Object> userSimilarity=new ArrayList<Object>();//记录当前的学生编号userSimilarity.add(goal.getKey());userSimilarity.add(calcTwoUserSimilarity(goal.getValue(),goalMap_p.get((Integer)stu)));userSimilaritys.add(userSimilarity);}sortCollection(userSimilaritys);System.out.println("与"+stu+"的相似度为:"+userSimilaritys);similarityUsers.add(userSimilaritys.get(0));similarityUsers.add(userSimilaritys.get(1));dataMap.put((Integer)stu, similarityUsers);}System.out.println(dataMap);//表示该学生 与其他两个学生的相似度为多少return dataMap;}/*** 获取全部推荐课程,计算平均课程推荐度*/private static Map<Integer,List<Object>> calcRecommendCourse(Map<Integer,List<List<Object>>> dataMap,Map<Integer,List<CourtsGoal>> goalMap){Map<Integer,List<List<Object>>> cf_map =  new HashMap<Integer, List<List<Object>>>();//存储没有课程的总的推荐分数Map<Integer,Double> cf_sumRate =  new HashMap<Integer, Double>();//遍历dataMap  分别拿到不同的学生  推荐的课程for(Map.Entry<Integer,List<List<Object>>> data:dataMap.entrySet()) {double recommdRate=0,sumRate=0;//拿到的是哪个用户  第一个//data.getValue().get(0).get(0);//拿到该用户的相识度值 第一个double xs_1 = Double.parseDouble(data.getValue().get(0).get(1).toString());//拿到的是哪个用户  第二个//data.getValue().get(1).get(0);//拿到该用户的相识度值 第二个double xs_2 = Double.parseDouble(data.getValue().get(1).get(1).toString());List<CourtsGoal> list_1 = goalMap.get(data.getValue().get(0).get(0));List<CourtsGoal> list_2 = goalMap.get(data.getValue().get(1).get(0));if(list_1.size()==list_2.size()) {List<List<Object>> recommendCourts = new ArrayList<List<Object>>();for(int i=0;i<list_1.size();i++) {List<Object>  recommendCourt=new ArrayList();recommdRate = list_1.get(i).getGoal() * xs_1 + list_2.get(i).getGoal() * xs_2;//添加课程recommendCourt.add(list_1.get(i).getCourtsId());//添加该课程推荐度recommendCourt.add(recommdRate);//被推荐的用户 、课程、课程的推荐度//System.err.println("用户"+data.getKey()+"课程"+list_1.get(i)+":"+recommdRate);recommendCourts.add(recommendCourt);sumRate+=recommdRate;}cf_map.put(data.getKey(), recommendCourts);cf_sumRate.put(data.getKey(), sumRate);}//for(CourtsGoal cGoal:list_1) {//System.out.println("给用户"+data.getKey()+"推荐的用户是:"+data.getValue().get(0).get(0)+"相似值是:"+data.getValue().get(0).get(1)+"课程信息"+cGoal.getCourtsId()+"评分"+cGoal.getGoal());//}}System.err.println(cf_map);System.out.println(cf_sumRate);//当前集合存放的是  给 key  推荐的课程集合Map<Integer,List<Object>> target_map = new HashMap<Integer, List<Object>>();for(Map.Entry<Integer,List<List<Object>>> cf_d:cf_map.entrySet()) {List<Object> targetRecommendCourts = new ArrayList<Object>();for(List<Object> obj:cf_d.getValue()) {if(Double.parseDouble(obj.get(1).toString()) > cf_sumRate.get(cf_d.getKey())/cf_d.getValue().size()){ //大于平均推荐度的商品才有可能被推荐targetRecommendCourts.add(obj.get(0));}}target_map.put(cf_d.getKey(), targetRecommendCourts);}System.out.println("最终:"+target_map);return target_map;}/*** 根据用户数据,计算用户相似度(欧氏距离)* @param user1Stars 其他用户评价分数* @param user2Starts  当前用户评价的分数* @return*/private static double calcTwoUserSimilarity(List<CourtsGoal> user1Stars,List<CourtsGoal> user2Starts){float sum=0;for(int i=0;i<user1Stars.size();i++){sum+=Math.pow(user1Stars.get(i).getGoal()-user2Starts.get(i).getGoal(),2);//平方}return Math.sqrt(sum);//开方}/*** 集合排序* @param list*/private static void sortCollection(List<List<Object>> list){Collections.sort(list, new Comparator<List<Object>>() {@Overridepublic int compare(List<Object> o1, List<Object> o2) {if(Double.valueOf(o1.get(1).toString()) > Double.valueOf(o2.get(1).toString())){return 1;}else if(Double.valueOf(o1.get(1).toString()) < Double.valueOf(o2.get(1).toString())){return -1;}else{return 0;}}});}}

系统功能截图

基于协同过滤算法实现选课推荐系统相关推荐

  1. 【毕业设计_课程设计】基于协同过滤算法的个性化推荐系统(源码+论文)

    文章目录 0 项目说明 1 研究目的 2 研究方法 3 系统设计 3.1 前台模块 3.1.1 首页 3.1.2 个人中心 3.1.3 发布者中心 3.2 后台模块 3.2.1 首页 3.2.2 新闻 ...

  2. 计算机毕业设计之java+ssm基于协同过滤算法的图书推荐系统

    计算机毕业设计之java+ssm基于协同过滤算法的图书推荐系统 项目介绍 "互联网:"的战略实施后,很多行业的信息化水平都有了很大的提升.但是目前很多行业的管理仍是通过人工管理的方 ...

  3. 计算机毕业设计ssm基于协同过滤算法的甜品推荐系统uhnk3系统+程序+源码+lw+远程部署

    计算机毕业设计ssm基于协同过滤算法的甜品推荐系统uhnk3系统+程序+源码+lw+远程部署 计算机毕业设计ssm基于协同过滤算法的甜品推荐系统uhnk3系统+程序+源码+lw+远程部署 本源码技术栈 ...

  4. (附源码)计算机毕业设计SSM基于协同过滤算法的甜品推荐系统

    (附源码)计算机毕业设计SSM基于协同过滤算法的甜品推荐系统 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclisp ...

  5. 基于协同过滤算法的电影推荐系统

    目录 前言 R语言 电影推荐系统 案例及代码 数据准备 数据预处理 建立模型 前言 电影推荐系统是数学建模培训中一次例题,网上对相同类型的模型已有答案,但相关代码跑起来仍然存在些许bug,本文基于同类 ...

  6. 毕业设计-基于协同过滤算法的旅游推荐系统

    目录 前言 课题背景和意义 实现技术思路 一.协同过滤算法的概念 二.旅游景点推荐系统设计与实现 三.总结 实现效果图样例 最后 前言

  7. 【计算机毕业设计】Java基于协同过滤算法的音乐推荐系统

    毕设帮助.开题指导.源码交流,联系方式见文末.. 音乐检索系统的开发目的是使音乐检索模式转变成信息管理,为音乐检索人员提供方便条件.对音乐检索的实际情况进行调研之后,进行详细的需求分析,对现有的管理模 ...

  8. [附源码]Python计算机毕业设计SSM基于协同过滤算法的甜品推荐系统(程序+LW)

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  9. ssm+jsp计算机毕业设计基于协同过滤算法的旅游推荐系统a8749(程序+lw+源码+远程部署).

    项目运行 项目含有源码(见文末).文档.程序.数据库.配套开发软件.软件安装教程 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ E ...

最新文章

  1. hdfs 创建用户和用户组_hadoop四:linux用户和组命令
  2. Note6:batch file programming
  3. matlab RBF 神经网络拟合
  4. Visual Studio 2005 Beta 2 will ship on April 25th
  5. [USACO1.4]母亲的牛奶 Mother's Milk
  6. 全国小学四则运算1.0
  7. 借助大数据进行社交媒体营销,企业们得这么玩!
  8. MySQL------如何将SQLServer文件数据迁移到MySQL
  9. 20171108 模拟题 T1
  10. bgp通告四原则_华为路由器BGP路由选路和负载均衡
  11. django jsonresponse_0基础掌握Django框架(29)HttpResponse对象
  12. python w3cschool_学习Python必去的8个网站
  13. 实参和形参的一些问题
  14. 打造最便捷的异步分页技术(提供下载)
  15. 【安全牛学习笔记】SSL、TLS拒绝服务***和补充概念
  16. Citrix 桌面云 XenApp_XenDesktop_7.18 部署
  17. python读取uci数据集
  18. 【编译打包】btsync-1.2.82-beta.el6.src.rpm
  19. Web框架-SSM框架
  20. React在ESLint下的报错收录(react-hooks/exhaustive-deps)

热门文章

  1. 修改ceph crush map,并指定到资源池
  2. Activity启动流程图
  3. 从Excel中导入数据时,提示“未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序”的解决办法...
  4. Thrift源码解析--TBinaryProtocol
  5. 微信 小程序布局 水平菜单
  6. Java transient
  7. linux之x86裁剪移植---字符界面sdl开发入门
  8. JavaScript正则表达式基础知识汇总
  9. HTTP协议Etag详解
  10. linux下查看内存使用情况