赞
踩
这次,我想给大家展示一个推荐系统中的贝叶斯算法的实现。这个项目非常接近实际。在解决问题的同时,大家如果仔细看懂这个小项目,以及贝叶斯算法,想必会觉得非常有趣。
这次,只有一个项目,希望能把问题看懂,以及贝叶斯分类是怎么进行的。把这两步弄明白,然后自己可以尝试自己写代码,实现这一算法。如果自己写不出来,再看我自己写的。这些东西对大家以后做推荐系统应该是入门,很有帮助的。
项目背景:
目前,有五个用户a、b、c、d、e。有五部电影x1、x2、x3、x4、x5。
已知b、c、d、e四个人对x1、x2、x3、x4、x5的评分:
{'b': {'x1': 2, 'x2': 4, 'x3': 2, 'x4': 4, 'x5': 2},
'c': {'x1': 3, 'x2': 1, 'x3': 4, 'x4': 3, 'x5': 2},
'd': {'x1': 5, 'x2': 1, 'x3': 1, 'x4': 1, 'x5': 2},
'e': {'x1': 3, 'x2': 3, 'x3': 1, 'x4': 5, 'x5': 3}}
同时,只知道a对x2、x3、x4、x5的评分:[3, 4, 3, 3]。
试求a对x1最有可能评分是多少?
数学过程:
贝叶斯分类借助的公式为:P(B│A)=(P(A|B)×P(B))/(P(A))。。。大学数学有讲这个公式。其中, ( )是指评分1-5的概率, ( )是贝叶斯分类的常量。尤其需要注意的是:贝叶斯分类是求其相关关系, 也就是比较概率大小,判断评分是几概率最大。而P(A)是目标用户的特征概率,这在所有贝叶斯公式中都是一样的,故可以舍去。
那么,贝叶斯分类化简后的公式为:P(B│A)=P(A|B)×P(B)。。。。如果不明白,看下面结合该项目就能能理解。
①首先,P(B│A)就是我们的目的,大家可以先看这个,然后就知道为什么定义下面的条件概率。这就是从目的推导条件概率的设置情况。
P(B│A)= ( _x1=1│ _x2=3、 _x3=4、 _x4=3、 _x5=3)、
( _x1=2│ _x2=3、 _x3=4、 _x4=3、 _x5=3)、
( _x1=3│ _x2=3、 _x3=4、 _x4=3、 _x5=3)、
( _x1=4│ _x2=3、 _x3=4、 _x4=3、 _x5=3)、
( _x1=5│ _x2=3、 _x3=4、 _x4=3、 _x5=3)。指的是在已知用户评分的条件下,推导出用户对x1的评分。我们的目的就是比较这几个概率哪个大,哪个就是可能评分。
那么根据,这个目的公式,就可以推导出P(B)、P(A|B)的具体形式了。
②然后,P(B)= ( _x1=1)、 ( _x1=2)、 ( _x1=3)、 ( _x1=4)、 ( _x1=5)也就是用户a对x1的所有可能评分概率。
P(A|B)= ( _x2=3、 _x3=4、 _x4=3、 _x5=3│ _x1=1)、
( _x2=3、 _x3=4、 _x4=3、 _x5=3│ _x1=2)、、
( _x2=3、 _x3=4、 _x4=5、 _x5=3│ _x1=3)、
( _x2=3、 _x3=4、 _x4=3、 _x5=3│ _x1=4)、
( _x2=3、 _x3=4、 _x4=3、 _x5=3│ _x1=5)这是对应评分的五中情况。
③最后,由于对x2、x3、x4、x5的评分是相互独立的,那么可以对条件概率进行拆分。
这里举一个若是评分为1(也就是B=1)例子:P(A|B)= ( _x2=3、 _x3=4、 _x4=3、 _x5=3、│ _x1=1)可以拆分分子成概率相乘的形式,如下:= ( _x2=3│ _x1=1)× ( _x3=4│ _x1=1) × ( _x4=3│ _x1=1) × ( _x5=3│ _x1=1)
④以上部分,所有可能对x1的评分,用表格表示为:
那么根据公式:P(B│A)=P(A|B)×P(B),可以分别求出P(B│A)分别为0,0,1/32,0,0。所以用户a对x1的评分最有可能的是3,概率为1/32。
代码的实现:
这些代码巧妙的利用了数据框[]中可以加入判断的条件,例如:df['x1'][df['x1'] == 1],先是df['x1']取出特定的一段序列Series,后面的那个中括号是条件产生布尔值,两者结合就可以满足条件的序列,然后就可以进行计数求概率。
import pandas as pd
data = {'b': {'x1': 2, 'x2': 4, 'x3': 2, 'x4': 4, 'x5': 2},
'c': {'x1': 3, 'x2': 1, 'x3': 4, 'x4': 3, 'x5': 2},
'd': {'x1': 5, 'x2': 1, 'x3': 1, 'x4': 1, 'x5': 2},
'e': {'x1': 3, 'x2': 3, 'x3': 1, 'x4': 5, 'x5': 3}}
df = pd.DataFrame(data).T
# 记录 ( │ )× ( )的结果,也就是记录各个评分的概率
list1 = []
# 已知的目标用户对其他影片的评分
known_scores = [3, 4, 3, 3]
# 用户的可能评分用n表示,记住循环求出每一个可能评分下的 ( │ )和 ( )
for n in range(1, 6):
# 初始化 ( │ )的概率,用b代表
b = 1
# 将评分数据框的columns提取出来
# 只用df.columns不行,它是个伪列表,虽然能用遍历,但是不能用del删除数据
movie_columns = list(df.columns)
# 剔除需要预测的电影,剩下全部已知评分的电影
del movie_columns[0]
# 求出每一个循环中的 ( )
p1 = df['x1'][df['x1'] == n].count() / df['x1'].count()
# 用df1代表:满足( =n)条件下的矩阵,用以判断各个 ( │ )
df1 = df[df['x1'] == n]
# 如果p1=0, ( │ )× ( )直接赋予0,且这样为求条件概率避免分母为0
if p1 != 0:
# i为已知评分的电影名,j是对应电影的评分,用zip()函数实现同步
for i, j in zip(movie_columns, known_scores):
# 在X1评分为n的条件下,x2评分分别为j的概率相乘
# 用p2表示每一个 ( =j│ )
p2 = df1[df1[i] == j][i].count()/df1[i].count()
b *= p2
# 这里b*p2,便实现了评分为n下的 ( │ )× ( )
b *= p1
else:
b = 0
# 收集所有可能评分下的 ( │ )× ( )
print('目标用户a对x1的评分为'+str(n)+'时,对应的概率为'+str(b)+'。')
list1.append({n: b})
print('汇总后的评分和其对应的概率:'+str(list1))
虽然这个小项目看起来特别枯燥,但是很通俗易懂,这样大家也许会明白,为什么打开视频播放器总会给我们推荐我们喜欢的视频,当然推荐系统还有很多算法,慢慢学习。
如果有错误的解释,请大家指出,但是也不能忘记关注一波哈哈哈
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。