推荐算法之-相似邻居计算

在上面两篇文章已经讲了如何通过用户对产品的评分分别计算出某个用户与其他用户之间的相似度,那么在计算完相似度后如何才能获取和该用户相似度高的人呢,方法分为两种:

1、固定数量的K个邻居,(K-neighborhoods)。意思很明确,就是按分数高低降序取K个

2、基于相似度门槛的邻居,(Threshord-based neighborhood)。取分数K分以上的作为邻居

<?php
/**
 * 余玄相似度计算出3个用户的相似度
 * 通过7件产品分析用户喜好相似度
 * 相似度使用函数 sim(user1,user2) =cos∂
 *
 * 设A、B为多维矩阵
 *
 *          ∑(Ai•Bi)            ∑(Ai•Bi)            ∑(USER1_i•USER2_i)
 * cos∂ = --------------- = -----------------  =  -------------------------
 *          |Ai|•|Bi|          √∑ Ai² • √∑ Bi²     √∑ USER1_i² • √∑ USER2_i²
 */

$infoTable = [
    'user1' => [
        5, 5, 4, 7, 8, 9, 4, //  分别为产品1评分,产品2评分,产品3评分,产品4评分,产品5评分,产品6评分,产品7评分
    ],
    'user2' => [
        1, 9, 1, 9, 2, 2, 8,
    ],
    'user3' => [
        5, 5, 5, 7, 8, 9, 3,
    ],
    'user4' => [
        9, 1, 9, 1, 8, 9, 1,
    ],
];

function calc($user1, $user2)
{
    global $infoTable;

    $sumAiBi = 0;
    $sumAi   = 0;
    $sumBi   = 0;
    $len     = 7; //7个产品
    for ($i = 0; $i < $len; $i++) {
        //∑(Ai•Bi)
        $sumAiBi += $infoTable[$user1][$i] * $infoTable[$user2][$i];

        //∑USER1_i
        $sumAi += pow($infoTable[$user1][$i], 2);

        //∑USER2_i
        $sumBi += pow($infoTable[$user2][$i], 2);
    }

    return $sumAiBi / (sqrt($sumAi) * sqrt($sumBi));

}

/**
 * K邻居
 *
 * @param array $arr
 * @param int   $K
 *
 * @return array
 */
function kNeighborhoods(array $arr, int $K)
{
    // 根据value降序排列
    array_multisort($arr, SORT_DESC);

    $KN_ARR = [];
    $i      = 0;
    foreach ($arr as $k => $v) {
        if ($i >= $K) {
            break;
        }
        $KN_ARR[$k] = $v;
        $i++;
    }

    return $KN_ARR;
}

/**
 * 相似度门槛
 *
 * @param array $arr
 * @param float $K
 *
 * @return array
 */
function thresholdBaseNeighborhoods(array $arr, float $K)
{
    $thresholdBashArr = [];
    foreach ($arr as $k => $v) {
        if ($v >= $K) {
            $thresholdBashArr[$k] = $v;
        }
    }

    return $thresholdBashArr;
}

// 计算user1的K邻居
$simArr = [];
$kUser  = 'user1';
foreach ($infoTable as $k => $v) {
    if ($k == $kUser) {
        continue;
    }
    $simArr[$k] = calc($kUser, $k);
}
print_r($simArr);
echo 'K邻居,K = 2时:' . PHP_EOL;
print_r(kNeighborhoods($simArr, 2));
echo '相似度门槛,K=0.9时:'.PHP_EOL;
print_r(thresholdBaseNeighborhoods($simArr,0.9));

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
├──Package │ ├── Sort 排序篇 │ │ ├── BubbleSort.php 冒泡排序 │ │ ├── HeapSort.php 堆排序 大根堆 │ │ ├── MBaseSort.php 基数排序 MSD │ │ ├── LBaseSort.php 基数排序 LSD │ │ ├── QuickSort.php 快速排序 │ │ ├── ShuttleSort.php 飞梭排序 │ │ ├── ShellSort.php 希尔排序 │ │ ├── MergeSort.php 归并排序 │ │ ├── InsertSort.php 插入排序 │ │ └── SelectSort.php 选择排序 │ │ │ ├── Query 查找篇 │ │ ├── BinaryQuery.php 二分查找 │ │ ├── InseertQuery.php 插入查找 │ │ ├── FibonacciQuery.php 斐波那契查找 │ │ ├── BFSQuery.php 广度优先查找 │ ├── Kmp.php 算法导论-KMP算法 │ ├── DijkstraQuery.php 迪克斯特拉算法 │ │ └── QulickQuery.php 快速查找 │ │ │ ├── Structure 数据结构 │ │ ├── StackExample.php 堆栈 先进后出 LIFO (Last In First Out) │ │ ├── LinearChain.php 线性表 单链存储 │ │ └── LinearOrder.php 线性表 顺序存储 │ │ └── BinarySearchTree.php 二叉搜索树 │ │ │ ├── Tools 小工具集 │ │ └── SystemSwitch.php 堆栈实现进制转换 │ │ │ └── Other 其他 │ ├── MonkeyKing.php 约瑟夫环 │ ├── DynamicProgramming.php 动态规划 │ ├── Fibonacci.php 斐波那契数列 │ ├── StealingApples.php 偷苹果求余 │ ├── HanoiGames.php 汉诺塔游戏 │ ├── BidirectionalQueue.php 双向队列 │ ├── ColorBricks.php 彩色砖块 │ ├── GetCattle.php 牛年求牛 │ ├── OnlyNumbers.php 求唯一数 │ ├── PokerGames.php 洗扑克牌 │ ├── Interval.php 抽奖区间算法 │ ├── Maze.php 迷宫寻址算法 │ ├── AntsClimb.php 蚂蚁爬杆算法 │ ├── Encryption.php 对称加密算法 │ ├── ElevatorDispatch.php 编程之美-电梯调度算法 │ ├── PointInTriangle.php 向量叉集计算点是否在三角形中 │ ├── TraversalOfBinary.php 二叉树非递归遍历算法实现 │ ├── Knapsack.php 贪心算法之背包问题实现 │ └── BigSmallReplace.php Hello World 输出 Olleh Dlrow │ └── Solution.php Facebook面试题之岛屿周长算法 │ └── RotationSort.php Facebook面试题之顺时针回旋算法 │ └── Square.php Facebook面试题之判断四个点能否组成正方形算法 │ └── Prim.php Prim算法(最小生成树算法) │ └── CartesianProduct.php 笛卡尔积算法 │ └── Square.php 面试题之平面任意四点能否组成一个矩形 │ └── Judge.php 面试题之扑克牌中任选五张判断是不是顺子 │ └── Factorial.php 面试题之N的阶乘末尾有多少个0

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_________MAN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值