博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
推荐系统中的相似性度量
阅读量:4519 次
发布时间:2019-06-08

本文共 4157 字,大约阅读时间需要 13 分钟。

1、 皮尔逊相关系数

在早期的推荐系统中皮尔逊相关系数是一个基础的相似性衡量标准,先从这个参数定义开始说起。
这里写图片描述
皮尔逊系数度量两个一一对应数列之间的线性相关程度,上述四种公式都是计算该系数方法,下面python 代码使用就是公式4。

def sim_pearson(prefs,p1,p2):    # Get the list of mutually rated items    si={}    for item in prefs[p1]:         if item in prefs[p2]: si[item]=1    # if they are no ratings in common, return 0    if len(si)==0:         return 0    # Sum calculations    n=len(si)    # Sums of all the preferences    sum1=sum([prefs[p1][it] for it in si])    sum2=sum([prefs[p2][it] for it in si])      # Sums of the squares    sum1Sq=sum([pow(prefs[p1][it],2) for it in si])    sum2Sq=sum([pow(prefs[p2][it],2) for it in si])      # Sum of the products    pSum=sum([prefs[p1][it]*prefs[p2][it] for it in si])  # Calculate r (Pearson score)    num=pSum-(sum1*sum2/n)    den=sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n))    if den==0:        return 0    r=num/den    return r

说完皮尔逊系数的计算后我们来分析该系数的优势和不足。

优势:该系数可以修正‘夸大分值’的情况,举例就是user1 倾向总是评分为高分,user2 倾向总是评分在低分区域,加入使用时欧式距离这样两个user的相似性比较低,但是其实两个user爱好可能类似,只是他们对分数的标准不是那么一致。
不足:首先没有考虑到两个用户的给出评分数目,两个看过200部电影的用户,即便他们偶尔有些评分不一致,但我们也会觉得比两个仅仅看了2部相同电影用户相似。
其次,根据公式可以发现,如果两个user重叠的评分只有一个item 这样,该公式定义是无法进行计算的,在稀疏数据集上面这个问题尤其凸显出来,当然如果两个用户重叠次数太少我们也基本可以认为两者相似性不高。
最后,根据公式可以明显发现,如果一个user评分序列中所有的评分都是一样的,这样导致该公式是未定义的。

2、 欧式距离定义相似度

这是最常用相似度,不做详细介绍。
3、 余弦相似性度量
简单贴下mahout中余弦公式实现

public static double distance(double[] p1, double[] p2) {    double dotProduct = 0.0;    double lengthSquaredp1 = 0.0;    double lengthSquaredp2 = 0.0;    for (int i = 0; i < p1.length; i++) {      lengthSquaredp1 += p1[i] * p1[i];      lengthSquaredp2 += p2[i] * p2[i];      dotProduct += p1[i] * p2[i];    }    double denominator = Math.sqrt(lengthSquaredp1) * Math.sqrt(lengthSquaredp2);    // correct for floating-point rounding errors    if (denominator < dotProduct) {      denominator = dotProduct;    }    // correct for zero-vector corner case    if (denominator == 0 && dotProduct == 0) {      return 0;    }    return 1.0 - dotProduct / denominator;  }

4、 斯皮尔曼相关系数

理论可以参考这个博客:
下面是mahout中该参数实现主要部分

@Override  public double userSimilarity(long userID1, long userID2) throws TasteException {    PreferenceArray xPrefs = dataModel.getPreferencesFromUser(userID1);    PreferenceArray yPrefs = dataModel.getPreferencesFromUser(userID2);    int xLength = xPrefs.length();    int yLength = yPrefs.length();    if (xLength <= 1 || yLength <= 1) {      return Double.NaN;    }    // Copy prefs since we need to modify pref values to ranks    xPrefs = xPrefs.clone();    yPrefs = yPrefs.clone();    // First sort by values from low to high    xPrefs.sortByValue();    yPrefs.sortByValue();    // Assign ranks from low to high    float nextRank = 1.0f;    for (int i = 0; i < xLength; i++) {      // ... but only for items that are common to both pref arrays      if (yPrefs.hasPrefWithItemID(xPrefs.getItemID(i))) {        xPrefs.setValue(i, nextRank);        nextRank += 1.0f;      }      // Other values are bogus but don't matter    }    nextRank = 1.0f;    for (int i = 0; i < yLength; i++) {      if (xPrefs.hasPrefWithItemID(yPrefs.getItemID(i))) {        yPrefs.setValue(i, nextRank);        nextRank += 1.0f;      }    }    xPrefs.sortByItem();    yPrefs.sortByItem();    long xIndex = xPrefs.getItemID(0);    long yIndex = yPrefs.getItemID(0);    int xPrefIndex = 0;    int yPrefIndex = 0;    double sumXYRankDiff2 = 0.0;    int count = 0;    while (true) {      int compare = xIndex < yIndex ? -1 : xIndex > yIndex ? 1 : 0;      if (compare == 0) {        double diff = xPrefs.getValue(xPrefIndex) - yPrefs.getValue(yPrefIndex);        sumXYRankDiff2 += diff * diff;        count++;      }      if (compare <= 0) {        if (++xPrefIndex >= xLength) {          break;        }        xIndex = xPrefs.getItemID(xPrefIndex);      }      if (compare >= 0) {        if (++yPrefIndex >= yLength) {          break;        }        yIndex = yPrefs.getItemID(yPrefIndex);      }    }    if (count <= 1) {      return Double.NaN;    }    // When ranks are unique, this formula actually gives the Pearson correlation    return 1.0 - 6.0 * sumXYRankDiff2 / (count * (count * count - 1));  }

转载于:https://www.cnblogs.com/huruzun/p/5423887.html

你可能感兴趣的文章
阿里巴巴卖空阿里巴巴入股新浪微博抑制投资者卖空行为
查看>>
分析打开hdu 3335 (最小路径覆盖)
查看>>
添加源ubuntu_x64 安装 Adobe Reader
查看>>
NFS-heartbeat-drbd模拟NFS高可用
查看>>
SQL Server性能调优:资源管理之内存管理篇(上)
查看>>
javaScript 基础知识
查看>>
接近开关,光耦
查看>>
基于visual Studio2013解决C语言竞赛题之1033数字交换
查看>>
给datalist加自动编号(解决博客的第XX楼)
查看>>
BZOJ3282: Tree (LCT模板)
查看>>
ES6中变量的解构赋值
查看>>
编译器C-Free V352注册算法分析
查看>>
数据绑定控件Reperter
查看>>
【codeforces】【比赛题解】#937 CF Round #467 (Div. 2)
查看>>
剑指Offer学习笔记(3)——解决面试题的思路
查看>>
.NET Framework基础知识(二)(转载)
查看>>
Yii DataProvider
查看>>
BestCoder Round #14 B 称号 Harry And Dig Machine 【TSP】
查看>>
hdu 1114 Piggy-Bank
查看>>
maven集成tomcat插件启动报错
查看>>