您的位置:首页 > 编程语言 > Python开发

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

2017-09-02 22:33 836 查看
开发工具: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. 实现推荐类

注意:文件录入时为左划线,直接复制的路径为右划线,不可直接粘贴使用。在路径的最后也要加入左划线,表示文件在该文件夹内。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据挖掘 python