【火炉炼AI】机器学习032-用户之间相似度的计算

(本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )

在构建推荐引擎时,一般需要计算两个用户之间的相似度,以便找到与数据库中特定用户相似的用户。计算相似度的方法有很多种,其中比较常见的两种是计算欧几里得距离和皮尔逊相关系数,本文分别讲述使用这两种方法来计算用户之间的相似度。

1. 计算两个用户的欧氏距离

欧几里得距离是欧几里得空间中两点间的普通距离,即两点组成的直线的距离。其计算公式可以说是数学里的基本公式,如下,其基本含义就是计算两个点之间的空间距离。

欧式距离很直观,是常见的一种相似度算法。其基本思路为:根据两用户之间共同评价的项目为维度,建立一个多维空间,用户对单一维度上的评价就可以组成一个数组或向量,一旦这个向量确定,那么就可以确定这个用户在这个多维空间的位置。但我们把多个用户都放置到这个多维空间后,距离非常近的两个用户,可以认为他们之间的相似度非常高,反之,距离较远的用户之间的相似度也较远,故而这种多维空间内的用户之间的欧式距离就标定了他们之间的相似度。

但是在日常使用中,我们一般不太习惯数值小反而表示相似度高,故而对这种数值取一个倒数,使得数值都落在0-1之间,即使用 1/(1+Distance(X,Y))之后,得到的相似度范围为:0<=Similarity(X,y)<=1,越接近1,表示相似度越高,这种表示方式很符合我们的惯性思维。

下面用代码来计算两个用户之间的欧式距离,其思想是,计算两个用户在数据集中的所有项目中的平方和,然后在开方,得到两个用户之间的距离,在用倒数法转变一下。

# 定义一个函数来计算两个用户之间的欧式距离
def euclidean_distance(dataset,user1,user2):# 首先要排除一种情况,如果数据集中不存在同时被两个用户评价过的电影,# 则表示两个用户之间的没有相似度,直接返回0both_rated_num=0 # 表示同时被两个用户都评价过的电影的数目for item in dataset[user1]: # 在user1评价过的电影中if item in dataset[user2]: # 如果user2也评价过,则+1both_rated_num+=1if both_rated_num==0:# 不存在同时被两个用户都评价过的电影return 0 # 直接返回0,表示两个用户之间相似度为0squared_difference=[] # 每一个元素表示同时被两个用户都评价过的电影得分的欧式距离for item in dataset[user1]:if item in dataset[user2]:squared_difference.append(np.square(dataset[user1][item]-dataset[user2][item]))return 1/(1+np.sqrt(np.sum(squared_difference)))复制代码

由于原始的电影评价数据都存放在movie_ratings.json文件中,所以需要用json模块加载数据,并对其进行分析

# 原始的电影评价数据都放置在 movie_ratings.json文件中,我们加载进来看看结果
import json
with open("E:\PyProjects\DataSet\FireAI\movie_ratings.json",'r') as file:dataset=json.loads(file.read())# 现在计算两个随机用户之间的欧式距离
user1='John Carson'
user2='Michelle Peterson'
print(" Euclidean score: ",euclidean_distance(dataset,user1,user2))
复制代码

---------------------------输---------出--------------------------------

Euclidean score: 0.29429805508554946

--------------------------------完-------------------------------------

即此处计算出这两个用户之间的欧式距离为0.29,相似度不是很高。

欧式距离虽然是比较常用的计算用户相似度的方法,但是它有其内在的缺点,比如:

1,由于计算时基于各维度特征的绝对数值,所以欧式距离需要保证各维度指标在相同的刻度级别。

2,欧式距离是数据上的直观体现,看似简单,但在处理一些受主观影响很大的评分数据时,效果则不太明显。即评价者的评价相对于平均水平偏离很大的时候欧式距离不能很好地揭示出真实的相似度。

2. 计算两个用户的皮尔逊相关系数

在统计学中,皮尔逊相关系数用于度量两个变量之间的线性相关性,其值位于-1到1之间。相关系数为1时,成为完全正相关;当相关系数为-1时,成为完全负相关;相关系数的绝对值越大,相关性越强;相关系数越接近于0,相关度越弱。

# 定义一个函数来计算两个用户之间的皮尔逊相关系数
def pearson_score(dataset,user1,user2):# 和上面的函数类似,先排除相似度为0的情况
#     both_rated_num=0 # 表示同时被两个用户都评价过的电影的数目
#     for item in dataset[user1]: # 在user1评价过的电影中
#         if item in dataset[user2]: # 如果user2也评价过,则+1
#             both_rated_num+=1
#     if both_rated_num==0:# 不存在同时被两个用户都评价过的电影
#         return 0 # 直接返回0,表示两个用户之间相似度为0both_rated={}for item in dataset[user1]:if item in dataset[user2]:both_rated[item]=1num_ratings=len(both_rated)if num_ratings==0: # 不存在同时被两个用户都评价过的电影return 0# 计算每个用户对每个相同电影的评价之和user1_sum=np.sum([dataset[user1][item] for item in both_rated])user2_sum=np.sum([dataset[user2][item] for item in both_rated])# 计算每个用户对每个相同电影的评价的平方和user1_squared_sum = np.sum([np.square(dataset[user1][item]) for item in both_rated])user2_squared_sum = np.sum([np.square(dataset[user2][item]) for item in both_rated])# 计算两个用户的相同电影的乘积product_sum=np.sum([dataset[user1][item]*dataset[user2][item] for item in both_rated])# 计算Pearson 相关系数Sxy = product_sum - (user1_sum * user2_sum / num_ratings)Sxx = user1_squared_sum - np.square(user1_sum) / num_ratingsSyy = user2_squared_sum - np.square(user2_sum) / num_ratingsif Sxx * Syy == 0:return 0return Sxy / np.sqrt(Sxx * Syy)
复制代码

