zoukankan      html  css  js  c++  java
  • 协同推荐算法-php实现

    概述:

      因为最近对算法这块进行了学习,所以最近对类似淘宝商品推荐协同推荐算法进行了整理总结,本文将用php语言进行实现,文章将从以下几点进行终结:  

      (1)什么是协同推荐算法?有什么用?

      (2)依据什么数学方法公式,为什么要用它?

      (3)实现流程是怎样的?

      (4)具体实现步骤。

      首先,第一点,我们要实现一个算法必须要知道它有什么用,核心思想是什么?顾名思义,它的用途就是用来给我们做一些相似性推荐,推荐你喜欢的恭喜,根据你的好友等预测你喜欢的然后再推荐给你;我们举个例子来概括一下算法的核心思想:该算法的核心思想可以概括为:若a,b喜欢同一系列的物品(暂时称b是a的邻居吧),则a很可能喜欢b喜欢的其他物品。算法的实现流程可以简单概括为:1.确定a有哪些邻居 2.通过邻居来预测a可能会喜欢哪种物品  3.将a可能喜欢的物品推荐给a。

      现在我们了解了这个核心思想以后,我们知道算法的核心是数学逻辑,我们必须理解其数学思想,然后再转化为编程思想达到我们的目标:

           我们先回忆一下余弦定理:

      

      

      可见cosA的夹角越小cosA的值越大,则边c和边b的长度越相近,因此我们利用余弦定理的向量方式类推出如下公式:

    1.余弦相似度(求邻居):

    暂无

    2.预测公式(预测a可能会喜欢哪种物品):

    暂无

     

      接下来我们介绍一下实现流程:

     

      现在我们具体看看怎样用php实现这个算法:

      (1)数据准备:在这里我们直接定义一组数据

      

    $userarray= [
        ['name'=>'A','a'=>3,'b'=>2,'c'=>1,'d'=>5,'e'=>null,'f'=>null,'g'=>null], 
        ['name'=>'B','a'=>1,'b'=>6,'c'=>6,'d'=>5,'e'=>2,'f'=>3,'g'=>5],
        ['name'=>'C','a'=>3,'b'=>5,'c'=>null,'d'=>4,'e'=>3,'f'=>3,'g'=>6],
        ['name'=>'D','a'=>4,'b'=>1,'c'=>1,'d'=>5,'e'=>3,'f'=>3,'g'=>3],
        ['name'=>'E','a'=>5,'b'=>1,'c'=>null,'d'=>4,'e'=>5,'f'=>1,'g'=>5],
        ['name'=>'F','a'=>1,'b'=>3,'c'=>2,'d'=>5,'e'=>6,'f'=>null,'g'=>4],
        ['name'=>'G','a'=>1,'b'=>5,'c'=>2,'d'=>5,'e'=>2,'f'=>3ll,'g'=>5]
    
                    ];

     

     

       (2)我们以A用户为对象分别计算出他们的余弦相似度,然后将其存入数组$cos中:

      

    /*
     * 以下示例只求A的推荐
     */
     $denominator_left = 0;//分母左边初始值
    //开始计算cos
    //计算分母左边
    for($i=1;$i<8;$i++){
        if($userarray[0][$i] != null){//$userarray[0]代表A
            $denominator_left += $userarray[0][$i] * $userarray[0][$i];
        }
    }
     
    $denominator_left = sqrt($denominator_left);//取算数平方根的值
     
    for($i=1;$i<6;$i++){
        $numerator = 0;//分子初始值
        $denominator_right = 0;//分母右边初始值
        
        for($j=1;$j<8;$j++){
            //计算分子
            if($userarray[0][$j] != null && $userarray[$i][$j] != null){
                $numerator += $userarray[0][$j] * $userarray[$i][$j];
            }
            //计算分母右边
            if($userarray[$i][$j] != null){
                $denominator_right += $userarray[$i][$j] * $userarray[$i][$j];
            }            
        }
         $denominator_right = sqrt($denominator_right );
    $cos[$i]['cos'] = $numerator /$denominator_left /$denominator_right ;//存储当前用户的cos近似值

       $cos[$i]['name'] = $userarray[$i]['name'];//存储当前用户的名字
       $cos[$i]['e'] = $userarray[$i]['e'];//存储当前用户的e物品评分

       $cos[$i]['f'] = $userarray[$i]['f'];//存储当前用户的f物品评分
       $cos[$i]['g'] = $userarray[$i]['g'];//存储当前用户的g物品评分
    
    
     
     
     
    }

      (3)我们对余弦近似值进行由大到小的排序,抽取前三个用户作为A用户的邻居,我们使用冒泡排序法对其进行排序

      

    // 第一层可以理解为从数组中键为0开始循环到最后一个
    for ($i = 0; $i < count($cos) ; $i++) {
      // 第二层为从$i+1的地方循环到数组最后
        for ($j = $i+1; $j < count($cos); $j++) {
         // 比较数组中两个相邻值的大小
            if ($cos[$i]['cos'] < $cos[$j]['cos']) {
                $tem = $cos[$i]; // 这里临时变量,存贮$i的值
                $cos[$i] = $cos[$j]; // 第一次更换位置
                $cos[$j] = $tem; // 完成位置互换
            }
        }        
    }

      (4)接下来我们对A用户可能喜欢的物品进行预测,利用第二个公式,求出product值

      

    //计算A对e的评分
    $numerator= 0;//分子初始值
    $denominator= 0;//分母初始值
    for($i=0;$i<3;$i++){
        $numerator+= $cos[$i]['cos'] * $cos[$i]['e'];
        $denominator+= $cos[$i]['cos'];
    }
    
    $score_e = $numerator/sqrt($denominator);
    
     
    //计算A对f的评分
    $numerator= 0;//分子初始值
    $denominator= 0;//分母初始值
    for($i=0;$i<3;$i++){
        $numerator+= $cos[$i]['cos'] * $cos[$i]['f'];
        $denominator+= $cos[$i]['cos'];
    }
    
    $score_f= $numerator/sqrt($denominator);
    
    //计算A对g的评分
    $numerator= 0;//分子初始值
    $denominator= 0;//分母初始值
    for($i=0;$i<3;$i++){
        $numerator+= $cos[$i]['cos'] * $cos[$i]['g'];
        $denominator+= $cos[$i]['cos'];
    }
    
    $score_g= $numerator/sqrt($denominator);

      最后我们可以比较这些值,可以选取值最大的物品推荐给用户A

      

      

  • 相关阅读:
    IDEA 快捷键
    Python3开启自带http服务
    redis-creating server tcp listening socket 127.0.0.1:6379: bind No error
    moco的使用方法
    tomcat程序闪退,如何让tomcat不闪退,可以看见报错
    java 项目中Error linstenerStart 报错解决方法
    Linux 常用命令
    TS数据类型及语法
    RabbitMQ的下载和安装
    vue 控制 input 的 disabled
  • 原文地址:https://www.cnblogs.com/zhangbobo/p/11577523.html
Copyright © 2011-2022 走看看