使用欧几里德距离构建简单的推荐系统计算用户相似度

在计算用户相似度的过程中,首先对于两个用户共同打分过的所有条目,计算他们对于每个条目的评分差值,对差值求平方、求和,再对结果求平方根,这样得到的值称为欧氏距离,但这并不足以作为显示度计算的度量值。相似度与距离的概念在某种程度上说是互反的,就其意义而言,欧氏距离越小,两个用户相似度就越大。相似度与距离这种反序关系很容易就可以调整过来,比如只要第一显示度为欧氏距离加1,再取倒数。


02data.php

<?php
$data = array(
    'Frank'=>array(
    	'Tears'=>5,
    	'La'=>4,
    	'Robinson'=>5,
    	'Yesterday'=>4,
    	'Wizard'=>5,
    	'Mozart'=>5,
    	'Bethoven'=>5
        ),
    'Constantine'=>array(
    	'Tears'=>5,
        'Fiddler'=>5,
        'Robinson'=>5,
        'Wonderful World'=>4,
        'Wizard'=>4,
        'Let It Be'=>5,
        'Mozart'=>5
        ),
    'Catherine'=>array(
        'Tears'=>1,
        'Robinson'=>2,
        'Yesterday'=>2,
        'Beethoven'=>3,
        'Sunnday'=>1,
        'Let It Be'=>2,
        ),
     'David'=>array(
        'Tears'=>1,
        'Robinson'=>2,
        'Yesterday'=>2,
        'Let It Be'=>2,
        'Bethoven'=>5
        )

);
?>

getSimilarity.php

<?php 
class getSimilarity
{
    /*
     * 获取两个用户共同条目
     */
    private function getCommonItems($user1,$user2)
    {
        $commonItems = 0;
        $sim = 0;
        foreach ($user1 as $key1=>$value1){
            if(isset($user2[$key1])){
                $commonItems++;
                $sim+=pow($value1-$user2[$key1], 2);
            }   
        }
        return array($commonItems, $sim);
    }
    
    /*
     * 计算相似度
     */
    public function getSim($user1,$user2)
    {
        $cs = $this->getCommonItems($user1, $user2);
        if($cs[0]>0){
            $sim = sqrt($cs[1]/(double)$cs[0]);
            $sim = 1 - tanh($sim);
            $maxCommonItems = min(count($user1),count($user2));
            $sim = $sim*((double)$cs[0]/(double)$maxCommonItems);
            return $sim;
        }else{
            return 0;
        }
    }
    
}


include_once '02data.php';
$user1 = $data['Frank'];
$user2 = $data['Constantine'];
$user3 = $data['Catherine'];
$user4 = $data['David'];


$similarity = new getSimilarity();
echo $similarity->getSim($user1,$user2);
echo '<br />';
echo $similarity->getSim($user1,$user3);
echo '<br />';
echo $similarity->getSim($user1,$user4);
echo '<br />';
echo $similarity->getSim($user2,$user3);
echo '<br />';
echo $similarity->getSim($user2,$user4);
echo '<br />';
echo $similarity->getSim($user3,$user4);


?>


 

上面的代码先求出两个用户有一些共同评分的歌曲,那么把他们对其中每首歌曲评分差值的平方和除以这部分歌曲的数量,再对商取平方根,最后用1减去这个双切正切函数的返回值,最后还考虑的两个用户共有的条目的量与两个人所有可能共有条目量的比率。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值