在Coursera上学Java编程基础,有个根据每部电影评分及个人喜好,推荐相应电影功能。作为小白,充分感觉到了代码架构的重要性。
准备工作
需要有三个基本类:Movie,Rater, Rating
- Movie:每部电影的信息。包含id, title, year, genres, director, country, poster, minutes实例变量。
- 有两种信息量不同的constructor。
- 每个变量都有自己的get方法。
- 重写
toString()
方法(每个类都重写toString()是个不错选择,有助于了解这个类)。
- Rater:评价人的信息。包含myID, myRating(ArrayList<Rating> )实例变量,每个人对不同电影的评价都放在了一个动态数组中。
- constructor使用myID作为参数。
- addRating(String item, double rating),把新的评分放到myRating中
- hasRating(String item)
- getID(),获取rater的id
- getRating(String item)
- numRatings(),返回该rater的评价数量
- Rating:一部电影的评价。评价需要比较,所以实现Comparable,之前讲到过这个点
- 包含item(电影id),value(电影评分)
- getItem()
- getValue()
- toString()
- compareTo()
第一个操作类(姑且这么叫吧)
上面三个类描述了电影和评价的基本信息。此时第一个操作类FirstRating派上了用场。FirstRating 中,movieLoader() 和 raterLoader() 两个方法是必不可少的。将两者从CSV或其他文件读取,并储存在ArrayList<Movie> 和 ArrayList<Rater> 中, 方便使用。这个类中,可以写一些方法测试,或实现简单功能,比如在Movie中查找所有的导演及其所有电影。给定一个movieId,找出多少rater。
第二个操作类
第二个操作类SecondRating实现更多功能。
因为有了第一个操作类,加载数据直接新建一个对象,然后调用里面的movieLoader() 和 raterLoader()方法即可获得数据。为方便操作,设置动态数组实例变量myRater 和myMoive放置数据。
- 如何获取一部电影的平均评分,要求评论人数至少达到
int minimalRater
才有效。 - 获取所有电影的平均分。可用ArrayList<Rating>
- 给定电影id,获取电影名
- 给定电影名,获取id
constructor有两个表示文件名的形参,可以指定文件名。默认给的话,可以用无行参的方式
this("defaultNameOne", "defaultNameTwo")
第三个操作类
有几个变化
- 这个类添加了Filter接口。
- 为了提高效率,单独用HashMap做了Movie 的数据库。里面都是静态方法和变量,无需new就可直接使用。
- 为提高Rater 效率,使用了EfficientRater。里面实例变量有
String raterID
,HashMap<String movieID, Rating rating>
。设置了Rater接口,将原来的Rater放在PlainRater中。
第四个操作类
推荐系统核心点在于如何判断一个人的喜好,并给出相应的推荐。分两步走
- 创建用户画像。用户对一系列电影进行评分后,创建一个EfficientRater,里面有他对一系列电影的评分。
- 寻找相似Rater。把该用户与数据库中所有rater比较相似性,使用一个ArrayList<Rating>, 每个Rating记录一个被比较的rater及其相似性。相似性计算规则:对该rater和每个rater共有的评分各减5(满分10),相乘累加。(该Rater评价电影A10分,电影B9分;另一个Rater评价电影B6分,电影C7分。则相似分=(9-5) *(6-5)=4。根据相似分对相似rater从高到低排列,选取得分最高用户的一部分。
- 生成推荐电影。对数据库中每部电影重新评分。如果这部电影在相似rater的Rating中,将所有相似用户中有这部电影的评分*相似度后累加。对所有电影重新评分后排序即可。