MapRedcue的demo(协同过滤)
MapRedcue的演示(协同过滤)
做一个关于电影推荐。你于你好友之间的浏览电影以及电影评分的推荐的协同过滤。
百度百科:
协同过滤简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人通过合作的机制给予信息相当程度的回应(如评分)并记录下来以达到过滤的目的进而帮助别人筛选信息,回应不一定局限于特别感兴趣的,特别不感兴趣信息的纪录也相当重要。
元数据:
1 盗梦空间 4.0
1 碟中谍 1.5
1 禁闭岛 4.0
2 王的盛宴 2.5
2 盗梦空间 5.0
2 肖申克的救赎 3.0
2 禁闭岛 2.5
3 教父 3.5
3 盗梦空间 5.0
3 007 4.5
3 星球大战 5.0
3 华尔街之狼 2.5
3 禁闭岛 1.5
3 碟中谍 2.0
4 碟中谍 2.5
4 禁闭岛 1.5
4 007 2.0
5 沉默的羔羊 4.5
5 肖申克的救赎 5.0
5 碟中谍 3.0
6 沉默的羔羊 5.0
6 碟中谍 4.0
6 王的盛宴 4.0
7 王的盛宴 5.0
7 碟中谍 1.5
7 肖申克的救赎 3.5
7 华尔街之狼 2.5
8 禁闭岛 3.0
8 盗梦空间 4.0
8 教父 2.5
8 星球大战 3.5
8 肖申克的救赎 3.0
8 王的盛宴 3.0
8 华尔街之狼 2.0
9 沉默的羔羊 5.0
9 禁闭岛 4.0
9 教父 5.0
9 盗梦空间 4.5
9 星球大战 4.0
9 王的盛宴 1.5
9 华尔街之狼 3.0
10 盗梦空间 3.5
10 沉默的羔羊 5.0
10 禁闭岛 2.5
10 肖申克的救赎 2.0
10 王的盛宴 4.0
10 教父 2.0
10 碟中谍 1.5
11 禁闭岛 3.0
11 碟中谍 2.5
11 盗梦空间 3.0
11 肖申克的救赎 3.0
12 华尔街之狼 3.0
12 星球大战 3.5
12 碟中谍 1.5
13 教父 3.5
13 肖申克的救赎 2.5
13 华尔街之狼 5.0
13 星球大战 5.0
13 沉默的羔羊 1.5
13 盗梦空间 3.0
13 禁闭岛 3.0
14 007 4.0
14 星球大战 2.5
14 华尔街之狼 1.5
14 教父 4.5
14 盗梦空间 3.0
14 沉默的羔羊 3.5
15 沉默的羔羊 4.0
15 华尔街之狼 2.5
15 肖申克的救赎 5.0
16 肖申克的救赎 2.0
16 007 5.0
16 盗梦空间 3.5
17 星球大战 4.5
17 禁闭岛 1.5
17 007 4.5
18 007 4.5
18 华尔街之狼 5.0
18 沉默的羔羊 1.5
18 盗梦空间 2.0
19 星球大战 4.5
19 华尔街之狼 3.0
19 肖申克的救赎 5.0
19 007 2.0
19 王的盛宴 4.0
19 碟中谍 2.5
19 沉默的羔羊 3.0
20 007 2.0
20 教父 4.0
20 星球大战 2.5
20 盗梦空间 4.5
20 华尔街之狼 3.0
20 碟中谍 4.5
20 肖申克的救赎 3.0
20 禁闭岛 2.0
21 王的盛宴 2.0
21 碟中谍 2.5
21 禁闭岛 2.5
21 盗梦空间 1.5
21 肖申克的救赎 4.5
22 沉默的羔羊 2.0
22 教父 4.0
22 肖申克的救赎 3.5
22 王的盛宴 1.5
22 禁闭岛 1.5
23 盗梦空间 3.5
23 华尔街之狼 4.0
23 007 2.0
23 肖申克的救赎 4.5
24 007 4.0
24 华尔街之狼 5.0
24 教父 1.5
24 禁闭岛 1.5
25 王的盛宴 3.0
25 星球大战 2.0
25 沉默的羔羊 5.0
25 禁闭岛 2.0
26 007 2.0
26 肖申克的救赎 3.5
26 星球大战 4.5
26 教父 4.5
27 沉默的羔羊 5.0
27 禁闭岛 1.5
27 肖申克的救赎 5.0
28 007 5.0
28 星球大战 5.0
28 盗梦空间 3.0
28 王的盛宴 4.0
28 沉默的羔羊 2.0
28 教父 2.5
28 华尔街之狼 5.0
28 肖申克的救赎 4.0
29 肖申克的救赎 3.0
29 盗梦空间 3.0
29 星球大战 3.5
29 王的盛宴 5.0
29 碟中谍 3.5
29 禁闭岛 1.5
30 沉默的羔羊 4.5
30 星球大战 1.5
30 教父 1.5
31 盗梦空间 3.0
31 肖申克的救赎 4.0
31 王的盛宴 3.0
32 碟中谍 2.0
32 禁闭岛 2.5
32 盗梦空间 3.0
33 禁闭岛 5.0
33 教父 3.0
33 肖申克的救赎 4.5
33 华尔街之狼 4.5
33 盗梦空间 4.0
34 星球大战 2.0
34 沉默的羔羊 3.0
34 007 5.0
34 禁闭岛 2.0
35 华尔街之狼 4.5
35 007 1.5
35 盗梦空间 3.5
35 星球大战 1.5
35 教父 2.5
36 碟中谍 2.0
36 肖申克的救赎 4.0
36 教父 1.5
36 王的盛宴 5.0
37 肖申克的救赎 2.0
37 沉默的羔羊 4.0
37 王的盛宴 2.5
37 盗梦空间 5.0
37 教父 2.5
38 华尔街之狼 1.5
38 星球大战 4.0
38 王的盛宴 3.0
39 007 3.5
39 教父 2.0
39 盗梦空间 3.5
39 王的盛宴 3.5
40 华尔街之狼 3.0
40 沉默的羔羊 4.5
40 盗梦空间 5.0
40 007 2.5
40 碟中谍 3.5
40 星球大战 1.5
40 教父 3.0
40 王的盛宴 2.0
41 教父 2.5
41 禁闭岛 4.5
41 007 1.5
41 沉默的羔羊 1.5
41 肖申克的救赎 2.0
41 盗梦空间 3.0
41 星球大战 4.0
42 华尔街之狼 1.5
42 王的盛宴 1.5
42 教父 4.0
43 华尔街之狼 3.5
43 教父 5.0
43 碟中谍 4.5
44 沉默的羔羊 5.0
44 教父 4.5
44 肖申克的救赎 4.0
44 盗梦空间 2.5
44 碟中谍 4.5
44 星球大战 1.5
44 王的盛宴 5.0
45 华尔街之狼 3.0
45 王的盛宴 4.5
45 禁闭岛 2.0
46 王的盛宴 2.5
46 盗梦空间 4.0
46 星球大战 4.5
46 007 2.0
46 教父 1.5
47 教父 2.5
47 华尔街之狼 3.0
47 007 5.0
47 碟中谍 1.5
47 禁闭岛 4.0
48 星球大战 5.0
48 教父 4.5
48 盗梦空间 2.5
49 沉默的羔羊 4.0
49 肖申克的救赎 5.0
49 王的盛宴 2.5
49 星球大战 1.5
49 碟中谍 2.0
49 华尔街之狼 4.5
49 盗梦空间 4.5
50 盗梦空间 2.0
50 禁闭岛 1.5
50 沉默的羔羊 2.0
思路:
step1:过滤得到每个用户看过的所有电影
输出:key:用户1 value:{ 1 盗梦空间:4.0,碟中谍:1.5,禁闭岛:4.0}
1 盗梦空间:4.0,碟中谍:1.5,禁闭岛:4.0
2 王的盛宴:2.5,盗梦空间:5.0,肖申克的救赎:3.0,禁闭岛:2.5
3 碟中谍:2.0,教父:3.5,盗梦空间:5.0,007:4.5,星球大战:5.0,华尔街之狼:2.5,禁闭岛:1.5
4 碟中谍:2.5,禁闭岛:1.5,007:2.0
5 沉默的羔羊:4.5,肖申克的救赎:5.0,碟中谍:3.0
6 沉默的羔羊:5.0,碟中谍:4.0,王的盛宴:4.0
7 王的盛宴:5.0,碟中谍:1.5,肖申克的救赎:3.5,华尔街之狼:2.5
8 禁闭岛:3.0,盗梦空间:4.0,教父:2.5,星球大战:3.5,肖申克的救赎:3.0,王的盛宴:3.0,华尔街之狼:2.0
9 禁闭岛:4.0,教父:5.0,盗梦空间:4.5,沉默的羔羊:5.0,星球大战:4.0,王的盛宴:1.5,华尔街之狼:3.0
10 肖申克的救赎:2.0,盗梦空间:3.5,沉默的羔羊:5.0,禁闭岛:2.5,王的盛宴:4.0,教父:2.0,碟中谍:1.5
11 禁闭岛:3.0,碟中谍:2.5,盗梦空间:3.0,肖申克的救赎:3.0
12 华尔街之狼:3.0,星球大战:3.5,碟中谍:1.5
13 华尔街之狼:5.0,教父:3.5,肖申克的救赎:2.5,星球大战:5.0,沉默的羔羊:1.5,盗梦空间:3.0,禁闭岛:3.0
14 星球大战:2.5,007:4.0,华尔街之狼:1.5,教父:4.5,盗梦空间:3.0,沉默的羔羊:3.5
15 沉默的羔羊:4.0,华尔街之狼:2.5,肖申克的救赎:5.0
16 肖申克的救赎:2.0,007:5.0,盗梦空间:3.5
17 禁闭岛:1.5,星球大战:4.5,007:4.5
18 007:4.5,华尔街之狼:5.0,沉默的羔羊:1.5,盗梦空间:2.0
19 星球大战:4.5,华尔街之狼:3.0,肖申克的救赎:5.0,007:2.0,王的盛宴:4.0,碟中谍:2.5,沉默的羔羊:3.0
20 007:2.0,教父:4.0,星球大战:2.5,盗梦空间:4.5,华尔街之狼:3.0,碟中谍:4.5,肖申克的救赎:3.0,禁闭岛:2.0
21 碟中谍:2.5,禁闭岛:2.5,盗梦空间:1.5,肖申克的救赎:4.5,王的盛宴:2.0
22 禁闭岛:1.5,沉默的羔羊:2.0,教父:4.0,肖申克的救赎:3.5,王的盛宴:1.5
23 盗梦空间:3.5,华尔街之狼:4.0,007:2.0,肖申克的救赎:4.5
24 007:4.0,华尔街之狼:5.0,教父:1.5,禁闭岛:1.5
25 星球大战:2.0,禁闭岛:2.0,沉默的羔羊:5.0,王的盛宴:3.0
26 肖申克的救赎:3.5,星球大战:4.5,教父:4.5,007:2.0
27 沉默的羔羊:5.0,禁闭岛:1.5,肖申克的救赎:5.0
28 华尔街之狼:5.0,007:5.0,星球大战:5.0,盗梦空间:3.0,王的盛宴:4.0,沉默的羔羊:2.0,教父:2.5,肖申克的救赎:4.0
29 肖申克的救赎:3.0,盗梦空间:3.0,星球大战:3.5,王的盛宴:5.0,碟中谍:3.5,禁闭岛:1.5
30 沉默的羔羊:4.5,星球大战:1.5,教父:1.5
31 盗梦空间:3.0,肖申克的救赎:4.0,王的盛宴:3.0
32 禁闭岛:2.5,碟中谍:2.0,盗梦空间:3.0
33 教父:3.0,肖申克的救赎:4.5,华尔街之狼:4.5,盗梦空间:4.0,禁闭岛:5.0
34 星球大战:2.0,沉默的羔羊:3.0,007:5.0,禁闭岛:2.0
35 教父:2.5,华尔街之狼:4.5,007:1.5,盗梦空间:3.5,星球大战:1.5
36 碟中谍:2.0,肖申克的救赎:4.0,教父:1.5,王的盛宴:5.0
37 肖申克的救赎:2.0,沉默的羔羊:4.0,王的盛宴:2.5,盗梦空间:5.0,教父:2.5
38 华尔街之狼:1.5,星球大战:4.0,王的盛宴:3.0
39 教父:2.0,007:3.5,盗梦空间:3.5,王的盛宴:3.5
40 盗梦空间:5.0,007:2.5,沉默的羔羊:4.5,碟中谍:3.5,星球大战:1.5,教父:3.0,华尔街之狼:3.0,王的盛宴:2.0
41 007:1.5,教父:2.5,禁闭岛:4.5,沉默的羔羊:1.5,肖申克的救赎:2.0,盗梦空间:3.0,星球大战:4.0
42 华尔街之狼:1.5,王的盛宴:1.5,教父:4.0
43 华尔街之狼:3.5,教父:5.0,碟中谍:4.5
44 王的盛宴:5.0,沉默的羔羊:5.0,教父:4.5,肖申克的救赎:4.0,盗梦空间:2.5,碟中谍:4.5,星球大战:1.5
45 华尔街之狼:3.0,禁闭岛:2.0,王的盛宴:4.5
46 007:2.0,王的盛宴:2.5,盗梦空间:4.0,星球大战:4.5,教父:1.5
47 教父:2.5,华尔街之狼:3.0,007:5.0,碟中谍:1.5,禁闭岛:4.0
48 星球大战:5.0,教父:4.5,盗梦空间:2.5
49 沉默的羔羊:4.0,肖申克的救赎:5.0,王的盛宴:2.5,星球大战:1.5,碟中谍:2.0,华尔街之狼:4.5,盗梦空间:4.5
50 盗梦空间:2.0,禁闭岛:1.5,沉默的羔羊:2.0
step2: 根据 step-out 通过所有用户看过的电影矩阵
输出:007:007 19(电影出现的次数)
007:007 19
007:华尔街之狼 11
007:教父 12
007:星球大战 12
007:沉默的羔羊 7
007:王的盛宴 5
007:盗梦空间 12
007:碟中谍 6
007:禁闭岛 8
007:肖申克的救赎 7
华尔街之狼:007 11
华尔街之狼:华尔街之狼 23
华尔街之狼:教父 14
华尔街之狼:星球大战 13
华尔街之狼:沉默的羔羊 9
华尔街之狼:王的盛宴 10
华尔街之狼:盗梦空间 13
华尔街之狼:碟中谍 9
华尔街之狼:禁闭岛 9
华尔街之狼:肖申克的救赎 10
教父:007 12
教父:华尔街之狼 14
教父:教父 25
教父:星球大战 15
教父:沉默的羔羊 11
教父:王的盛宴 12
教父:盗梦空间 17
教父:碟中谍 8
教父:禁闭岛 11
教父:肖申克的救赎 12
星球大战:007 12
星球大战:华尔街之狼 13
星球大战:教父 15
星球大战:星球大战 23
星球大战:沉默的羔羊 12
星球大战:王的盛宴 11
星球大战:盗梦空间 15
星球大战:碟中谍 8
星球大战:禁闭岛 10
星球大战:肖申克的救赎 10
沉默的羔羊:007 7
沉默的羔羊:华尔街之狼 9
沉默的羔羊:教父 11
沉默的羔羊:星球大战 12
沉默的羔羊:沉默的羔羊 21
沉默的羔羊:王的盛宴 11
沉默的羔羊:盗梦空间 12
沉默的羔羊:碟中谍 7
沉默的羔羊:禁闭岛 9
沉默的羔羊:肖申克的救赎 12
王的盛宴:007 5
王的盛宴:华尔街之狼 10
王的盛宴:教父 12
王的盛宴:星球大战 11
王的盛宴:沉默的羔羊 11
王的盛宴:王的盛宴 23
王的盛宴:盗梦空间 14
王的盛宴:碟中谍 10
王的盛宴:禁闭岛 9
王的盛宴:肖申克的救赎 14
盗梦空间:007 12
盗梦空间:华尔街之狼 13
盗梦空间:教父 17
盗梦空间:星球大战 15
盗梦空间:沉默的羔羊 12
盗梦空间:王的盛宴 14
盗梦空间:盗梦空间 29
盗梦空间:碟中谍 11
盗梦空间:禁闭岛 15
盗梦空间:肖申克的救赎 17
碟中谍:007 6
碟中谍:华尔街之狼 9
碟中谍:教父 8
碟中谍:星球大战 8
碟中谍:沉默的羔羊 7
碟中谍:王的盛宴 10
碟中谍:盗梦空间 11
碟中谍:碟中谍 20
碟中谍:禁闭岛 10
碟中谍:肖申克的救赎 11
禁闭岛:007 8
禁闭岛:华尔街之狼 9
禁闭岛:教父 11
禁闭岛:星球大战 10
禁闭岛:沉默的羔羊 9
禁闭岛:王的盛宴 9
禁闭岛:盗梦空间 15
禁闭岛:碟中谍 10
禁闭岛:禁闭岛 24
禁闭岛:肖申克的救赎 12
肖申克的救赎:007 7
肖申克的救赎:华尔街之狼 10
肖申克的救赎:教父 12
肖申克的救赎:星球大战 10
肖申克的救赎:沉默的羔羊 12
肖申克的救赎:王的盛宴 14
肖申克的救赎:盗梦空间 17
肖申克的救赎:碟中谍 11
肖申克的救赎:禁闭岛 12
肖申克的救赎:肖申克的救赎 25
step3: 根据 step-out 用户评分矩阵
输出: 007 用户40:2.5
007 40:2.5
007 41:1.5
007 35:1.5
007 46:2.0
007 17:4.5
007 4:2.0
007 23:2.0
007 28:5.0
007 47:5.0
007 16:5.0
007 19:2.0
007 14:4.0
007 18:4.5
007 39:3.5
007 24:4.0
007 3:4.5
007 26:2.0
007 20:2.0
007 34:5.0
华尔街之狼 38:1.5
华尔街之狼 7:2.5
华尔街之狼 47:3.0
华尔街之狼 40:3.0
华尔街之狼 15:2.5
华尔街之狼 23:4.0
华尔街之狼 19:3.0
华尔街之狼 24:5.0
华尔街之狼 18:5.0
华尔街之狼 49:4.5
华尔街之狼 13:5.0
华尔街之狼 28:5.0
华尔街之狼 45:3.0
华尔街之狼 12:3.0
华尔街之狼 3:2.5
华尔街之狼 9:3.0
华尔街之狼 33:4.5 .。。。。。
step4: 根据step3-out和step4-out 计算推荐结果列表(计算电影的评分,根据电影出现的数据*用户对应得评分)
输入:007:007 19/007 40:2.5
输出:19 华尔街之狼,22.0
34 教父,60.0
23 教父,24.0
24 教父,48.0
35 教父,18.0
46 教父,24.0
47 教父,60.0
14 教父,48.0
26 教父,24.0
16 教父,60.0
39 教父,42.0
17 教父,54.0
28 教父,60.0
18 教父,54.0
19 教父,24.0
3 教父,54.0
4 教父,24.0
40 教父,30.0
41 教父,18.0
20 教父,24.0
34 碟中谍,30.0
23 碟中谍,12.0
24 碟中谍,24.0
35 碟中谍,9.0
46 碟中谍,12.0
47 碟中谍,30.0
14 碟中谍,24.0
26 碟中谍,12.0
16 碟中谍,30.0
39 碟中谍,21.0
17 碟中谍,27.0
28 碟中谍,30.0
18 碟中谍,27.0
19 碟中谍,12.0
3 碟中谍,27.0
4 碟中谍,12.0
40 碟中谍,15.0
41 碟中谍,9.0
20 碟中谍,12.0
34 王的盛宴,25.0
23 王的盛宴,10.0
24 王的盛宴,20.0
.....
step5: 根据step-out4 合并所有数据
输出:19 华尔街之狼,289.0
1 碟中谍,114.0
1 教父,124.0
1 肖申克的救赎,132.5
1 王的盛宴,107.0
1 盗梦空间,192.5
1 禁闭岛,171.0
1 007,89.0
1 华尔街之狼,101.5
1 沉默的羔羊,94.5
1 星球大战,112.0
2 碟中谍,138.0
2 教父,178.5
2 王的盛宴,192.0
2 肖申克的救赎,225.0
2 盗梦空间,268.5
2 禁闭岛,193.5
2 007,113.5
2 华尔街之狼,142.5
2 沉默的羔羊,146.0
2 星球大战,157.5
3 教父,369.0
3 碟中谍,227.5
3 王的盛宴,248.0
3 肖申克的救赎,273.5
3 盗梦空间,410.5
3 禁闭岛,278.0
3 007,299.0
3 华尔街之狼,317.5
3 沉默的羔羊,240.0
3 星球大战,360.0
4 教父,60.5
4 碟中谍,77.0
4 王的盛宴,48.5
4 肖申克的救赎,59.5
4 盗梦空间,74.0
.....
step6: 根据step5-out 排除用户看过得电影,然后把类似得,评分高得优先推荐(排序)。
输出: 1 肖申克的救赎 132.5 1 教父 124.0 1 星球大战 112.0 1 王的盛宴 107.0 1 华尔街之狼 101.5
Movie [userid=1, movieName=肖申克的救赎, score=132.5]
Movie [userid=1, movieName=教父, score=124.0]
Movie [userid=1, movieName=星球大战, score=112.0]
Movie [userid=1, movieName=王的盛宴, score=107.0]
Movie [userid=1, movieName=华尔街之狼, score=101.5]
Movie [userid=1, movieName=沉默的羔羊, score=94.5]
Movie [userid=1, movieName=007, score=89.0]
Movie [userid=2, movieName=教父, score=178.5]
Movie [userid=2, movieName=星球大战, score=157.5]
Movie [userid=2, movieName=沉默的羔羊, score=146.0]
Movie [userid=2, movieName=华尔街之狼, score=142.5]
Movie [userid=2, movieName=碟中谍, score=138.0]
Movie [userid=2, movieName=007, score=113.5]
Movie [userid=3, movieName=肖申克的救赎, score=273.5]
Movie [userid=3, movieName=王的盛宴, score=248.0]
Movie [userid=3, movieName=沉默的羔羊, score=240.0]
Movie [userid=4, movieName=盗梦空间, score=74.0]
Movie [userid=4, movieName=教父, score=60.5]
Movie [userid=4, movieName=星球大战, score=59.0]
Movie [userid=4, movieName=华尔街之狼, score=58.0]
Movie [userid=4, movieName=王的盛宴, score=48.5]
Movie [userid=4, movieName=沉默的羔羊, score=45.0]
Movie [userid=5, movieName=盗梦空间, score=172.0]
Movie [userid=5, movieName=王的盛宴, score=149.5]
Movie [userid=5, movieName=教父, score=133.5]
Movie [userid=5, movieName=禁闭岛, score=130.5]
Movie [userid=5, movieName=星球大战, score=128.0]
Movie [userid=5, movieName=华尔街之狼, score=117.5]
Movie [userid=5, movieName=007, score=84.5]
Movie [userid=6, movieName=盗梦空间, score=160.0]
Movie [userid=6, movieName=肖申克的救赎, score=160.0]
Movie [userid=6, movieName=星球大战, score=136.0]
Movie [userid=6, movieName=教父, score=135.0]
Movie [userid=6, movieName=华尔街之狼, score=121.0]
Movie [userid=6, movieName=禁闭岛, score=121.0]
Movie [userid=6, movieName=007, score=79.0]
Movie [userid=7, movieName=盗梦空间, score=178.5]
Movie [userid=7, movieName=教父, score=149.0]
Movie [userid=7, movieName=星球大战, score=134.5]
Movie [userid=7, movieName=沉默的羔羊, score=130.0]
Movie [userid=7, movieName=禁闭岛, score=124.5]
Movie [userid=7, movieName=007, score=86.0]
Movie [userid=8, movieName=沉默的羔羊, score=231.5]
Movie [userid=8, movieName=碟中谍, score=203.0]
Movie [userid=8, movieName=007, score=202.0]
Movie [userid=9, movieName=肖申克的救赎, score=335.5]
Movie [userid=9, movieName=007, score=269.5]
Movie [userid=9, movieName=碟中谍, score=238.5]
Movie [userid=10, movieName=星球大战, score=243.5]
.....
代码:
package com.huhu.day06;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.WritableComparable;
public class Movie implements WritableComparable<Movie> {
private int userid;
private String movieName;
private float score;
public Movie() {
super();
}
public Movie(int userid, String movieName, float score) {
super();
this.userid = userid;
this.movieName = movieName;
this.score = score;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getMovieName() {
return movieName;
}
public void setMovieName(String movieName) {
this.movieName = movieName;
}
public float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((movieName == null) ? 0 : movieName.hashCode());
result = prime * result + Float.floatToIntBits(score);
result = prime * result + userid;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Movie other = (Movie) obj;
if (movieName == null) {
if (other.movieName != null)
return false;
} else if (!movieName.equals(other.movieName))
return false;
if (Float.floatToIntBits(score) != Float.floatToIntBits(other.score))
return false;
if (userid != other.userid)
return false;
return true;
}
@Override
public String toString() {
return "Movie [userid=" + userid + ", movieName=" + movieName + ", score=" + score + "]";
}
@Override
public void readFields(DataInput in) throws IOException {
this.userid = in.readInt();
this.movieName = in.readUTF();
this.score = in.readFloat();
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(userid);
out.writeUTF(movieName);
out.writeFloat(score);
}
@Override
public int compareTo(Movie o) {
if (this.userid == o.getUserid()) {
if (this.score == o.score) {
return this.movieName.compareTo(o.movieName);
} else {
return (int) (o.getScore() - this.score);
}
} else {
return this.userid - o.getUserid();
}
}
}
package com.huhu.day06;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* 输入: 1 盗梦空间 4.0
*
* 输出 : 1 盗梦空间:4.0,碟中谍:1.5,禁闭岛:4.0
*
* @author huhu_k
*
*/
public class Step1 {
static class MyMapper extends Mapper<LongWritable, Text, IntWritable, Text> {
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, IntWritable, Text>.Context context)
throws IOException, InterruptedException {
String[] line = value.toString().split("\t");
// k:用户 v: item电影名称:分数
context.write(new IntWritable(Integer.valueOf(line[0])), new Text(line[1] + ":" + line[2]));
}
}
// 相同key的数据相遇 k:1 v:{}
static class MyReduce extends Reducer<IntWritable, Text, IntWritable, Text> {
Text va = new Text();
@Override
protected void reduce(IntWritable key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
StringBuffer br = new StringBuffer();
for (Text v : values) {
br.append("," + v.toString());
}
va.set(br.toString().replaceFirst(",", ""));
// k:用户id v:电影1:评分,电影2:评分.....
// 1 盗梦空间:4.0,碟中谍:1.5,禁闭岛:4.0
context.write(key, va);
}
}
public Job getJob(Configuration conf) throws Exception {
Path inpath = new Path("hdfs://ry-hadoop1:8020/in/items.txt");
Path outpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step1");
Job job = Job.getInstance(conf, this.getClass().getSimpleName());
job.setJarByClass(this.getClass());
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(IntWritable.class);
job.setMapOutputValueClass(Text.class);
job.setReducerClass(MyReduce.class);
job.setOutputKeyClass(IntWritable.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, inpath);
FileOutputFormat.setOutputPath(job, outpath);
return job;
}
}
package com.huhu.day06;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* 输入:1 盗梦空间:4.0,碟中谍:1.5,禁闭岛:4.0
*
* 输出 :007 40:2.5
*
* @author huhu_k
*
*/
public class Step3 {
static class MyMapper extends Mapper<LongWritable, Text, Text, Text> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] line = value.toString().split("\t");
String userid = line[0];
String[] item = line[1].split(",");
for (String it : item) {
context.write(new Text(it.split(":")[0]), new Text(userid + ":"+new Text(it.split(":")[1])));
}
}
}
public Job getJob(Configuration conf) throws Exception {
Path inpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step1");
Path outpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step3");
Job job = Job.getInstance(conf, this.getClass().getSimpleName());
job.setJarByClass(Step3.class);
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, inpath);
FileOutputFormat.setOutputPath(job, outpath);
return job;
}
}
package com.huhu.day06;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* 商品同现矩阵 输出 :1 盗梦空间:4.0,碟中谍:1.5,禁闭岛:4.0
*
* 输出:007:007 19
*
* @author huhu_k
*
*/
public class Step2 {
static class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
private Text k = new Text();
private final IntWritable one = new IntWritable(1);
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//盗梦空间:4.0 碟中谍:1.5 禁闭岛:4.0
String[] line = value.toString().split("\t")[1].split(",");
System.err.println(line+"----------------------");
for (int i = 0; i < line.length; i++) {
for (int j = 0; j < line.length; j++) {
k.set(line[i].split(":")[0] + ":" + line[j].split(":")[0]);
// k: 盗梦空间:碟中谍 1 每个人看过所有电影的乘积
context.write(k, one);
}
}
}
}
static class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
// k: 盗梦空间:碟中谍 1
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable v : values) {
sum += v.get();
}
// k:007:007 v:19
context.write(key, new IntWritable(sum));
}
}
public Job getJob(Configuration conf) throws Exception {
Path inpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step1");
Path outpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step2");
Job job = Job.getInstance(conf, this.getClass().getSimpleName());
job.setJarByClass(this.getClass());
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
job.setReducerClass(MyReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, inpath);
FileOutputFormat.setOutputPath(job, outpath);
return job;
}
}
package com.huhu.day06;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* 输入:1 盗梦空间:4.0,碟中谍:1.5,禁闭岛:4.0
*
* 输出 :007 40:2.5
*
* @author huhu_k
*
*/
public class Step3 {
static class MyMapper extends Mapper<LongWritable, Text, Text, Text> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] line = value.toString().split("\t");
String userid = line[0];
String[] item = line[1].split(",");
for (String it : item) {
context.write(new Text(it.split(":")[0]), new Text(userid + ":"+new Text(it.split(":")[1])));
}
}
}
public Job getJob(Configuration conf) throws Exception {
Path inpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step1");
Path outpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step3");
Job job = Job.getInstance(conf, this.getClass().getSimpleName());
job.setJarByClass(Step3.class);
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, inpath);
FileOutputFormat.setOutputPath(job, outpath);
return job;
}
}
package com.huhu.day06;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* step4: 计算推荐结果列表 输入:007:007 19 输入:007 40:2.5
*
* 输出:19 华尔街之狼,22.0
*
* @author huhu_k
*
*/
public class Step4 {
static class MyMapper extends Mapper<LongWritable, Text, Text, Text> {
String filename = "";
@Override
protected void setup(Context context) throws IOException, InterruptedException {
FileSplit inputSplit = (FileSplit) context.getInputSplit();
// 获取父文件名
filename = inputSplit.getPath().getParent().getName();
}
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] line = value.toString().split("\t");
if ("step2".equals(filename)) {
String[] v1 = line[0].split(":");
String item1 = v1[0];
String item2 = v1[1];
String num = line[1];
context.write(new Text(item1), new Text("A:" + item2 + "," + num));
} else if ("step3".equals(filename)) {
String item = line[0];
String userid = line[1].split(":")[0];
String score = line[1].split(":")[1];
context.write(new Text(item), new Text("B:" + userid + "," + score));
}
}
}
// 相同key的数据相遇 k:1 v:{}
static class MyReduce extends Reducer<Text, Text, Text, Text> {
// k: 电影名称 v:A:007,20 来自于商品同现矩阵
// k: 电影名称 v:B:1,4 来自于用户评分矩阵
String[] info = null;
@Override
protected void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
Map<String, String> mapA = new HashMap<>();
Map<String, String> mapB = new HashMap<>();
for (Text va : values) {
String src = va.toString();
if (src.startsWith("A:")) {
// A:电影名称,次数
info = src.substring(2).split(",");
// mapA k: 电影名称 v:次数
mapA.put(info[0], info[1]);
} else if (src.startsWith("B:")) {
// B:用户,评分
info = src.substring(2).split(",");
// mapB k: 用户 v:评分
mapB.put(info[0], info[1]);
}
}
float result = 0;
Iterator<String> iterator = mapA.keySet().iterator();
while (iterator.hasNext()) {
String item = iterator.next();
int num = Integer.parseInt(mapA.get(item));
Iterator<String> iterator2 = mapB.keySet().iterator();
while (iterator2.hasNext()) {
String userid = iterator2.next();
float score = Float.valueOf(mapB.get(userid));
result = score * num;
context.write(new Text(userid), new Text(item + "," + result));
}
}
}
}
public Job getJob(Configuration conf) throws Exception {
Path inpath1 = new Path("hdfs://ry-hadoop1:8020/out/day06/step2");
Path inpath2 = new Path("hdfs://ry-hadoop1:8020/out/day06/step3");
Path outpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step4");
Job job = Job.getInstance(conf, this.getClass().getSimpleName());
job.setJarByClass(Step4.class);
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class);
job.setReducerClass(MyReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, inpath1);
FileInputFormat.addInputPath(job, inpath2);
FileOutputFormat.setOutputPath(job, outpath);
return job;
}
}
package com.huhu.day06;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* step5: 合并结果列表 输入:19 华尔街之狼,22.0
*
* 输出:19 华尔街之狼,229.0
*
* @author huhu_k
*
*/
public class Step5 {
static class MyMapper extends Mapper<LongWritable, Text, IntWritable, Text> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] line = value.toString().split("\t");
context.write(new IntWritable(Integer.parseInt(line[0])), new Text(line[1]));
}
}
// 相同key的数据相遇 k:1 v:{}
static class MyReduce extends Reducer<IntWritable, Text, IntWritable, Text> {
// k: 电影名称 v:A:007,20 来自于商品同现矩阵
// k: 电影名称 v:B:1,4 来自于用户评分矩阵
@Override
protected void reduce(IntWritable key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
Map<String, Float> map = new HashMap<>();
for (Text v : values) {
String[] str = v.toString().split(",");
String item = str[0];
float score = Float.valueOf(str[1]);
if (map.containsKey(item)) {
map.put(item, map.get(item) + score);
} else {
map.put(item, score);
}
}
for (Map.Entry<String, Float> m : map.entrySet()) {
context.write(key, new Text(m.getKey() + "," + m.getValue()));
}
}
}
public Job getJob(Configuration conf) throws Exception {
Path inpath1 = new Path("hdfs://ry-hadoop1:8020/out/day06/step4");
Path outpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step5");
Job job = Job.getInstance(conf, this.getClass().getSimpleName());
job.setJarByClass(Step5.class);
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(IntWritable.class);
job.setMapOutputValueClass(Text.class);
job.setReducerClass(MyReduce.class);
job.setOutputKeyClass(IntWritable.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, inpath1);
FileOutputFormat.setOutputPath(job, outpath);
return job;
}
}
package com.huhu.day06;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.filecache.DistributedCache;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* 输入:排除 用户看过的电影,并且 排序输出 降序 输入:19 华尔街之狼,289.0
*
* 输出 :1 肖申克的救赎 132.5 1 教父 124.0 1 星球大战 112.0 1 王的盛宴 107.0 1 华尔街之狼 101.5
*
* @author huhu_k
*
*/
public class Step6 {
static class MyMapper extends Mapper<LongWritable, Text, IntWritable, Text> {
private Map<Integer, String> map;
private Path[] localFiles;
@Override
protected void setup(Context context) throws IOException, InterruptedException {
map = new HashMap<>();
Configuration conf = context.getConfiguration();
localFiles = DistributedCache.getLocalCacheFiles(conf);
for (Path p : localFiles) {
BufferedReader br = new BufferedReader(new FileReader(p.toString()));
String word = "";
while ((word = br.readLine()) != null) {
String[] s = word.split("\t");
int userid = Integer.parseInt(s[0]);
String item = s[1];
if (map.containsKey(userid)) {
// 1 007;008
map.put(userid, map.get(userid) + ";" + item);
} else {
// 1 007
map.put(userid, item);
}
}
br.close();
}
}
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, IntWritable, Text>.Context context)
throws IOException, InterruptedException {
String[] line = value.toString().split("\t");
// 19 华尔街之狼,289.0
int userid = Integer.valueOf(line[0]);
String movie = line[1].split(",")[0];
String movieList = map.get(userid);
// map得到null 第一次来 没有任何数据
if (movieList == null || movieList.length() == 0 || movieList == "" || !movieList.contains(movie)) {
context.write(new IntWritable(userid), new Text(line[1]));
}
}
}
// 相同key的数据相遇 k:1 v:{}
static class MyReduce extends Reducer<IntWritable, Text, Movie, NullWritable> {
private TreeSet<Movie> set = new TreeSet<>();
@Override
protected void reduce(IntWritable key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
for (Text v : values) {
Movie m = new Movie(Integer.parseInt(key.toString()), v.toString().split(",")[0],
Float.parseFloat(v.toString().split(",")[1]));
set.add(m);
}
}
@Override
protected void cleanup(Context context) throws IOException, InterruptedException {
for (Movie m : set) {
context.write(m, NullWritable.get());
}
}
}
public Job getJob(Configuration conf) throws Exception {
Path inpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step5");
Path outpath = new Path("hdfs://ry-hadoop1:8020/out/day06/step6");
DistributedCache.addCacheFile(new URI("hdfs://ry-hadoop1:8020/in/items.txt"), conf);
Job job = Job.getInstance(conf, this.getClass().getSimpleName());
job.setJarByClass(Step6.class);
job.setMapperClass(MyMapper.class);
job.setMapOutputKeyClass(IntWritable.class);
job.setMapOutputValueClass(Text.class);
job.setReducerClass(MyReduce.class);
job.setOutputKeyClass(Movie.class);
job.setOutputValueClass(NullWritable.class);
FileInputFormat.addInputPath(job, inpath);
FileOutputFormat.setOutputPath(job, outpath);
return job;
}
}
package com.huhu.day06;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapreduce.lib.jobcontrol.ControlledJob;
import org.apache.hadoop.mapreduce.lib.jobcontrol.JobControl;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class Movie_App extends ToolRunner implements Tool {
private Configuration con;
public static void main(String[] args) throws Exception {
Movie_App m = new Movie_App();
int num = ToolRunner.run(m.getConf(), m, args);
System.exit(num);
}
@Override
public Configuration getConf() {
if (con == null) {
return new Configuration();
}
return con;
}
@Override
public void setConf(Configuration arg0) {
}
@Override
public int run(String[] arg0) throws Exception {
Step1 step1 = new Step1();
Step2 step2 = new Step2();
Step3 step3 = new Step3();
Step4 step4 = new Step4();
Step5 step5 = new Step5();
Step6 step6 = new Step6();
ControlledJob controlledJob1 = new ControlledJob(step1.getJob(getConf()).getConfiguration());
ControlledJob controlledJob2 = new ControlledJob(step2.getJob(getConf()).getConfiguration());
ControlledJob controlledJob3 = new ControlledJob(step3.getJob(getConf()).getConfiguration());
ControlledJob controlledJob4 = new ControlledJob(step4.getJob(getConf()).getConfiguration());
ControlledJob controlledJob5 = new ControlledJob(step5.getJob(getConf()).getConfiguration());
ControlledJob controlledJob6 = new ControlledJob(step6.getJob(getConf()).getConfiguration());
controlledJob2.addDependingJob(controlledJob1);
controlledJob3.addDependingJob(controlledJob1);
controlledJob4.addDependingJob(controlledJob2);
controlledJob4.addDependingJob(controlledJob3);
controlledJob5.addDependingJob(controlledJob4);
controlledJob6.addDependingJob(controlledJob5);
JobControl jobControl = new JobControl("Movive");
jobControl.addJob(controlledJob1);
jobControl.addJob(controlledJob2);
jobControl.addJob(controlledJob3);
jobControl.addJob(controlledJob4);
jobControl.addJob(controlledJob5);
jobControl.addJob(controlledJob6);
Thread t = new Thread(jobControl);
t.start();
while (!jobControl.allFinished()) {
t.sleep(1000);
}
jobControl.stop();
return 0;
}
}
关于什么是矩阵:我看了两篇比较好得,推荐给大家。
https://blog.csdn.net/xyilu/article/details/9066973
https://blog.csdn.net/liuxinghao/article/details/39958957
MapRedcue的demo(协同过滤)的更多相关文章
- win7下使用Taste实现协同过滤算法
如果要实现Taste算法,必备的条件是: 1) JDK,使用1.6版本.需要说明一下,因为要基于Eclipse构建,所以在设置path的值之前要先定义JAVA_HOME变量. 2) Maven,使用2 ...
- 基于Python协同过滤算法的认识
Contents 1. 协同过滤的简介 2. 协同过滤的核心 3. 协同过滤的实现 4. 协同过滤的应用 1. 协同过滤的简介 关于协同过滤的一个最经典的例子就是看电影,有时候 ...
- SparkMLlib—协同过滤之交替最小二乘法ALS原理与实践
SparkMLlib-协同过滤之交替最小二乘法ALS原理与实践 一.Spark MLlib算法实现 1.1 显示反馈 1.1.1 基于RDD 1.1.2 基于DataFrame 1.2 隐式反馈 二. ...
- SparkMLlib—协同过滤推荐算法,电影推荐系统,物品喜好推荐
SparkMLlib-协同过滤推荐算法,电影推荐系统,物品喜好推荐 一.协同过滤 1.1 显示vs隐式反馈 1.2 实例介绍 1.2.1 数据说明 评分数据说明(ratings.data) 用户信息( ...
- 推荐系统-协同过滤在Spark中的实现
作者:vivo 互联网服务器团队-Tang Shutao 现如今推荐无处不在,例如抖音.淘宝.京东App均能见到推荐系统的身影,其背后涉及许多的技术.本文以经典的协同过滤为切入点,重点介绍了被工业界广 ...
- MapReduce实现倒排索引(类似协同过滤)
一.问题背景 倒排索引其实就是出现次数越多,那么权重越大,不过我国有凤巢....zf为啥不管,总局回应推广是不是广告有争议... eclipse里ctrl+t找接口或者抽象类的实现类,看看都有啥方法, ...
- [Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现
1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...
- 协同过滤和简单SVD优化
协同过滤(collaborative filtering) 推荐系统: 百度百科的定义是:它是利用电子商务网站向客户提供商品信息和建议,帮助用户决定应该购买什么产品,模拟销售人员帮助客户完成购买过程主 ...
- 推荐系统(协同过滤,slope one)
1.推荐系统中的算法: 协同过滤: 基于用户 user-cf 基于内容 item –cf slop one 关联规则 (Apriori 算法,啤酒与尿布) 2.slope one 算法 slope o ...
随机推荐
- SQLAlchemy(包含有Flask-Migrate知识点)
what's the SQLAlchemy SQLAlchemy是一个基于Python实现的ORM框架.该框架建立在 DB API之上,使用关系对象映射进行数据库操作,简言之便是:将类和对象转换成SQ ...
- nuxtJs中直接使用自带的@nuxtjs/axios
最初我以为在nuxtjs中是需要重新npm install axios,但是其实nuxtjs自己集成了这个数据渲染方法 你只需在nuxt.config.js中配置一下就可以了 modules: [ / ...
- 027-Session状态提供程序
Session分三种:1.InProc(进程内)-默认就是这种-速度快/但内存小/易丢失进程外:可以在IIS或ASPNET服务意外关闭时继续保持状态,注意此时存储到session中的对象必须支持序列化 ...
- nginx rewrite 指令
ginx通过ngx_http_rewrite_module模块支持url重写.支持if条件判断,但不支持else. 该模块需要PCRE支持,应在编译nginx时指定PCRE源码目录, nginx安装方 ...
- make pycaffe时候报错:Makefile:501: recipe for target 'python/caffe/_caffe.so' failed
安装caffe-ssd编译环境的时候报错: python/caffe/_caffe.cpp:10:31: fatal error: numpy/arrayobject.h: No such file ...
- 再解炸弹人,dfs&bfs
输入样例: 13 13 3 3##############GG.GGG#GGG.####.#G#G#G#G##.......#..G##G#.###.#G#G##GG.GGG.#.GG##G#.#G# ...
- 第十篇——Struts2的拦截器栈
拦截器栈: 从结构上看:拦截器栈相当于多个拦截器的组合: 从功能上看:拦截器栈也是拦截器. 默认拦截器栈: 在struts-core.jar包中的struts-default.xml中自定义了一个de ...
- Java 五大原则
1.单一职责 不论是在设计类,接口还是方法,单一职责都会处处体现,单一职责的定义:我们把职责定义为系统变化的原因.所有在定义类,接口,方法的时候.定义完以后再去想一想是不能多于一个的动机去改变这个类, ...
- docker容器与大数据组件的冲突点
1.容器里面安装spark,外面的程序(安装spark主机的容器)会连接不上集群.理由:这个组件用的akka,连接上集群,会提示: akka.ErrorMonitor: dropping messag ...
- draw9patch图片拉伸
在此吐槽Android studio的稳定性,我用的Android studio已经完全不能用了.只要新建项目资源文件就会变成乱码.解决无果,忍无可忍的我只能重新下了一个低版本的.虽然还是有点毛病,但 ...