本人是python初学者,本系列用来熟悉python和记录学习点滴
【度量、参数、函数】『名词』▲注意
第二章:推荐算法
语言python
例子:电影推荐
思想:『协作性过滤』:对一大群人进行搜索,找出与我们品味相近的一小群人。对这些人偏爱的其他内容进行考察,将他们组合起来构造出一个经过排名的推荐列表。
步骤:
2『相似度系数』:用来确定与其他人评委的相似程度的度量。
常用两种度量:
①【欧几里得距离】:坐标系上两点之间的距离
pow(m,n) m的n次方 sqrt(m)m的平方根。/无须
sqrt(pow(a-b,2)+pow(c-d),2))空间(a,b)(c,d)上两点的距离。须from math import sqrt
距离越小,偏好越接近。不过为了使得总是返回0-1之间的值,并且值越大,偏好越接近。
在这里对距离进行处理1/(1+sqrt(pow(a-b,2)+pow(c-d),2))),+1并去倒数。
【函数】
def sim_distance(prefs,person1,pernson2):
si={}
for item in prefs[person1]:
if item in prefs[person2]:
si[item]=1
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]])
</pre><pre name="code" class="python"> return 1/(1+sum_of_squares)
▲如果一个人的评价始终比另一个人严格宽松,导致评价分苏偏高偏低,则欧几里得距离不再使用,下面的方法修正了这一点
②【皮尔逊相关系数】:与某一直线的拟合程度,数学上讲就是线性相关程度。是介于-1与1之间的数,1完全正相关,-1完全负相关。
如果一个人对不同电影打分总是比另一个人偏高,而二者的分值只差又始终保持一致。
反应在坐标系上,数据会拟合成一条直线。两个的分数的相关程度越高,说明两人仍有着相对近似的偏好。
公式:两个变量X、Y,那么两变量间的皮尔逊相关系数可通过以下公式计算
【函数】
def sim_pearson(prefs,p1,p2):
si={}
for item in prefs[p1]:
if item in prefs[p2]: si[item]=1
</pre><pre name="code" class="python"> if len(si)==0: return 0
</pre><pre name="code" class="python"> n=len(si)
#求和
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
</pre><pre name="code" class="python"> r=num/den
return r
③【其他度量】:jaccard系数、曼哈顿距离。
3.找到与自己品味相近的人,然后去看他的评论
【函数】
def topMatches(prefs,person,n=5,similarity=sim_pearson):
scores=[(similarity(prefs,person,other),other)
for other in prefs if other!=person]
scores.sort()
scores.reverse()
return scores[0:n]
返回相似性最高的前n项。
这里利用了python的列表推导式: 【 函数(表达式) for var in 序列(列表、字典) if condion】
功能是对一组元素进行条件过滤,并的过滤后的元素代入函数或者表达式进行变形,可省略if不进行过滤单独使用。
这里similarity用来选择一种系数,可以是任何一种系数的函数,只要他返回一个浮点数且数值越大,相似度越大。
4.推荐电影。
①如果一个趣味相投的人,还未对某些影片做过评论;或者他对于某一部影片及其热衷,而其他所有人的态度恰恰相反。
我们就需要考虑所有的人的评价,无论他是与我们趣味相投,还是相差甚远。
通过一个加权的评价值设计来解决这个问题。
加权后的评价值= 评价值*相似度系数 ,影片得分=加权评价值之和 / 相似度系数之和
【函数】
def getRecommendations(prefs,person,similarity=sim_pearson):
totals={}
simSums={}
for other in prefs:
# 不和自己比较
if other==person: continue
sim=similarity(prefs,person,other)
# 去掉评价0的情况
if sim<=0: continue
for item in prefs[other]:
# 只对自己没看过或评价为0的电影进行计算
if item not in prefs[person] or prefs[person][item]==0:
totals.setdefault(item,0)
totals[item]+=prefs[other][item]*sim
simSums.setdefault(item,0)
simSums[item]+=sim
rankings=[(total/simSums[item],item) for item,total in totals.items()]
rankings.sort()
rankings.reverse()
return rankings
【dict.setdefault(key,[default])】:如果键在字典中,返回这个键所对应的值。如果键不在字典中,向字典 中插入这个键,并且以default为这个键的值,并返回 default。default的默认值为None