文章目录
使用Apriori算法来发现频繁集
支持度:某一项集的记录在数据集所占的比例
可信度:某一项集包含的细分项集的比例
如何找到支持度大于0.8的所有项集?
首先自建一个简单的数据集,构建两个辅助函数,createc1函数用来构建不变集合,scand函数扫描数据集,计算出现频数和支持度。
def loaddata():
return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]]
def createc1(dataset):
c1 = []
for tran in dataset:
for item in tran:
if not [item] in c1:
c1.append([item])
c1.sort()
#print(c1)
return list(map(frozenset,c1))#返回frozenset的列表
def scand(D,Ck,sup):
cnt={}
for tid in D:
for can in Ck:
if can.issubset(tid):#issubset()判断can是否是tid的子集
if not can in cnt: cnt[can]=1
else: cnt[can] += 1
numitems = float(len(D))
retlist = []
supdata = {}
for key,value in cnt.items():
support = value/numitems
if support>=sup:
retlist.insert(0,key)
supdata[key]=support
return retlist,supdata
接下来组建完整的Apriori算法,这里包含主函数apriori和辅助函数genc,genc输入Ck-1和k,生成集合的组合Ck,这里采用的一个比较神奇的方式,比较集合的前k-2个元素,如果相等,那么就将这两个集合求并集。这里我们举个例子来看下假如Ck-1集合的元素为{0,1},{0,2},{1,2},我们要创建三元素项集,这里k=3,取前k-2个元素也就是只取第一个元素0是相同的,那么我们对前俩个取并集,获得{0,1,2},这样就不需要遍历列表寻找非重复值。
def genc(Lk,k):#create Ck Lk=Lk-1
retlist = []
lenlk = len(Lk)
for i in range(lenlk):
for j in range(i+1,lenlk):
L1=list(Lk[i])[:k-2]# start from k=2 L1=[] k=3 L1= [one element]
L2=list(Lk[j])[:k-2]# if the first just(k-2) is same, then |
L1.sort()
L2.sort()
if L1==L2:
retlist.append(Lk[i] | Lk[j])
return retlist
def apriori(data,minsup=0.5):
C1 = createc1(data)
D = list(map(set,data))
L1,supdata = scand(D,C1,minsup)
L = [L1]# a list that L[0] = L1
k=2
while (len(L[k-2])>0):#while Ck=[] break
Ck = genc(L[k-2],k)#L is list of Lk
print(Ck)
Lk,supK = scand(D,Ck,minsup)
supdata.update(supK)# put dict supK into supdata
L.append(Lk)
print(L)
k +=1
print(k)
return L,supdata
关联规则生成
关联规则生成函数
从一个频繁项开始,首先创建规则右部只有一个元素的规则列表进行测试,接下来合并所有剩余规则来创建一个新的规则列表,规则右部包含两个元素。
这里基本重点代码处都写了注释,就不在一一列举了,按照例子来理解会更容易些,genru生成规则函数在i大于1时会调用ruconseq函数,i等于调用calcconf函数,而i的值关系到L[i]中的元素个数,L[1]的元素个数为2
def genru(L,supdata,minconf=0.7):
rulist = []
for i in range(1,len(L)):
for freqset in L[i]:# for exam:freqset=frozenset({2, 5})
H1 = [frozenset([item]) for item in freqset]
print(H1)
if (i>1):# more than two element
ruconseq(freqset,H1,supdata,rulist,minconf)
else:
calcconf(freqset,H1,supdata,rulist,minconf)#freqset=frozenset({2, 3, 5})
return rulist
def calcconf(freqset,H,supdata,br1,minconf=0.7):#for exam:freqset=frozenset({2, 5}) H=[frozenset({2}),frozenset({5})]
pru=[]
for conseq in H:
conf = supdata[freqset]/supdata[freqset-conseq]#frozenset({2, 5})/frozenset({2, 5})-H[0] or frozenset({2, 5})-H[1]
if conf >= minconf:
print(freqset-conseq,'--->',conseq,'conf',conf)#frozenset({2, 5})-frozenset({2})--->frozenset({2})
br1.append((freqset-conseq,conseq,conf))# record the revelance
pru.append(conseq)
return pru# for judge to stop cycle
def ruconseq(freqset,H,supdata,br1,minconf=0.7):
m = len(H[0])#H = [frozenset({2}),frozenset({3}),frozenset({5})]
if len(freqset) > (m+1):
hmp1 = genc(H,m+1)
hmp1 = calcconf(freqset,hmp1,supdata,br1,minconf)
if len(hmp1) > 1:#cycle when hmp1 is [] break
ruconseq(freqset,hmp1,supdata,br1,minconf)
未完待续…