apriori算法是一种典型的关联规则挖掘算法,apriori算法总结
环境
Python版本:3.5
数据源
分享来自51CTO网站的数据,点击此处下载
关联规则
关联规则是指现实中同时发生的两件不同事物之间的关联程度。具体分析可以参考这篇博客,清晰明了。
数据分析
这是一个数据文件。
数据文件
电影中电影信息的内容如图。
电影. dat
每行都是电影id、电影名称和电影类别,用:Rating.dat是收集的用户评分记录,users.dat是用户id对应的用户信息,personalRating.txt是个人评分,用于找到规律后向个人推荐电影。等级
评级. dat
有用户id,电影id,评分(1-5分,评分时间,总计100多万行数据。我喜欢定3分以上的分数。最小支持度为0.2,最小可靠度为0.5。代码实现如下
#-*-编码:utf-8-*-
应用程序执行。
创建于10月26日13360093360032536
@作者:FWW
导入时间
DEFC1(数据):
创建初始候选集列表。这意味着所有候选集只包含一个元素。
C1是所有大小为1的候选集合的集合。
C1=[]
对于数据集中的事务:
对于交易中的项目:
如果[项目]不在C1:
C1.append ([ item])。
C1.sort().
返回列表(映射(冻结集,C1))
defscand(d,Ck,minSupport):
计算事务集D的每个事务对Ck的项集的支持度,选择,
返回满足最小支持度的项目集集合以及所有项目集的支持度信息字典。
ssCnt={}
对于D中的tid:
#关于所有翻译
对于Ck中的can:
#检查每个候选集合是否可以是传输的一部分
#也就是说,这个候选人是否能得到交易的支持?
ifcan.issubset(tid):
scnt[can]=sscnt.get(can,0 ) 1
numitems=float(Len(d)))))))))))).
retList=[]
supportData={}
对于ssCnt中的键:
#对每个项目集的支持程度
support=ssCnt[ key ]/numItems
#将满足最低支持的项目集添加到retList
如果支持=最小支持:
retlist.insert(0,key)).
#总结支持数据
support data[key]=支持
返回列表,支持数据
# Aprior算法
defapriorigen(LK,k):
根据初始候选集合Lk,
k表示包含在生成的新项目集中的元素的数量。
retList=[]
lenlk=len(lk))
forIinrange(lenlk):
福金兰奇(I1,伦克) :
L1=list(lk[I])[:k-2];
L2=list(lk[j])[:k-2];
L1 . sort(;L2.sort()。
如果L1==L2:
retlist.append(lk[I]lk[j]))
返回列表
默认先验(数据集,minSupport=0.5):
#构建初始候选集C1
C1=创建C1(数据集) )
#开放数据集
,以满足scanD的格式要求。
D=列表(映射(集合,数据集))
#建立一个初始频繁项集,即所有项集只有一个元素
L1,suppData=scanD( D,C1,minSupport)
L=[ L1 ]
#原始L1中的每个项集包含一个元素,新生成的
#项目集应包含2个元素,因此k=2
k=2
while ( len( L[ k - 2 ] ) 0):
Ck=aprioriGen( L[ k - 2 ],k)
Lk,supK=scanD( D,Ck,minSupport)
#将新项目集的支持数据添加到原始总支持字典中。
suppData.update( supK)
#将满足最低支持要求的项集添加到l。
附加(Lk)
#新生成的项集中的元素数量应该不断增加。
k=1
#返回满足条件的所有频繁项集的列表,以及所有候选项集的支持度信息。
返回L,suppData
def calcConf( freqSet,H,supportData,brl,minConf=0.5):
计算规则的可信度,并返回满足最低可信度的规则。
FreqSet(frozenset):频繁项目集
H(frozenset):频繁项目集中的所有元素。
数据(DIC):频繁项集中所有元素的支持度。
Brl(tuple):满足可信度条件的关联规则。
MinConf(float):最低可信度
prunedH=[]
对于H中的conseq:
conf=support data[freq set]/support data[freq set-conseq]
如果conf=minConf:
#print (freqSet - conseq,-,conseq, conf:,conf)
brl.append( ( freqSet - conseq,conseq,conf))
prunedH.append( conseq)
返回prunedH
def rulesFromConseq( freqSet,H,supportData,brl,minConf=0.5):
对频繁项集中元素超过2的项集进行合并。
频率集(冷冻集):频繁项集
h(冷冻集):频繁项集中的所有元素,即可以出现在规则右部的元素
支持数据(字典):所有项集的支持度信息
brl(元组):生成的规则
m=len( H[ 0 ])
如果m==1:
calcConf(频率集,H,支持数据,brl,minConf)
# 查看频繁项集是否大到移除大小为m的子集
如果len(频率集)米^ 1:
Hmp1=aprioriGen( H,m 1)
Hmp1=calcConf( freqSet,Hmp1,supportData,brl,minConf)
# 如果不止一条规则满足要求,进一步递归合并
如果len( Hmp1 ) 1:
rulesFromConseq( freqSet,Hmp1,supportData,brl,minConf)
定义推荐的电影(规则、个人列表、电影列表):
recommend_list=[]
sup_list=[]
对于规则中的规则:
如果规则[0]=个人列表:
对于规则[1]中的电影:
如果电影列表[电影-1]不在推荐列表中:
推荐_列表。追加(电影_列表[电影-1])
sup_list.append(规则[2])
对于推荐列表中的推荐:
i=recommend_list.index(推荐)
打印(推荐你看,推荐,,,round(sup_list[i]*100,2), %和你差不多的人都喜欢!)
def生成器规则(L,supportData,minConf=0.5):
根据频繁项集和最小可信度生成规则。
l(列表):存储频繁项集
支持数据(字典):存储着所有项集(不仅仅是频繁项集)的支持度
minConf(浮点型):最小可信度
bigRuleList=[]
对于范围(1,len( L))中的我:
对于L[ i ]中的频率集:
# 对于每一个频繁项集的集合频率集
H1=[频率集中项目的frozenset([item])]
# 如果频繁项集中的元素个数大于2,需要进一步合并
如果我1:
rulesFromConseq(频率集、H1、支持数据,大规则列表,最小配置)
否则:
calcConf(频率集、H1、支持数据,大规则列表,最小配置)
返回大规则列表
if __name__==__main__ :
# 导入数据集
start_time=time.time()
file_object=open(ratings.dat )
movies_object=open(movies.dat )
personal _ object=open(个人评级。txt’)
file_list=[]
尝试:
all_the_text=file_object.read()
origin _ list=(行。all _ the _ text中第行的split(:)。拆分( n ))
tem_list=[]
对于来源_列表中的行:
如果len(文件列表)
文件列表附加(项目列表)
tem_list=[]
否则:
if int(line[2])3:
tem_list.append(int(line[1]))
movies_text=movies_object.read()
movies_list=[]
对于电影_文字。split( n )(for line in(line。拆分(:)中的项目:
如果项目[1]不在电影_列表中:
电影_列表.追加(项目[1])
个人文本=个人对象。阅读()
personal_list=[]
对于personal_text.split(n ))中的行的(line.split(:)中的项目:
if int(item[2])3:
个人_列表。append(int(item[1]))
最后:
file_object.close()
movies_object.close()
个人_对象。关闭()
打印(读取文件成功in ,time.time()-start_time, s )
# 选择频繁项集
l,suppData=apriori( file_list,0.2)
rules=generateRules( L,suppData,minConf=0.5)
#打印(规则:n ,规则)
打印(计算规则成功时间,time.time()-start_time, s )
推荐电影(规则、frozenset(个人列表)、电影列表)
打印(程序完成时间,time.time()-start_time, s )
运行结果
2017-11-05 14-53-20屏幕截图100 . png
读文件用了1.3秒,运行花了14秒,相信之后用数组数组改进一下运行速度会更快