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

最近在折腾一个图片站,我想在其中加入一个不要太差劲的推荐系统。算法

可能有些童鞋尚未明白推荐系统是啥玩意,下面我Paste百度百科的一段说明,也算是凑字数啊!!!数组

推荐系统:个性化推荐是根据用户的兴趣特色和购买行为,向用户推荐用户感兴趣的信息和商品。随着电子商务规模的不断扩大,商品个数和种类快速增加,顾客须要花费大量的时间才能找到本身想买的商品。这种浏览大量无关的信息和产品过程无疑会使淹没在信息过载问题中的消费者不断流失。为了解决这些问题,个性化推荐系统应运而生。个性化推荐系统是创建在海量数据挖掘基础上的一种高级商务智能平台,以帮助电子商务网站为其顾客购物提供彻底个性化的决策支持和信息服务…查看所有信息函数

推荐系统应用很普遍:使用淘宝、京东的时候,他们会向咱们推荐可能感兴趣的商品,用今日头条、UC新闻的时候,推荐感兴趣的新闻,百度的广告匹配等等。测试

安利结束啦….网站

做为一个资深的Copy && Paste工程师,首先想到的是百度一下PHP的推荐系统(别问我为何不用谷歌)。url

结果让我比较失望:我竟然没找到一个靠谱的推荐系统,有些虽然有推荐系统这个关键词在里面,可是实际上和推荐并无什么关系。spa

好吧,既然不能找到现成的轮子,那么只好本身造轮子了。orm

首先明确一点:要作一个不要太差劲的推荐系统,可是也不会太好(好的推荐系统涉及的东西太多了,远比咱们想象的复杂)。blog

既然要完成这么一个推荐系统,确定是要进行用户行为分析的。图片

在一年半以前,我进入第一家公司作社交应用的时候,其实有个需求就是智能的广告推荐(商家的精确推送),可是当时的Boss想了一个办法,让我当时跃跃欲试的心情瞬间低落下来,这个办法就是:用户注册的时候,兴趣分类必须选择,而后推荐这几个兴趣相关的广告。

这样其实也没错,可是显得很Low啊,用户的行为每时每刻都在发生变化,甚至选择了羽毛球这种兴趣实际上倒是常常参加篮球活动,因此,咱们不能作得这么Low,首先要获取用户行为数据,进行数据分析,利用类似度进行推荐。

今天,咱们利用欧几里德距离计算类似度(类似度计算还有皮尔逊相关度、曼哈顿距离、Jaccard系数等)。

这个算法的原理就是:获取两个不一样用户之间类似的地方,计算每个类似数据的平方,而后将全部平方之和进行求平方根操做,就获得了数据。

在PHP中,数组是一种强大的数据类型,做用覆盖其余语言中的数组、列表、字典等数据类型。
首先,咱们假设已经完成了数据收集这一步,并将数据存放进PHP数组中,方便后续计算。
注:本次实例假设你已经知晓PHP的基本语法及简单的数学知识(如平方、平方根)。

为了方便演示,我假设有五个样本,分别冠以赵1、钱2、孙3、李4、周伍,每一个样本购买过各不相同的图书,并对图书有着不同的评分。

数组以下:

$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

相关文章
相关标签/搜索