这是一个b站使用推荐引擎推荐的案例:
0点赞1收藏2转发
1 <select id="getAllUserPreference" resultType="com.imooc.bilibili.domain.UserPreference">
2 select
3 userId,
4 videoId,
5 sum(case operationType
6 when '0' then 6
7 when '1' then 2
8 when '2' then 2
9 else 0 end
10 ) as `value`
11 from
12 t_video_operation
13 group by userId, videoId
14 </select>
15 public class UserPreference {
16
17 private Long id;
18
19 private Long userId;
20
21 private Long videoId;
22
23 private Float value;
24
25 private Date createTime;
26
27 public Long getId() {
28 return id;
29 }
30
31 public void setId(Long id) {
32 this.id = id;
33 }
34
35 public Long getUserId() {
36 return userId;
37 }
38
39 public void setUserId(Long userId) {
40 this.userId = userId;
41 }
42
43 public Long getVideoId() {
44 return videoId;
45 }
46
47 public void setVideoId(Long videoId) {
48 this.videoId = videoId;
49 }
50
51 public Float getValue() {
52 return value;
53 }
54
55 public void setValue(Float value) {
56 this.value = value;
57 }
58
59 public Date getCreateTime() {
60 return createTime;
61 }
62
63 public void setCreateTime(Date createTime) {
64 this.createTime = createTime;
65 }
66 }
67
68 /**
69 * 基于用户的协同推荐
70 * @param userId 用户id
71 */
72 public List<Video> recommend(Long userId) throws TasteException {
73 List<UserPreference> list = videoDao.getAllUserPreference();
74 //创建数据模型
75 DataModel dataModel = this.createDataModel(list);
76 //获取用户相似程度
77 UserSimilarity similarity = new UncenteredCosineSimilarity(dataModel);
78 System.out.println(similarity.userSimilarity(11, 12));
79 //获取用户邻居
80 UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(2, similarity, dataModel);
81 long[] ar = userNeighborhood.getUserNeighborhood(userId);
82 //构建推荐器
83 Recommender recommender = new GenericUserBasedRecommender(dataModel, userNeighborhood, similarity);
84 //推荐视频
85 List<RecommendedItem> recommendedItems = recommender.recommend(userId, 5);
86 List<Long> itemIds = recommendedItems.stream().map(RecommendedItem::getItemID).collect(Collectors.toList());
87 return videoDao.batchGetVideosByIds(itemIds);
88 }
89
90
91 /**
92 * 基于内容的协同推荐
93 * @param userId 用户id
94 * @param itemId 参考内容id(根据该内容进行相似内容推荐)
95 * @param howMany 需要推荐的数量
96 */
97 public List<Video> recommendByItem(Long userId, Long itemId, int howMany) throws TasteException {
98 List<UserPreference> list = videoDao.getAllUserPreference();
99 //创建数据模型
100 DataModel dataModel = this.createDataModel(list);
101 //获取内容相似程度
102 ItemSimilarity similarity = new UncenteredCosineSimilarity(dataModel);
103 GenericItemBasedRecommender genericItemBasedRecommender = new GenericItemBasedRecommender(dataModel, similarity);
104 // 物品推荐相拟度,计算两个物品同时出现的次数,次数越多任务的相拟度越高
105 List<Long> itemIds = genericItemBasedRecommender.recommendedBecause(userId, itemId, howMany)
106 .stream()
107 .map(RecommendedItem::getItemID)
108 .collect(Collectors.toList());
109 //推荐视频
110 return videoDao.batchGetVideosByIds(itemIds);
111 }
112
113 private DataModel createDataModel(List<UserPreference> userPreferenceList) {
114 FastByIDMap<PreferenceArray> fastByIdMap = new FastByIDMap<>();
115 Map<Long, List<UserPreference>> map = userPreferenceList.stream().collect(Collectors.groupingBy(UserPreference::getUserId));
116 Collection<List<UserPreference>> list = map.values();
117 for(List<UserPreference> userPreferences : list){
118 GenericPreference[] array = new GenericPreference[userPreferences.size()];
119 for(int i = 0; i < userPreferences.size(); i++){
120 UserPreference userPreference = userPreferences.get(i);
121 GenericPreference item = new GenericPreference(userPreference.getUserId(), userPreference.getVideoId(), userPreference.getValue());
122 array[i] = item;
123 }
124 fastByIdMap.put(array[0].getUserID(), new GenericUserPreferenceArray(Arrays.asList(array)));
125 }
126 return new GenericDataModel(fastByIdMap);
127 }