您的位置:首页 > 其它

推荐系统算法之基于邻域的算法

2014-05-20 12:03 239 查看
基于领域的算法是推荐系统中最基本的算法,该算法在实际应用中得到了广泛的应用,亚马逊的推荐算法就是采用基于领域的算法。基于领域的算法分为两大类,一类是基于用户的协同过滤算法,这种算法给用户推荐和他兴趣相似的其他用户喜欢的物品;另一类是基于物品的协同过滤算法,这种算法给用户推荐和他之前喜欢的物品相似的物品。

实验所采用的数据集可以用GroupLens提供的MovieLens数据集。为了测试方便,这里暂时使用一个有10条记录的二维数组:

$train=array(
array(1,11),		//array(userid,itemid)
array(1,12),
array(1,14),
array(2,11),
array(2,13),
array(3,12),
array(3,15),
array(4,13),
array(4,14),
array(4,15),
);
一、基于用户的协同过滤算法

该算法的主要步骤:

1、找到与该用户兴趣相似的用户集;

2、找到这个集合中的用户喜欢的但是没有听说过的物品推荐给目标用户。

用户的相似度可以用如下公式计算:



其中u,v表示两个用户,N(u)表示用户u曾经有过正反馈的物品集合;N(v)表示用户v曾经有过正反馈的物品集合。因为大多数用户的兴趣相似度可能位0,即|N(u)∩N(v)|
= 0,所以我们可以建立一个物品到用户的倒排表:



实现该步骤的PHP代码:

//计算相似度
function userSimilarity($train){
//建立物品列表
$item_user=array();	//存放物品列表
for($i=0;$i<count($train);$i++){
$item=$train[$i][1];
$user=$train[$i][0];
$item_user[$item][]=$user;
}

$N=array();	//$N[u]表示用户u使用过的物品总数
$C=array();	//C[u][v]=|N(u)∩N(u)|
foreach($item_user as $user){
for($i=0;$i<count($user);$i++){
$N[$user[$i]]+=1;
for($j=0;$j<count($user);$j++){
if($user[$i]!=$user[$j]){
$C[$user[$i]][$user[$j]]+=1;
}
}
}
}

$W=array();	//$W[u][v]表示用户u和用户v的相似度
foreach($C as $key=>$value){
$u=$key;	//用户u
foreach($value as $v=>$cuv){
$W[$u][$v]=$cuv/sqrt($N[$u]*$N[$v]);
}
}

return $W;
}
最后我们就可以给用户推荐和他兴趣相似的其他用户喜欢的物品:



其中,P(u,i)是用户u对物品i的感兴趣程度,S(u,k)包含和用户兴趣最接近的K个用户,N(i)是对物品i有过行为的用户集合Wuv是用户u和v的兴趣相似度,Rvi代表用户v对物品i的兴趣,因为使用的是单一的隐反馈数据,所以所有的Rvi=1.

实现上面UserCF算法的PHP代码如下:

//推荐算法
function recommend($user,$train,$W){
$rank=array();	//用户对物品的感兴趣程度

for($i=0;$i<count($train);$i++){
if($train[$i][0]==$user){
//用户使用过的物品集合
$interacted_items[]=$train[$i][1];
}
}

$group=$W[$user];	//和用户兴趣相似的其他用户
arsort($group);
$count=0;	//计算器
$K=3;	//和用户最接近的K个用户
foreach($group as $v=>$wuv){
$count++;
for($i=0;$i<count($train);$i++){
if($train[$i][0]==$v&&!in_array($train[$i][1], $interacted_items)){
$rank[$train[$i][1]]+=$wuv;
}
}

if($count==$K) break;
}

return $rank;
}
最后使用如下代码测试(即给id为1的用户推荐物品):

$W=userSimilarity($train);
print_r(recommend(1,$train,$W));
/*
* 显示
Array
(
[13] => 0.7415816237972
[15] => 0.7415816237972
)
*/
推荐系统会给用户推荐物品id为13、15号的物品,用户1对它们的感兴趣程度都是0.7416.

二、基于物品的协同过滤算法

基于物品的协同过滤(item-based
collaborative filtering)算法是目前使用最多的算法。亚马逊、Netflix、Hulu、Youtube的推荐算法基础都是该算法。基于物品的协同过滤算法主要分为两步:

1、计算物品间的相似度;

2、根据物品的相似度和用户的历史行为给用户生成推荐列表。

和基于用户的协同过滤算法相似,我们也需要建立一个用户倒物品的倒排表,物品i和物品j的相似度可以用同时喜欢物品i和j的用户数,即|N(i)∩N(j)|,除以√|N(i)||N(j)|.并且计算用户u对一个物品i的感兴趣程度也和基于用户的协同过滤算法类似,所有的代码如下:

<?php
//ItemCF
error_reporting(E_ALL&&~E_NOTICE);
$train=array(
array(1,11),		//array(userid,itemid)
array(1,12),
array(1,14),
array(2,12),
array(2,13),
array(2,15),
array(3,13),
array(3,14),
array(4,12),
array(4,13),
array(4,14),
array(5,11),
array(5,14),
);

//计算相似度
function itemSimilarity($train){
//建立用户到物品倒排表
$user_item=array();
for($i=0;$i<count($train);$i++){
$item=$train[$i][1];
$user=$train[$i][0];
$user_item[$user][]=$item;
}

$N=array();	//$N[i]表示喜欢物品i的用户数
$C=array();	//C[i][j]=|N(i)∩N(j)|
foreach($user_item as $item){
for($i=0;$i<count($item);$i++){
$N[$item[$i]]+=1;
for($j=0;$j<count($item);$j++){
if($item[$i]!=$item[$j]){
$C[$item[$i]][$item[$j]]+=1;
}
}
}
}

$W=array();	//$W[i][j]表示物品i和物品j的相似度
foreach($C as $key=>$value){
$i=$key;	//物品i
foreach($value as $j=>$cij){
$W[$i][$j]=$cij/sqrt($N[$i]*$N[$j]);
}
}
return $W;
}

//推荐算法
function recommend($train,$user_id,$W,$K){
$rank=array();	//用户对物品的感兴趣程度
//用户到物品倒排表,和itemSimilarity的重复,以后可以考虑合并或更换训练集的数据结构
$user_item=array();
for($i=0;$i<count($train);$i++){
$item=$train[$i][1];
$user=$train[$i][0];
$user_item[$user][]=$item;
}
$ru=$user_item[$user_id];	//用户喜欢的物品集合
foreach($ru as $i){
//$W[$i]表示和物品i相似的其他物品集合
arsort($W[$i]);
$count=0;	//计数器
foreach($W[$i] as $j=>$wij){
$count++;
if(!in_array($j, $ru)){
$rank[$j]+=$wij;
}

if($count==$K) break;
}
}

return $rank;
}

$W=itemSimilarity($train);
print_r(recommend($train,1,$W,3));
?>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: