You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.5 KiB
5.5 KiB
8.3 动手实现Apriori
想要从数据中挖掘出关联规则,就需要先能够寻找频繁项集,所以首先我们可以实现一些用于寻找频繁项集的函数。
频繁项集来源于项集,所以首先需要构建只有一个元素的项集,再构建只有两个元素的项集,...,一直到有 K 个元素的项集。因此首先需要构建只有一个元素的项集,构建的函数实现如下:
# 构建只有一个元素的项集, 假设dataSet为[[1, 2], [0, 1]. [3, 4]]
# 那么该项集为frozenset({0}), frozenset({1}), frozenset({2}),frozenset({3}), frozenset({4})
def createC1(dataSet):
C1 = []
for transaction in dataSet:
for item in transaction:
if not [item] in C1:
C1.append([item])
C1.sort()
return map(frozenset, C1)
有了从无到有之后,接下来需要从 1 到 K。不过需要注意的是,这个时候需要排除掉支持度小于最小支持度的项集。代码实现如下:
# 从只有k个元素的项集,生成有k+1个元素的频繁项集,排除掉支持度小于最小支持度的项集
# D为数据集,ck为createC1的输出,minsupport为最小支持度
def scanD(D, ck, minsupport):
ssCnt = {}
for tid in D:
for can in ck:
if can.issubset(tid):
if not ssCnt.has_key(can):
ssCnt[can]=1
else:
ssCnt[can] +=1
numItems = float(len(D))
reList = []
supportData = {}
for key in ssCnt:
support = ssCnt[key]/numItems
if support >= minsupoort:
reList.insert(0, key)
supportData[key] = support
#reList为有k+1个元素的频繁项集,supportData为频繁项集对应的支持度
return reList, supportData
这就完了吗?还没有,我们还需要一个能够实现构建含有 K 个元素的频繁项集的函数。实现代码如下:
#构建含有k个元素的频繁项集
#如输入为{0},{1},{2}会生成{0,1},{0, 2},{1,2}
def aprioriGen(Lk, k):
retList = []
lenLk = len(LK)
for i in range(lenLk):
for j in range(i+1,lenKk):
L1 = list(Lk[i])[k:-2]
L2 = list(Lk[j])[:k-2]
if L1 == L2:
relist.append(Lk[i] | Lk[j])
return reList
有了以上的函数之后,我们就可以根据生成候选频繁项集的流程,使用这些函数来实现这个功能了。代码如下:
#生成候选的频繁项集列表,以及候选频繁项集的支持度,因为在算可信度时要用到
def apriori(dataSet, minsupport=0.5):
C1 = creatC1(dataSet)
D = map(set, dataSet)
L1, supportData = scanD(dataSet, C1, minsupport)
L = [L1]
k = 2
while (len(L[k-2])>0):
Ck = aprioriGen(L[k-2], k)
Lk, supK = scanD(D, Ck, minsupport)
supportData.update(supK)
L.append(Lk)
k += 1
# L为候选频繁项集列表,supportData为候选频繁项集的支持度
return L, supportData
有了候选频繁项集和它的支持度之后,就可以开始着手挖掘关联规则了。在挖掘关联规则时,需要排除可信度比较小的关联规则,所以首先需要实现计算关联规则的可信度的功能。代码实现如下:
# 计算关联规则的可信度,并排除可信度小于最小可信度的关联规则
# freqSet为频繁项集,H为规则右边可能出现的元素的集合,supportData为频繁项集的支持度,brl为存放关联规则的列表,minConf为最小可信度
def calcConf(freqSet, H, supportData, brl, minConf = 0.7):
prunedH = []
for conseq in H:
conf = supportData[freqSet]/supportData[freqSet - conseq]
if conf >= minConf:
brl.append((freqSet - conseq, conseq, conf))
prunedH.append(conseq)
return prunedH
接下来就需要实现从频繁项集中生成关联规则的功能了,若已经忘记了算法流程,可以翻看一下上一节的内容,实现如下:
# 从频繁项集中生成关联规则
# freqSet为频繁项集,H为规则右边可能出现的元素的集合,supportData为频繁项集的支持度,brl为存放关联规则的列表,minConf为最小可信度
def ruleFromConseq(freqSet, H, supportData, brl, minConf = 0.7):
m = len(H[0])
if len(freqSet) > m+1:
Hmp1 = aprioriGen(H, m+1)
Hmp1 = calcConf(freqSet, Hmp1, supporData, brl, minConf)
if len(Hmp1) > 1:
ruleFromConseq(freqSet, Hmp1, supportData, brl, minConf)
由于使用apriori
函数后得到的是一个候选频繁项集的列表,所以需要遍历整个候选频繁项集的列表来挖掘关联规则,所以代码实现如下:
# 从频繁项集中挖掘关联规则
# L为频繁项集, supportData为频繁项集的支持度,minConf为最小可信度
def generateRules(L, supportData, minConf = 0.7):
digRuleList = []
for i in range(1, len(L)):
# freqSet为含有i个元素的频繁项集
for freqSet in L[i]:
H1 = [frozenset([item]) for item in freqSet]
if i > 1:
# H1为关联规则右边的元素的集合
rulesFromConseq(freqSet, H1, supportData, digRuleList, minConf)
else:
calcConf(freqSet, H1, supportData, digRuleList, minConf)
return digRuleList
# 挖掘关联规则部分 End
到这里,我们已经实现了Apriori
算法和关联规则挖掘算法。接下来,将介绍如何使用刚刚实现的算法来挖掘毒蘑菇的共性特征。