User-based KNN with LibRec
本项目使用领先的推荐系统Java开源工具库LibRec
完成,实现其中的UserKNN
算法,并使用struts2
框架完成简单的网页展示。
Prerequisites
- JDK 1.7
- TomCat 7.0
- struts 2.3.34
- LibRec 2.0
- BootStrap 3.3.7
Algorithm
本项目的算法使用的是基于协同过滤的User-based KNN
算法。基本思想就是,如果你喜欢某几部电影,而另外一个人也喜欢这几部电影,并且他还喜欢A电影,则你也很有可能喜欢A电影。
因此算法的原理就是先找到与目标用户相似的用户集合,然后找到集合中用户喜欢的并且目标用户没有评价过的物品推荐给他。
计算相似度
该算法通常使用Jaccard公式或余弦相似度计算两个用户之间的相似度。
Jaccard:
$$
W_{uv}=\frac{ |N(u)\cap N(v)| }{ |N(u)\cup N(v)| }
$$
余弦相似度:
$$
W_{uv}=\frac{ |N(u)\cap N(v)| } {\sqrt { |N(u)\cup N(v)| }}
$$
假设用户ABCD与物品abcde的关系如下:
A | a | b | d |
---|---|---|---|
B | a | c | |
C | b | e | |
B | c | d | e |
首先建立“物品—用户”的倒排表 :
a | A | B |
---|---|---|
b | A | C |
c | B | D |
d | A | D |
e | C | D |
然后对于每个物品,喜欢他的用户,两两之间相同物品加1:
A | B | C | D | |
---|---|---|---|---|
A | 0 | 1 | 1 | 1 |
B | 1 | 0 | 0 | 1 |
C | 1 | 0 | 0 | 1 |
D | 1 | 1 | 1 | 0 |
接着计算余弦相似度:
A | B | C | D | |
---|---|---|---|---|
A | 0 | $$\frac 1 {\sqrt {3\times 2}}$$ | $$\frac 1 {\sqrt {3\times 2}}$$ | $$\frac 1 {\sqrt {3\times 3}}$$ |
B | $$\frac 1 {\sqrt {3\times 2}}$$ | 0 | 0 | $$\frac 1 {\sqrt {3\times 2}}$$ |
C | $$\frac 1 {\sqrt {3\times 2}}$$ | 0 | 0 | $$\frac 1 {\sqrt {3\times 2}}$$ |
D | $$\frac 1 {\sqrt {3\times 3}}$$ | $$\frac 1 {\sqrt {3\times 2}}$$ | $$\frac 1 {\sqrt {3\times 2}}$$ | 0 |
####推荐物品
首先从矩阵中找出与目标用户 $$u $$最相似的 K 个用户,用集合$$ S(u, K) $$表示,将$$ S $$中用户喜欢的物品全部提取出来,并去除$$ u$$ 已经喜欢的物品。
对于每个候选物品$$ i $$,用户$$ u $$对它感兴趣的程度用如下公式计算:
$$
p(u,i)=\sum_{v\in S(u,K)\cap N(i)}{w_{uv} \times r_{vi}}
$$
其中$$r_{vi}$$表示用户$$ v $$对$$ i$$ 的喜欢程度,在本例中都是为 1,在一些需要用户给予评分的推荐系统中,则要代入用户评分。
这样,就能计算出任意目标用户对其他物品可能的的喜欢程度了,按照得分排序就能得到推荐的物品列表。
Installation
导入项目到eclipse中,部署到TomCat即可。
Configuration
Datasets:
filmtrust ratings
librec.properties:
- data:
数据目录是dfs.data.dir=/data
,该目录放在WebContent/WEB-INF/classes/
下,其中数据文件是data.input.path=ratings.txt
,因为filmtrust的数据格式为User-Item-Rating,所以librec设置中数据的格式为data.column.format=UIR
因为放在了classes下面,所以通过tomcat运行项目时相对路径是没有问题的,可以直接运行。
- Splitter:
LibRec中含有数据的划分方式共五类, 将数据集根据一定比例划分为训练集与测试集(及验证集), 留出其中一个作为验证, 给定N个作为验证, K折交叉验证, 以及测试数据集与训练数据集等五种方式. 其中部分分割方式又含有基于user或item等其他分割方式。综合考虑之后使用ratio
按照比例划分为训练集与测试集,其中训练集比例设置为0.8 。
- Evaluator:
RecommenderEvaluator
接口用于实现对特定算法的评估. 目前实现对于ranking的评估器有AUC, Precision, Recall等十类评估器. 对于rating实现评估器有MAE, MPE, MSE, RMSE这四类。由于本项目使用的是rating方式,所以使用了RMSE
评估器。
Running
Web:
Console:
web结果中可以看到推荐给用户1的电影,console中可以看到RMSE均方标准差以及推荐的数据。
Architecture
GetRecAction.java
struts框架的Action类,用于获取用户输入的id,存储由
GetRecItem.java
推荐的电影表。GetRecItem.java
实现LibRec的推荐算法功能的类,参考librec官网的文档。