集体智慧编程学习笔记——提供推荐(一)

协作型过滤

一个协作型过滤 的通常做法是对一大群人进行搜索,并从中找到与我们品味相近的一小群人。算法会对这些人偏爱的其他内容进行考察,并将它们组合起来构造出一个经过排名的推荐列表。有许多不同的方法可以帮助我们确定哪些人与自己品位接近,并将他们的选择组合成列表。

搜集偏好(构造数据集)

使用嵌套的字典,写一个py文件

  1. 将使用交互方式使用python ,因此应该先将这个py文件保存起来,便于python的交互解释程序能够读取到它;
#一个涉及影评者及其对几部影片评分情况的字典
critics={
'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5,  'The Night Listener': 3.0},

'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5,  'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0,  'You, Me and Dupree': 3.5}, 

'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0, 'Superman Returns': 3.5, 'The Night Listener': 4.0},

'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener': 4.5, 'Superman Returns': 4.0,  'You, Me and Dupree': 2.5},

'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,  'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0, 'You, Me and Dupree': 2.0}, 

'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},

'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0},

'xiaoYu': {'Lady in the Water': 2.0, 'Snakes on a Plane': 3.0, 'Just My Luck': 2.5, 'Superman Returns': 3.0, 'You, Me and Dupree': 2.0,  'The Night Listener': 2.5} 
}

相近的用户
搜集完人们的偏好数据后,需要有一种方法来确定人们在品味方面的相似程度。为此,可以将每个人与所有其它人进行对比,并计算他们的相似度评价值
介绍两套计算相似度评价值的体系:
欧几里得距离
皮尔逊相关度

欧几里得距离评价

以经过人们一致评价的物体为坐标轴,将参与评价的人绘制到图上,考察彼此间的距离远近。

处于偏好空间中的人们   处于偏好空间中的人们
两人在偏好空间中的距离越近,他们的兴趣偏好就越相似。
求两人在坐标平面的距离:

from math import sqrt
print(sqrt(pow(4.5-4, 2)+pow(1-2, 2)))

需要一个偏好函数:偏好越相近的情况给出越大的值:
1 x 2 + y 2 + 1 \frac{1}{\sqrt {x^2+y^2}+1} x2+y2 +11

加一可以避免被0整除的错误。这一新的函数返回介于0-1之间的值,返回1 表明两人具有一样的偏好

构造计算相似度的函数sim_distance:

#返回一个有关person1和person2的基于距离的相似度的评价
def sim_distance(prefs, person1, person2):
	#得到shared_items的列表
	si={}
	for item in prefs[person1]:
		if item in prefs[preson2]:
			si[item]=1
	#如果两者没有共同之处,则返回0
	if len(si)==0: return 0
	sum_of_squares=sum(pow(prefs[person1][item]-prefs[person2][item],2) for item in prefs[person1] if item in prefs[person2])
	return 1/sqrt(sum_of_squares)
		

可以通过以下方式获取两个人的欧几里得距离:

import recommendations
x=recommendations.sim_distance(recommendations.critics, 'Lisa Rose', 'Gene Seymour')
print(x)

皮尔逊相关度评价

更复杂的方法判断人们兴趣的相似度:皮尔逊相关系数
该相关系数是判断两组数据与某一直线拟合程度 的一种度量,对应的公式比欧几里得距离评价的计算公式要复杂。
它在数据不是很规范(如:影评者对影片的评价总是相对于平均水平偏离很大的时候),会倾向于给出更好的结果。

通过绘制一条最佳拟合线尽可能地靠近图上所有的坐标点。如果两位评论者对所有影片的评分情况都相同,那么这条直线将成为对角线,并与图上所有的坐标点都相交,从而得到一个结果为1的理想相关度评价。

对于下图,由于评论者对部分影片的评分不尽相同,因而相关系数大约为0.4左右
在这里插入图片描述
下图是一个相关度更高的例子,皮尔逊系数为0.75

在这里插入图片描述

该算法的好处:即使一个人一直倾向于给更低的分数(更加严格),直线也能拟合,表示两人的偏好相同的程度。

皮尔逊相关度评价算法:

  1. 找出两位评论者都曾评价过的物品
  2. 计算两者的评分总和与平方和
  3. 求得评分的乘积之和
  4. 利用这些计算结果计算出皮尔逊相关系数

写一个函数sim_pearson计算相关系数

#返回p1和p2的皮尔逊相关系数
def sim_pearson(prefs, p1, p2):    
	#得到双方都曾评价过的物体列表    
	si={}    
	for item in prefs[p1]:        
		if item in prefs[p2]:           
 			si[item]=1
 			
 	#得到列表元素的个数   
     n=len(si)
     
    #如果两者没有相似之处,则返回1    
    if len(si)==0: return 1  
              
    #对所有偏好求和    
    sum1=sum([prefs[p1][it] for it in si]) #加[]是为了把生成器类型转化为列表类型    
    sum2=sum([prefs[p2][it] for it in si])
    
    #求平方和    
    sum1sq=sum([pow(prefs[p1][it],2) for it in si])    
    sum2sq=sum([pow(prefs[p2][it],2) for it in si])
    
    #求乘积之和   
    psum=sum([prefs[p1][it]*prefs[p2][it] for it in si])
    
    #计算皮尔逊评价值   
    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

该函数返回一个介于-1 到 1 之间的数值。值为1 表示两个人对每一样物品均有完全一致的评价
与距离。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值