数据挖掘python学习——《写给程序员的数据挖掘实践指南》第2章

开发工具:pycharm

语言:python

所需资料:《写给程序员的数据挖掘实践指南》——书和代码包


第 2 章    协同过滤——爱你所爱


问题描述:每个用户对于一些乐队有一些评价,如何针对某一个用户对他进行乐队推荐。

解决思路:寻找与该用户最相似的用户(首先使用曼哈顿距离衡量两者之间的距离),根据最相似用户的评价结果进行推荐。


1. 表示表格中的数据




以前两列为例

users = { "Angelica": { "Blues Traveler": 3.5, "Broken Bells": 2, "Norah Jones": 4.5, "Phoenix": 5,
                        "Slightly Stoopid": 1.5, "The Strokes": 2.5, "Vampire Weekend": 2 },
          "Bill": { "Blues Traveler": 2, "Broken Bells": 3.5, "Deadmau5": 4, "Phoenix": 2,
                        "Slightly Stoopid": 3.5, "Vampire Weekend": 3 }}
print(users["Angelica"])


输出结果如下




2. 计算曼哈顿距离


公式理解:



因此,曼哈顿距离公式如下:



依据公式,书写曼哈顿距离计算函数

def manhattan (user1, user2):
    distance = 0
    for key in user1:
        if key in user2:
            distance += abs(user1[key] - user2[key])
    return distance

print(manhattan(users["Hailey"], users["Veronica"]))
print(manhattan(users["Hailey"], users["Jordyn"]))
ps:此处的数据与上表相同,数据录入代码从书本提供代码中获取。


输出如下:




3. 寻找最近的用户(按照相似度从高到低的次序返回用户列表)


def computeNearestNeighbor(username, users):
    distances = []
    for user in users:
        if user != username:
            distance = manhattan(users[user], users[username])
            distances.append((distance, user))

    distances.sort()
    return distances

print(computeNearestNeighbor("Hailey", users))

输出如下:



4. 根据最近用户的结果进行推荐


def recommend(username, users):

    nearest = computeNearestNeighbor(username, users)[0][1]
    recomendations = []
    neighborRatings = users[nearest]
    userRatings = users[username]
    for artist in neighborRatings:
        if not artist in userRatings:
            recomendations.append((artist, neighborRatings[artist]))

    return sorted(recomendations, key=lambda artistTuple: artistTuple[1], reverse=True)

print(recommend('Hailey', users))
print(recommend('Angelica', users))


首先利用前文中的函数找出用户最近的邻居,然后将最近邻居中评价过而用户没有评价过的乐队找出来,利用sorted函数进行排序。sorted函数与前面用于自身的sort函数不同,会返回排序后的列表而不改变列表本身。函数中key参数的含义是依据列表第二位的内容进行排序,而reverse为True则是逆反排序,由高到低。

输出结果如下:


从输出结果可以看出存在空推荐的情况,这是由于最近的邻居并没有评价过用户没有评价的乐队,下文将解决这一问题。



【习题1】

实现Minkowski函数


从上面的函数公式得到以下实现函数

def minkowski (user1, user2, r):
    distance = 0
    empty = True
    for key in user1:
        if key in user2:
            distance += pow(abs(user1[key] - user2[key]), r)
            empty = False
    if empty:
         return 0
    else:
        return pow(distance, 1/r)

这个函数可以完全代替前文中实现的曼哈顿距离的函数,将r传入为1即可。

这个函数的实现中学习到,开次方根的时候也可以用pow函数。


【习题2】

实现皮尔逊相关系数函数




这个函数需要对数据进行多变扫描,效率较低,因此皮尔逊相关系数的近似计算公式被提出,它能够通过但遍扫描得到结果,但是缺点是一些微小的错误可能会由于这个公式被放大。函数公式如下:



函数实现如下:

def pearson(user1, user2):
    n = 0
    sum_x = 0
    sum_y = 0
    sum_x2 = 0
    sum_y2 = 0
    sum_xy = 0
    for key in user1:
        if key in user2:
            n += 1
            sum_x += user1[key]
            sum_y += user2[key]
            sum_x2 += user1[key] ** 2
            sum_y2 += user2[key] ** 2
            sum_xy += user1[key] * user2[key]
    d = sqrt(sum_x2 - (sum_x ** 2) / n) * sqrt(sum_y2 - (sum_y ** 2) / n)
    if d == 0:
        return 0
    else:
        return (sum_xy - sum_x * sum_y / n) / d

print(pearson(users['Angelica'], users['Bill']))
print(pearson(users['Angelica'], users['Hailey']))
print(pearson(users['Angelica'], users['Jordyn']))

从函数代码中我们可以看出,经过一个for循环的扫描,即可得到结果。

输出结果如下:




5. 余弦相似度


在稠密数据集上,曼哈顿距离和欧式距离的效果都比较理想。但对于一些稀疏的数据集,在对缺失值没有较好处理的情况下,它们的评判结果可能不尽人意。在这种情况下,采用余弦相似度可能是更好的选择。


余弦相似度计算公式如下:



6. 实现推荐类


注意:文件录入时为左划线,直接复制的路径为右划线,不可直接粘贴使用。在路径的最后也要加入左划线,表示文件在该文件夹内。





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值