集体智慧编程 读书笔记 二

还是第二章, 后面内容

        这部分讲了基于物品的协作过滤, 之前讲基于用户的协作过滤,  基于物品的协作过滤适用于大数据集, 因为我们可以体检对数据进行处理, 物品的变化很小,所以计算一次后,以后可以较少的修改,这部分内容比较简单,当有数据集后, 计算每种物品的topmatch 物品

def buildSimilarItems(prefs, n=10):
    result = {}
    itemPrefs = transformPrefs(prefs)
    c = 0
    for item in itemPrefs:
        c += 1
        print ("%d / %d" % (c,len(itemPrefs)))
        scores = topMatches(itemPrefs, item, n=n)
        result[item] = scores
    return result

构建好相似物品后, 就可以利用它为用户做推荐, 还是利用加权的方法, 文中方法比较简单就是用户的评分做权值, 乘以相似度,代码就不贴了, 很好写


然后书中提供了一个比较好的数据集,http://www.grouplens.org/node/73, 格式如下

movies.dat里包含的是电影信息, 包含电影id, name, 和类型, 数据用冒号分割

1::Toy Story (1995)::Adventure|Animation|Children|Comedy|Fantasy
2::Jumanji (1995)::Adventure|Children|Fantasy
3::Grumpier Old Men (1995)::Comedy|Romance


ratings.dat里包含的是评价信息, 有用户id, 电影id, 评分, 和时间戳, 也是冒号分割

1::122::5::838985046
1::185::5::838983525
1::231::5::838983392
1::292::5::838983421
1::316::5::838983392
1::329::5::838983392
1::355::5::838984474
1::356::5::838983653
1::362::5::838984885

所以首先构建书中之前代码能够处理的数据集格式, 代码如下:

def loadMovies(path='your own path'):
    count = 0
    movies = {}
    for line in open(path + '/movies.dat'):
        (id, title) = line.split('::')[0:2]
        movies[id] = title
    prefs = {}
    for line in open(path + '/ratings.dat'):
        count += 1
        if count > 100000: return prefs
        (user, movie, rating, ts) = line.split('::')
        prefs.setdefault(user, {})
        prefs[user][movies[movie]] = float(rating)
    return prefs

为了节省时间, 用count标识只处理10w行数据

有了数据集就可以验证之前的一些算法, 基于用户和物品的协作过滤了, 还发现了一个bug, 在上一篇文章里的 获取推荐的计算时, sim < 0  contiue, 改成 sim <=0 否则会出 divied by zero的错误


最后是习题:

第一个是 写tanimoto 分值的相似度计算方法, 


def sim_tanimoto(prefs, p1, p2):
    si = {}
    for item in prefs[p1]:
        if item in prefs[p2]:
            si[item] = 1
    length = len(si)
    if length == 0: return 0
    t = length/(len(prefs[p1]) + len(prefs[p2]) - length)
    return t

上面是集合的求法, 我觉得也可以用转换后的公式来求(不知道可以不)

def sim_tanimoto(prefs, p1, p2):
    si = {}
    for item in prefs[p1]:
        if item in prefs[p2]:
            si[item] = 1
    length = len(si)
    if length == 0: return 0
    # sum of multi
    sumMul = sum(prefs[p1][item] * prefs[p2][item] for item in si)
    # sum of pow
    sumPow1 = sum(pow(prefs[p1][item], 2) for item in si)
    sumPow2 = sum(pow(prefs[p2][item], 2) for item in si)
    #den
    den = sqrt(sumPow1) + sqrt(sumPow2) - sumMul

    t = sumMul/den
    return t

我觉得还是集合的方法靠谱, tanimoto系数适用于没有精确数值的情况, 比如存在为1不存在为0 所以第一个比较倾向的方法


第五题是构建一个音乐推荐系统。。。。 好大的题


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值