如何找到相似的用户 -距离公式
曼哈顿距离

欧几里得距离
曼哈顿距离的优点之一是计算速度快,对于Facebook这样需要计算百万用户之间的相似度时就非常有利。

皮尔逊相关系数

左边平方和的累加乘以右边平方和的累加
余弦相似度
其中,“·”号表示数量积。“||x||”表示向量x的模,计算公式是:
我们用上文中“偏好完全一致”的示例:
所以两个向量为:
它们的模是:
数量积的计算:
因此余弦相似度是:
余弦相似度的范围从1到-1,1表示完全匹配,-1表示完全相悖。所以0.935表示匹配度很高**
距离公式使用范围
- 如果数据存在“分数膨胀”问题,就使用皮尔逊相关系数。
- 如果数据比较“密集”,变量之间基本都存在公有值,且这些距离数据是非常重要的,那就使用欧几里得或曼哈顿距离。
- 如果数据是稀疏的,则使用余弦相似度。
只是选择一个最相似的人是不对的 —— K最邻近算法
按照选择的距离公式 来推荐k个距离最近的人;
欧几里得的 K最邻近算法 代码实现
let target = {'张爽' :[2,3,5,6,undefined],"邓超" :[1,2,3,undefined,4],"吴亦凡" :[1,undefined,3,2,1],};// 计算两个对象的距离 例 "张爽” 和“吴亦凡”function ojld(p1,p2) {let sum = 0;for (let i=0; i<p1.length && i<p2.length;i++){if(p1[i] !== undefined && p2[i] !== undefined){sum += p1[i]*p1[i] - p2[i] * p2[i]}}return Math.pow(Math.abs(sum),0.5)}function getObstacle(obj,k) {let persons = Object.keys(obj);// 存储所有距离 返回一个 json对象let result = {};// 两层嵌套循环返回一个距离的矩阵for (let i=0; i<persons.length;i++){// 存放单个的距离let arr = [];for (let j= 0;j<persons.length;j++){if(i !== j) {arr.push({[persons[j]] : ojld(obj[persons[i]],obj[persons[j]])});}}// 如果计算的人数大于k才进行筛选if(k < Object.keys(arr).length){result[persons[i]] = arr.sort((a,b)=>{return Number(Object.values(b)) - Number(Object.values(a))}).slice(0,k)}else {result[persons[i]] = arr}}return result}console.log(getObstacle(target,1));// 可以看看数据结构// { '张爽': [ { '吴亦凡': 7.14142842854285 } ],// '邓超': [ { '张爽': 4.898979485566356 } ],// '吴亦凡': [ { '张爽': 7.14142842854285 } ] }
