CH02:提供推荐

有关推荐问题:

目标输出:我想得到一个长串,里面既有与这个人评分较高(即相似度较高)的人的名字,也有他的得分,应该用Python里的什么结构?

Q:一个列表也好,一个字典也好,不定义可以直接用吗?

A:不可以。一个字符在不定义的时候可以直接用(for item in ...)并没有定义item,直接拿来用就好 item可以是数字,可以是名称字符,方便直接

但是,在用列表和字典的时候,一定要先定义一个 比如 score=【】 或者score={}


Q:如果用一个列表list [],我想添加元素 怎么加?

A:先写一个空score=【】,然后score.append(XXX),其中XXX是你想添加的东西,XXX可以也是一个列表【】,也可以是一个元组(),根据你自己而定。

Q:如果用一个字典dict{},我想添加元素,怎么办?

A:先写一个空的字典score={},然后直接写键和键值就可以,添加key的时候记得用中括号,score【'Liza Rose'】=3.95 即可,它会自动给你一个一个添加(对么)。但是,当输出list的时候,一般情况下只能输出value,如果想把key和value同时输出,需要把它们变成一个元组tuple,然后输出(没试,待检验)


推荐系统的两种状况:

1.我是一个人,O是另外一个人

这个人和我很像,我们都给电影A打高分,都给电影B打低分。

这个人还看过【我没看过的】CDEF电影,那么,我根据这个人的口味 给我推荐电影CDEF

简化:给我推荐另一部电影

2.我是一个电影,△是另外一个电影

我们两部电影很像,有许多人,给我打高分的同时都给△打高分。

那么,看过△的(没看过本电影)的人有XYZ,我根据电影的相似度,给XYZ推荐本电影。

简化:给这部电影推荐其他的人(来看来买)

理论意义:在线零售商会收集人们的购买历史(看电影历史),找到购买某些商品(电影)的潜在客户。对于市场营销的规划,很有意义

给一个人推荐1w个电影,和把一个商品推荐给1w个人,哪个更有商业意义?显然是第二个。也就是第二个方法。


#coding=utf-8
from math import sqrt
# 定义distance,输入两个人 算出他们“共有”的某几项之间的距离
def sim_distance(prefs,person1,person2):
    si={}
    a=0
    for item in prefs[person1]:
        if item in prefs[person2]:
            si[item]=1
    if len(si)==0:
        print'no simulation'
    for item in prefs[person1]:
        if item in prefs[person2]:
            a =a + pow(prefs[person1][item]-prefs[person2][item],2)
    print 1/(1+sqrt(a))

# 定义pearson相关系数的求法 输入两个人 算出他们俩“共有”的某几项的相关系数
# 输入:数据集,第一个人(list型,电影名,打分),第二个人
# 输出:他们俩的相关系数,一个值
def sim_pearson(prefs,person1,person2):
    si = {}
    for item in prefs[person1]:
        if item in prefs[person2]:
            si[item] =1
    l=len(si)
    sum1 = sum([prefs[person1][item] for item in si]) # 求xi求和
    sum2 = sum([prefs[person2][item] for item in si]) 
    sum1sq = sum([pow(prefs[person1][item],2) for item in si]) # 求xi平方的和
    sum2sq = sum([pow(prefs[person2][item],2) for item in si])
    psum = sum([prefs[person1][item]*prefs[person2][item] for item in si]) #求xiyi乘积的和

    a = psum - (sum1*sum2/l)  #这三行是pearson相关系数的公式
    b = sqrt((sum1sq-pow(sum1,2)/l)*(sum2sq-pow(sum2,2)/l))
    r = a/b
    return r

# 为其余评论者打分,计算与某一评论者最相像的前n个人,得分可选为pearson或distance
def topMatches(prefs,person):
    scores = [] #我觉得这里变成一个字典会更好。待尝试
    for other in prefs:
        if other!=person:  #除了我要比较之外的所有人,都计算一下pearson
            scores.append([sim_pearson(prefs,person,other),other]) 
    scores.sort() #不太理解,scores是按啥排的啊?我的scores是一个二维的列表啊,按哪个维度排的
    scores.reverse()
    return scores[0:5]

#输入:数据集,待推荐的人,【使用的方法】
#输出:一个评分list:rankings,里面有电影名和电影的综合评分()

def getRecommendations(prefs,person):
    totals={}   #需要建立一个
    simSums={}
    for other in prefs: #第一步,在数据集的人里面找其他人
        if other != person: #找到之后,找其他人里有A没看过的电影
            for item in prefs[other]:
                if item not in prefs[person] or prefs[person][item]==0:  #这地方很重要!找A没看过的电影,我最开始的想法是C语言一样写一个循环查找,殊不知Python的好处就是可以直接查找
                    totals.setdefault(item,0) #找到了这部电影,先加入total里,键是电影名,键值先设置为0
                    totals[item]+= sim_pearson(prefs,person,other)*prefs[other][item] #相关系数乘以打分
                    simSums.setdefault(item,0)
                    simSums[item]+=sim_pearson(prefs,person,other)
    rankings=[]
    for item in totals:
        rankings.append((totals[item]/simSums[item],item))
    
    rankings.sort()
    rankings.reverse()
    return rankings                    
#评价:这地方,在原代码上加了一个对相关系数的判断,小于0的不介入调查。【当然,也可以自己设定为相关性小于多少的不予判别】

#输入:一个数据集
#输出:把里面的人换为电影
def transformPrefs(prefs):
    result={}
    for person in prefs:
        for item in prefs[person]:
            result.setdefault(item,{}) #此时定义了result字典里的外层:key是项也就是电影,value是又一个字典
            result[item][person]=prefs[person][item]#在这里定义第二个字典,即result[item]里的键是person,value是prefs里两层字典的值【也就是打分】
    return result


def calculateSimilarItems(prefs):
    result={}
    itemPrefs = transformPrefs(prefs)
    for item in itemPrefs:
        scores=topMatches(itemPrefs,item)
        result[item]=scores
    return result




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值