我理解的预测与推荐

推荐

怎么做推荐呢?实际开发过程中,我们一边学习推荐相关的知识,一边先按直觉做了几个 demo。

在第一个版本中,用模糊查询实现。根据用户的相关信息到数据查询。大概是因为逻辑判断太多了,速度非常慢。

第二个版本,尝试优化查询语句,建立索引。

第三个版本。因为前面已经通过多元回归计算出了用户的工资区间(虽然很不准确就是了),我们拍脑袋觉得对于一份工作来说,工资是很重要的,于是直接按工资区间到数据库查询…

前两个版本,模糊查询的推荐结果还不错,至少能一眼看出与用户的信息有关。但是速度实在太慢了。

第三个版本,因为前面做的预测结果本来就不准,所以效果更差劲…而且这个思路太想当然了。

但至少现在已经有这样一个功能模块了!!于是接着尝试真正的推荐。

我理解的推荐

因为水平不到位,不能从比较宏观的角度解释,下面都只是我在这个项目中的感受。所以,推荐以「推荐 Job」为例…

我理解的推荐,就是为用户建立一个模型——「我最喜欢的 Job」。系统不断优化这个模型,试图找到用户心中最中意的那个 Job。(这只是个理想化的模型,实际的系统当中可能并不存在)然后从系统中找出与这个模型最匹配的 Job,推荐给用户。

那么问题来了,计算机怎么判断用户是不是中意某个 Job 呢?

我们看看协同过滤算法中的基于用户的推荐算法。

基于用户的推荐算法

最简单的一种,如下:

1
2
小明 喜欢 A、B、C。
小红 喜欢 A、B、C、D。

我们发现小红的喜欢和小明的喜欢重叠度很高,小明可能也会喜欢 D,所以把 D 推荐给他。

但是这种判断的粒度太大了,再细一点可以这样:

1
2
3
4
5
小明 非常喜欢 A
小明 有点喜欢 B

小红 非常喜欢 B
小红 有点喜欢 A

在计算机中,可以简化为这样的三元组 < 用户 ID, 物品 ID, 用户偏好 > 表示:

1
2
3
4
5
6
用户   JobID   偏好值(权重)
小明 001 15
小明 002 0

小红 001 0
小红 002 15

那么这个偏好值怎么来呢?

肯定需要严格的算法…

我们可以粗略举个例子来理解,比如用户点击一次某个职位,我们假定他是被这个职位所吸引,把他与这个职位的权重相应增加。

这样在计算机内部就得到用户与 Job 的关系。

用这样的数值来量化之后,我们就可以通过做一些矩阵运算,根据用户自己的列表和别的用户的列表,把口味相似的用户关注的职位推荐给用户。

好了!暂且到这一步。

我们回过头来看,基于用户的推荐算法,需要满足两项。

  1. 用户(使用推荐功能的用户)的喜好
  2. 别的用户的喜好

这就是冷启动需要解决的问题。

它不仅需要用户自己有信息,还需要别的用户有信息…

考虑到我们做的这个小项目根本不可能有那么多用户,测试起来也麻烦,看来这个方式不合适…

基于内容的推荐算法

基于用户的推荐算法,是通过比较各个用户的喜好,把别的用户关注的东西推荐给有共同喜好的用户。

而基于内容的推荐算法,就是把用户的喜好直接与 Job (物品)比较。

还是看个最简单的:

1
2
小红       喜欢 哲学书籍
《大问题》 是 哲学书籍

所以把《大问题》推荐给小红。

同样,我们可以更细粒度一点:

1
2
3
4
5
小红       非常喜欢   哲学书籍
小红 有点喜欢 小说

《大问题》 是 哲学书籍
《爱的教育》 是 小说

我们优先推荐《大问题》给小红…

而在计算机内,可能是这样表示的:

1
2
3
4
5
6
7
8
9
用户		标签		权重
小红 Java 10
小红 Web 9

Job 标签 权重
001 Java 0
001 Web 10
002 Java 10
002 Web 9

通过计算向量距离,得出用户和 Job 的相似度,生成推荐。

基于内容的推荐需要解决两个问题。

第一个仍然是冷启动,用户需要打上标签。我们考虑过根据用户的行为——历史记录,点击记录等来生成用户标签。

不过都没时间做…(太真实了)

其实提到这个场景,我想到的是各种信息流 app,注册时让用户选择一堆感兴趣的话题,相当于打上标签。于是我也模仿这样做了个…

我们只做到了用户和某个标签产生联系,如标签 HadoopJava

存在数据库里 :

1
2
3
4
用户 ID		标签Id		有无 // 标志用户有没有选择某个标签。。。
001 001 0
001 002 1
...

第二个问题就是提取出 Job 的标签,并且提取权重。

这个是重点也是难点…

从抽象的角度来看,Job 其实也只是一串文本描述的一样物品。

粗略地做,我们可以进行简单的词频统计…

常用的更标准的方式是使用 TF-IDF。

比较

SQL 模糊查询是基于元数据的推荐。比如推荐书,紧紧按出版年份来推荐是不太合适的。(大多数情况下)

而协同过滤,是基于标签,更合理些(理论上)。

我们做出来的效果,感觉模糊查询似乎看起来科学点…至少能在推荐的结果找到我们的输入的信息。

通过后面的方式得到的推荐结果(因为我们技术不到位的原因)看起来有点没头没脑…