您的位置:首页 > 其它

【推荐系统】推荐系统简介及相似度计算

2015-12-24 00:00 309 查看
最近在折腾一个图片站,我想在其中加入一个不要太差劲的推荐系统。
可能有些童鞋还没有明白推荐系统是啥玩意,下面我Paste百度百科的一段说明,也算是凑字数啊!!!
推荐系统:个性化推荐是根据用户的兴趣特点和购买行为,向用户推荐用户感兴趣的信息和商品。随着电子商务规模的不断扩大,商品个数和种类快速增长,顾客需要花费大量的时间才能找到自己想买的商品。这种浏览大量无关的信息和产品过程无疑会使淹没在信息过载问题中的消费者不断流失。为了解决这些问题,个性化推荐系统应运而生。个性化推荐系统是建立在海量数据挖掘基础上的一种高级商务智能平台,以帮助电子商务网站为其顾客购物提供完全个性化的决策支持和信息服务…查看全部信息
推荐系统应用很广泛:使用淘宝、京东的时候,他们会向我们推荐可能感兴趣的商品,用今日头条、UC新闻的时候,推荐感兴趣的新闻,百度的广告匹配等等。
安利结束啦….
作为一个资深的Copy && Paste工程师,首先想到的是百度一下PHP的推荐系统(别问我为什么不用谷歌)。
结果让我比较失望:我居然没找到一个靠谱的推荐系统,有些虽然有推荐系统这个关键词在里面,但是实际上和推荐并没有什么关系。
好吧,既然不能找到现成的轮子,那么只好自己造轮子了。
首先明确一点:要做一个不要太差劲的推荐系统,但是也不会太好(好的推荐系统涉及的东西太多了,远比我们想象的复杂)。
既然要完成这么一个推荐系统,肯定是要进行用户行为分析的。
在一年半之前,我进入第一家公司做社交应用的时候,其实有个需求就是智能的广告推荐(商家的精确推送),但是当时的Boss想了一个办法,让我当时跃跃欲试的心情瞬间低落下来,这个办法就是:用户注册的时候,兴趣分类必须选择,然后推荐这几个兴趣相关的广告。
这样其实也没错,但是显得很Low啊,用户的行为每时每刻都在发生变化,甚至选择了羽毛球这种兴趣实际上却是经常参加篮球活动,所以,我们不能做得这么Low,首先要获取用户行为数据,进行数据分析,利用相似度进行推荐。
今天,我们利用欧几里德距离计算相似度(相似度计算还有皮尔逊相关度、曼哈顿距离、Jaccard系数等)。
这个算法的原理就是:获取两个不同用户之间相似的地方,计算每一个相似数据的平方,然后将所有平方之和进行求平方根操作,就得到了数据。
在PHP中,数组是一种强大的数据类型,作用覆盖其他语言中的数组、列表、字典等数据类型。
首先,我们假设已经完成了数据收集这一步,并将数据存放进PHP数组中,方便后续计算。
注:本次实例假设你已经知晓PHP的基本语法及简单的数学知识(如平方、平方根)。
为了方便演示,我假设有五个样本,分别冠以赵一、钱二、孙三、李四、周伍,每个样本购买过各不相同的图书,并对图书有着不一样的评分。
数组如下:

$array = array(
‘赵一’ => array(
“人类简史” => 5.0,
“代码大全” => 4.7,
“从零到一” => 4.5,
“文明之光” => 3.9,
“数学之美” => 3.7
),
‘钱二’ => array(
“人类简史” => 5.0,
“代码大全” => 4.0,
“宇宙之书” => 3.8,
“时间简史” => 4.8,
“梦的解析” => 4.0
),
‘孙三’ => array(
“全球通史” => 4.5,
“宇宙之书” => 3.6,
“时间简史” => 4.8,
“梦的解析” => 4.0
),
‘李四’ => array(
“人类简史” => 5.0,
“代码大全” => 4.0,
“从零到一” => 4.2,
“梦的解析” => 4.0
),
‘周伍’ => array(
“全球通史” => 4.5,
“宇宙之书” => 4.8,
“时间简史” => 3.8,
“梦的解析” => 4.0
)
);

假设我们要计算钱二和周伍的相似度,用下面一个坐标系表示:
我们怎么计算他们之间的距离呢(相似度)?
首先利用pow函数对某一个数据求平方,比如我们对钱二和周伍的《时间简史》这一项进行求平方:

$sum = pow($array[‘钱二’][‘时间简史’] – $array[‘钱二’][‘时间简史’], 2);

然后,就要进行求平方根操作了:

$sim = sqrt($sum);

为了更直观,我们将sim值加上1(避免遇到被0整除)之后再取它的倒数:

$sim = 1 / ($sim + 1);

这样就可以得到0到1之间的数字了,越接近0,代表相似度越低,越接近1,代表相似度越高。
下面给出完整的PHP代码实现:

function similarity($array, $person1, $person2)
{
//保存两人相同数据,数组交集计算
$pub = array_intersect_key($array[$person1], $array[$person2]);
//若没有共同点,返回0
if (count($pub) == 0) return 0;
//计算交集平方和
$sum = 0;
foreach ($pub as $key => $value) {
$sum += pow($array[$person1][$key] – $array[$person2][$key], 2);
}
return 1 / (1 + sqrt($sum));
}
$sim = similarity($array, ‘钱二’, ‘周伍’);
echo $sim;

好了,相似度计算就到此为止,既然算出来了相似度,就可以进行推荐的工作了。
假设钱二和周伍的相似度达到60%以上(不代表上述代码运行结果),那么就可以进行相关的推荐了。
具体的下次有机会再说吧!!!
备注:为了方便测试,我给出上面代码的运行结果,也就是钱二和周伍的相似度值:0.4142135623731
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: