# 推荐策略的设计与实现
# 一些初始的设定
# 用户分类
系统会将用户分为新用户与老用户, 新用户即仅有少量用户行为的用户, 老用户是有大量 (30 条以上) 用户行为的用户. 系统要求用户登录后使用系统, 以降低系统复杂度.
# 新闻类别分类
# 完整的新闻类别表
英文 | 中文 | 英文 | 中文 | 英文 | 中文 |
---|---|---|---|---|---|
society | 社会 | entertainment | 娱乐 | tech | 科技 |
military | 军事 | sports | 体育 | car | 汽车 |
finance | 财经 | world | 国际 | fashion | 时尚 |
travel | 旅游 | discovery | 探索 | baby | 育儿 |
regimen | 养生 | story | 故事 | essay | 美文 |
game | 游戏 | history | 历史 | food | 美食 |
# 定义的 对时间敏感的类别
英文 | 中文 | 英文 | 中文 | 英文 | 中文 |
---|---|---|---|---|---|
society | 社会 | entertainment | 娱乐 | tech | 科技 |
military | 军事 | sports | 体育 | car | 汽车 |
finance | 财经 | world | 国际 | fashion | 时尚 |
game | 游戏 |
# 定义的 对时间不敏感的类别
英文 | 中文 | 英文 | 中文 | 英文 | 中文 |
---|---|---|---|---|---|
travel | 旅游 | discovery | 探索 | baby | 育儿 |
regimen | 养生 | story | 故事 | essay | 美文 |
history | 历史 | food | 美食 |
# 用户行为定义 (完整)
- 无动作
- 文章编辑
- 文章浏览
- 文章点赞 (-3)
- 文章点踩 (-4)
- 对文章评论, 即数据库中的评论 (-5)
- 对文章评论点赞 (-6)
- 对文章评论点踩 (-7)
- 对评论评论, 即数据库中的回复 (-8)
- 对评论评论点赞 (-9)
- 对评论评论点踩 (-10)
- 关注用户 (-11)
实际情况下用不到这么多行为.
# 推荐算法
# 新闻排分
对新闻打分, 然后推荐. 新闻打分时, 系统使用了四个参数: 新闻时间 (新闻发布时间距离当前时间的小时差的绝对值), 新闻评论数量, 新闻回复数量以及新闻阅读数量. 这四个参数分别使用了四个不同的权重值 (当然有相同的权重问题也不是很大) , 其中新闻时间使用的是负权重, 作为新闻分数的惩罚.
# 协同过滤算法
协同过滤, 基于用户相似度. 相似度的计算对两个用户特征向量计算求和平方差, 值越小, 用户相似度越高. 所谓的用户特征向量, 就是用户在 18 种不同类别下做出的用户行为的统计值.
相似用户计算, 这应该是我这活到现在, 写过的最长的一个 SQL.
<select id="getRelativeCusList" resultType="java.lang.Integer">
select
a.cfc_cus_id
from CusFeatureCount as a,
(select
cfc_news_society, cfc_news_entertainment, cfc_news_tech, cfc_news_military, cfc_news_sports, cfc_news_finance,
cfc_news_world, cfc_news_fashion, cfc_news_travel, cfc_news_discovery, cfc_news_baby, cfc_news_regimen,
cfc_news_story, cfc_news_essay, cfc_news_game, cfc_news_history, cfc_news_food, cfc_news_car
from CusFeatureCount where cfc_cus_id = #{cusId}) as b
where a.cfc_cus_id != #{cusId}
order by
SQRT(
POW((cast(a.cfc_news_society as signed) - cast(b.cfc_news_society as signed)), 2) +
POW((cast(a.cfc_news_entertainment as signed) - cast(b.cfc_news_entertainment as signed)), 2) +
POW((cast(a.cfc_news_tech as signed) - cast(b.cfc_news_tech as signed)), 2) +
POW((cast(a.cfc_news_military as signed) - cast(b.cfc_news_military as signed)), 2) +
POW((cast(a.cfc_news_sports as signed) - cast(b.cfc_news_sports as signed)), 2) +
POW((cast(a.cfc_news_finance as signed) - cast(b.cfc_news_finance as signed)), 2) +
POW((cast(a.cfc_news_world as signed) - cast(b.cfc_news_world as signed)), 2) +
POW((cast(a.cfc_news_fashion as signed) - cast(b.cfc_news_fashion as signed)), 2) +
POW((cast(a.cfc_news_travel as signed) - cast(b.cfc_news_travel as signed)), 2) +
POW((cast(a.cfc_news_discovery as signed) - cast(b.cfc_news_discovery as signed)), 2) +
POW((cast(a.cfc_news_baby as signed) - cast(b.cfc_news_baby as signed)), 2) +
POW((cast(a.cfc_news_regimen as signed) - cast(b.cfc_news_regimen as signed)), 2) +
POW((cast(a.cfc_news_story as signed) - cast(b.cfc_news_story as signed)), 2) +
POW((cast(a.cfc_news_essay as signed) - cast(b.cfc_news_essay as signed)), 2) +
POW((cast(a.cfc_news_game as signed) - cast(b.cfc_news_game as signed)), 2) +
POW((cast(a.cfc_news_history as signed) - cast(b.cfc_news_history as signed)), 2) +
POW((cast(a.cfc_news_food as signed) - cast(b.cfc_news_food as signed)), 2) +
POW((cast(a.cfc_news_car as signed) - cast(b.cfc_news_car as signed)), 2)
)
limit #{num};
</select>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 推荐场景
系统需要提供热点新闻推荐与个性化新闻推荐. 同时为了避免推荐系统抽风了一样向用户推荐他 "想要的" 内容, 避免用户陷入坑内无法跳到其他类别中; 同时也是为了给所有的新闻能够在用户面前呈现的机会, 系统在不同的推荐场景下的推荐内容基本都不是来源于单一的方式.
# 热点新闻推荐
使用新闻排分的推荐方式, 不区分用户类型, 这是最简单的推荐. 热点新闻需要来源于对时间敏感的类别, 同时新闻发布时间距离当期时间不超过 72 小时. 热点新闻依据新闻排分择优录取.
# 个性化推荐
# 新用户综合推荐
使用新闻排分推荐.
新闻来源
- 20% 新创建的新闻 (仅依据时间排序)
- 70% 对时间敏感的新闻
- 10% 对时间不敏感的新闻
# 新用户单一类别推荐
使用新闻排分推荐.
新闻来源
- 10% 此类别新创建的新闻 (仅依据时间排序)
- 90% 此类别新闻 (排分推荐)
# 老用户综合推荐
使用相似用户推荐, 当相似用户推荐内容结束后, 系统将切回到新用户综合推荐 (大概).
新闻来源
- 30% 热点新闻 (新闻排分推荐)
- 60% 相似用户推荐
- 10% 新创建的新闻 (仅依据时间排序)
# 老用户单一类别推荐
计划也是使用相似用户推荐, 但是一个问题是, 某些用户并没有在某些类别下有用户行为, 强行的相似用户推荐并不是一个好主意, 所以系统的具体实现使用的仍然是新用户单一类别推荐.
新闻来源
- 10% 此类别新创建的新闻 (仅依据时间排序)
- 90% 此类别新闻 (排分推荐)
← 用户系统的设计与实现 总结与展望 →