国庆策划 | 深度学习推荐系统基础,你掌握了多少?

你好,我是王喆。

今天是国庆假期的第二天,我在基础架构篇的基础上,设计了一套测试题,希望你能在假期里试做一下,温故知新,巩固所学。

在这套测试题中,有 10 道选择题,每道题 10 分,满分为 100。这些内容全部来自我们之前专栏所讲的内容,都是基础知识,希望能帮助你查缺补漏。

最后呢,我还为你准备了两道实践题,这两道题为选做。如果你对自己有更高的要求,我希望你可以show me the code!当然,在答题和实践中遇到任何问题,都可以在留言区评论,我们一起来探讨。还等什么,点击下面的按钮开始测试吧!

选择题

问答题

第一题:通过阅读SparrowRecSys的代码,你能找到首页中每行内部的电影都是按照什么排序的吗?

第二道题:如果你已经发现了排序的规则,你能在推荐服务器的代码里添加一个叫“热度”(popularity)的排序规则,然后让首页按照“热度”排序吗(💡补充:热度的定义是“这个电影被评价的次数”)?

我相信这是熟悉movielens数据、推荐服务器代码的一个非常好的机会,那在实现过程中的任何问题,都欢迎你留言和我交流!我们10月9日再见!

精选留言

  • 神经蛙

    2020-11-24 21:09:54

    课后题:
    1.排序依据:
    根据影片历史平均评分,降序排列。详细调用过程:
    a.index.html里面的js代码,调用在头部加载的recsys.js 的addGenreRow, 传入参数(页面ID,影片类别名称,rowId, 每行放置影片个数,baseUrl)
    b.在addGenreRow调用已注册的 getrecommendation 服务,传参的排序依据为rating.
    c.服务getrecommendation绑定类RecommendationService, GET请求数据
    d.RecommendationService.doGet 中 调用 online.datamanager.DataManager#getMoviesByGenre,根据每个影片的历史平均rating,降序排列.
    2.根据popularity排序:
    a.recsys.js
    function addGenreRow(pageId, rowName, rowId, size, baseUrl) {
    addRowFrame(pageId, rowName, rowId, baseUrl);
    $.getJSON(baseUrl + "getrecommendation?genre="+rowName+"&size="+size+"&sortby=popularity", function(result){
    $.each(result, function(i, movie){
    appendMovie2Row(rowId, movie.title, movie.movieId, movie.releaseYear, movie.averageRating.toPrecision(2), movie.ratingNumber, movie.genres,baseUrl);
    });
    });
    };
    b.com.wzhe.sparrowrecsys.online.datamanager.DataManager#getMoviesByGenre:
    添加一行:
    case "popularity": movies.sort((m1, m2) -> Integer.compare(m2.getRatingNumber(), m1.getRatingNumber()));break;

    用mmovie.getRatings.size() 也行,但应该效率比上面的低。
    c.改改前端的展示代码
    不太擅长
    作者回复

    非常好。前端展示代码不用修改,修改js就可以了。

    2020-11-25 03:29:55

  • Sean

    2021-04-28 15:52:48

    第一题
    是根据电影的分数(rating)排序的

    第二题
    1. 先从RecSysServer.java进入,找到68行的RecommendationService
    2. 再看到getMoviesByGenre.java第35行的getMoviesByGenre()
    3. 在switch中新增: case "popularity": movies.sort((m1, m2) -> Integer.compare(m2.getRatingNumber(), m1.getRatingNumber()));break; 就是按照热度排序了
    4. 再回到RecommendationService的33行, String sortby = request.getParameter("sortby"); 代表排序依据的参数是由某个api传入的
    5. 找到recsys.js第102行,把sortby=rating修改为sortby=popularity即可:$.getJSON(baseUrl + "getrecommendation?genre="+rowName+"&size="+size+"&sortby=popularity", function(result)
    作者回复

    2021-04-30 04:54:55

  • 朱月俊

    2020-10-07 22:36:48

    先说一下每一种类型的电影是如何排名的:
    默认是按照打分平均分数以及发布时间排名,在recsys.js中的addGenereRow处指定排名的方式。
    如何新增排名算法,比如增加热度这个指标?
    需要在DataManager中照葫芦画瓢增加ratingNumber,然后在js中指定一下即可。

    还在研究的问题:首页是如何调用getrecommendation接口以及如何传入参数的。麻烦老师指教一下。
    作者回复

    关注一下addGenereRow方法中的sortby参数
    $.getJSON(baseUrl + "getrecommendation?genre="+rowName+"&size="+size+"&sortby=rating"

    2020-10-11 15:00:13

  • Kepler

    2021-02-03 12:16:38

    问题:如果修改js及对应的RecommendationService后,主页仍未显示排序效果
    解决:
    方式1. 拉新github(推荐,避免后续有什么其他问题)
    方式2. 修改index.html的<script src="./js/recsys.js"></script>,原加载js文件为recsys.js?v=1.19
    作者回复

    非常好 改js版本可是避免很多缓存问题

    2021-02-03 22:07:13

  • ALAN

    2020-10-05 16:28:26

    问题一:按电影的平均打分从高到低排序
    问题二:修改DataManager.java中221行代码。将compara函数中参数getAverageRating函数改成getRatingNumber函数
    作者回复

    是的,如果需要看到效果的话,还需要修改一些recsys.js中相关的js代码

    2020-10-11 15:02:01

  • 大钰儿

    2020-10-13 00:06:54

    今天拉的主干代码,默认用了redis载入embedding导致无法启动,是不是需要改一下😅
    作者回复

    good point,已经改回了默认从file load数据

    2020-10-14 08:07:04

  • 金鹏

    2020-10-02 22:17:26

    问题一:
    首页每行(一个类别)按电影的AverageRating平均打分从高到低做为排序依据;

    问题二:
    public List<Movie> getMoviesByGenre(String genre, int size, String sortBy){
    if (null != genre){
    List<Movie> movies = new ArrayList<>(this.genreReverseIndexMap.get(genre));
    switch (sortBy){
    case "rating":movies.sort((m1, m2) -> Double.compare(m2.getAverageRating(), m1.getAverageRating()));break;
    case "releaseYear": movies.sort((m1, m2) -> Integer.compare(m2.getReleaseYear(), m1.getReleaseYear()));break;
    case "popularity":movies.sort((m1, m2) -> Integer.compare(m2.getRatingNumber(), m1.getRatingNumber()));break;
    default:
    }
    ........
    作者回复

    赞。

    要真正更改排序的方法,还需要修改一下前端js的一些条件。

    2020-10-03 06:48:42

  • VICTOR

    2021-11-29 10:36:28

    针对修改完后前端没有现实的原因,可能是因为js缓存的原因,尝试Win: Ctrl+Shift+R / Mac OS: Cmd+Shft+R 强制刷新缓存进行刷新
  • 闫阿佳需要学习

    2021-10-04 08:23:56

    修改index.html的<script src="./js/recsys.js"></script> 没有起作用,最后还是清楚缓存重新加载后显示的
    步骤:(chrome)F12->勾选" Disable cache" -> 刷新
  • 2021-01-06 13:00:22

    课后选择题习题第二题:感觉选项D其实也是深度学习带来的重要变革。
    推荐系统是连接人与物的,那么如何表示和编码人与物就是非常重要的,毕竟只有更好的认知,才能带来更好的连接,深度学习带来的表示学习我觉的能算是重要变革吧?虽然非深度学习时代的矩阵分解等得到的latent vector也算是embedding吧,但和如今万物皆可embedding,应该算是个重要变革?
    作者回复

    这样理解也没有错。原题选项D是
    “推荐系统可利用的特征发生了根本性的变化”,我的本意是推荐系统可利用的特征原数据其实没有变化,只是处理特征的方式发生了根本性的改变。

    只是一道选择题,大家理解知识就好,不用解决于说法。

    2021-01-07 02:10:30

  • yangchao

    2022-02-23 21:47:57

    思考题
    1.首页中每行内部的电影都是按照rating即评分进行排序的

    2.首先修改DataManager类下的getMoviesByGenre:
    case "popularity": movies.sort((m1, m2) -> Integer.compare(m2.getRatingNumber(), m1.getRatingNumber()));break;

    然后在recsys.js里新增方法:
    function addGenreRowByPopularitySort(pageId, rowName, rowId, size, baseUrl) {
    addRowFrame(pageId, rowName, rowId, baseUrl);
    $.getJSON(baseUrl + "getrecommendation?genre="+rowName+"&size="+size+"&sortby=popularity", function(result){
    $.each(result, function(i, movie){
    appendMovie2Row(rowId, movie.title, movie.movieId, movie.releaseYear, movie.averageRating.toPrecision(2), movie.ratingNumber, movie.genres,baseUrl);
    });
    });
    };

    最后在index.html里 将所有 addGenreRow替换为addGenreRowByPopularitySort

    最后重新编译重启go即可
  • yangchao

    2022-02-23 18:20:28

    考试结果:
    https://time.geekbang.org/quiz/?act_id=216&exam_id=666&source=1009560
  • Geek_0ea2ff

    2022-01-24 08:11:22

    第二题,修改成按Popularity排序,跑出来的结果不对,同类型电影没有按ratingNumber降序展示。
  • 土豆是天使

    2021-11-13 16:37:46

    老师,按照别的同学说的改了代码,也按照不能显示的方法试了,排序结果还是和之前一样
  • Geek_8a732a

    2021-08-05 16:33:26

    1、按照电影平均历史评分进行排序

    2、RecSysServer.java的68行找到RecommendationService(),进入后找到35行getMoviesByGenre,再进入后,在switch里新增 case "popularity": movies.sort((m1,m2) -> Integer.compare(m2.getRatingNumber(),m1.getRatingNumber()));break;

    3、回到RecommendationService.java中找到
    //ranking algorithm
    String sortby = request.getParameter("sortby");
    选中sortby,右键find in files,
    找到
    $.getJSON(baseUrl + "getrecommendation?genre="+rowName+"&size="+size+"&sortby=rating", function(result)
    将其中的sortby=rating,改成sortby=popularity

    4、为看显示效果,参考了Kelper的“ 修改index.html的<script src="./js/recsys.js"></script>,原加载js文件为recsys.js?v=1.19”,然后重新run RecSysServer.java就可以了
  • me_hu

    2021-08-02 18:36:54

    1. 按照电影评分排序
    2. a. 修改recsys.js, sortby=rating 改为 sortby=popularity
    b. DataManager.getMoviesByGenre方法增加 case popularity, 按照 ratingNumber排序
  • 82

    2021-07-13 14:53:05

    还有跟中代码的main启动方法 没看到,深度学习的引擎起起来啊?这块代码在哪里起的?
  • 82

    2021-07-13 11:00:24

    public static double calculateSimilarScore(Movie movie, Movie candidate){
    int sameGenreCount = 0;
    for (String genre : movie.getGenres()){
    if (candidate.getGenres().contains(genre)){
    sameGenreCount++;
    }
    }
    double genreSimilarity = (double)sameGenreCount / (movie.getGenres().size() + candidate.getGenres().size()) / 2;
    double ratingScore = candidate.getAverageRating() / 5;

    double similarityWeight = 0.7;
    double ratingScoreWeight = 0.3;

    return genreSimilarity * similarityWeight + ratingScore * ratingScoreWeight;
    }

    上面这个是干嘛的啊?
  • 老叔叔安森

    2021-05-31 08:29:06

    1、默认是按照每个类别的影片的历史平均评分,在类别内排序。
    2、在DataManager类的GetMovieByGenre中增加多一个判断:case "popularity":movies.sort((m1, m2) -> Integer.compare(m2.getRatingNumber(), m1.getRatingNumber()));break;
    并修改index.html源码中js的sortby传参为popularity