同理计算得到两个用户的皮尔逊相关系数为: Peason score: 0.396. 相似度不能横向比较,即不能将Pearson得分和欧式距离进行比较,这样比较没有意义,只能用于纵向比较。

########################小**********结###############################

1,用户之间的相似度计算可以采用欧式距离的方式计算,也可以采用皮尔逊相关系数来计算。

2,貌似用皮尔逊相关系数来表示相似度更好一些,在很多时候能够克服欧式距离表示法的一些缺点。

#################################################################

注:本部分代码已经全部上传到(我的github)上,欢迎下载。

参考资料:

1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译

【火炉炼AI】机器学习032-用户之间相似度的计算相关推荐

  1. 【火炉炼AI】机器学习053-数据降维绝招-PCA和核PCA

    [火炉炼AI]机器学习053-数据降维绝招-PCA和核PCA (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplo ...

  2. 【火炉炼AI】机器学习007-用随机森林构建共享单车需求预测模型

    [火炉炼AI]机器学习007-用随机森林构建共享单车需求预测模型 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matp ...

  3. 【火炉炼AI】机器学习018-项目案例:根据大楼进出人数预测是否举办活动

    [火炉炼AI]机器学习018-项目案例:根据大楼进出人数预测是否举办活动 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, ...

  4. 【火炉炼AI】机器学习040-NLP性别判断分类器

    [火炉炼AI]机器学习040-NLP性别判断分类器 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib ...

  5. 【火炉炼AI】机器学习044-创建隐马尔科夫模型

    [火炉炼AI]机器学习044-创建隐马尔科夫模型 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2 ...

  6. 词袋模型 matlab,【火炉炼AI】机器学习051-视觉词袋模型+极端随机森林建立图像分类器...

    [火炉炼AI]机器学习051-视觉词袋模型+极端随机森林建立图像分类器 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, m ...

  7. 【火炉炼AI】机器学习023-使用层次聚类算法构建模型

    [火炉炼AI]机器学习023-使用层次聚类算法构建模型 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotli ...

  8. python用numpy和pil处理图像成灰度图_「火炉炼AI」机器学习047-图像的直方图均衡化操作...

    [火炉炼AI]机器学习047-图像的直方图均衡化操作 [火炉炼AI]机器学习047-图像的直方图均衡化操作 (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, sc ...

  9. 【火炉炼AI】机器学习013-用朴素贝叶斯分类器估算个人收入阶层

    [火炉炼AI]机器学习013-用朴素贝叶斯分类器估算个人收入阶层 (本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matp ...

最新文章

  1. 【基础概念】 Redis简介和面试常见问题
  2. 1022.在线视频—IT售前营销讲座(三)售前情报、策划和资源协调
  3. NeurIPS 2020有哪些值得读的「图神经网络」论文?
  4. 缓存-分布式锁-Redisson-信号量测试
  5. ffmpeg命令 抓屏_使用FFmpeg从视频中截图的命令 | 学步园
  6. MySql的存储过程
  7. pyecharts怎么绘制散点图_pyecharts可视化和wx的结合
  8. c++ time.h 用法
  9. css怎么设置数字的字体格式,css设置字母数字字体库信息
  10. 北航 软件学院课程 实用软件工具
  11. 详解|天猫搜索前端技术历代记
  12. hn版是什么版本的教材_初中教材都有什么版本
  13. Redis客户端连接远程Redis服务器
  14. 这几本书看了之后在工作生活上都是有用的
  15. Python 在线编译器简单实现
  16. RemoteView流程
  17. VulnStack-ATTCK-3(红日靶场三)
  18. 小伙伴们-GO-带你揭开Linux的神秘面纱
  19. 为什么韭菜一定要割三次后开花?
  20. 中文为什么没有词干提取_词干中没有小写字母

热门文章

  1. b树c语言,B树——思路、及C语言代码的实现
  2. 解决Pycharm无法使用已经安装Selenium的问题
  3. 使用WebStorm将项目部署到IIS
  4. POJ 1692 Crossed Matchings dp[][] 比较有意思的dp
  5. BZOJ 3357: [Usaco2004]等差数列( dp )
  6. C# 委托实例(跨窗体操作控件)
  7. (3)插入排序之一 直接插入排序
  8. Asp.net 2.0生命周期
  9. oracle数据库初始化参数分类,oracle初始化参数设置
  10. ASP.NET Core 使用MySQL(Database First)