Apriori算法:
扫描一遍数据库,得到一阶频繁项
用一阶频繁项构造二阶候选项
扫描数据库对二阶候选项进行计数,删除其中的非频繁项,得到二阶频繁项
然后构造三阶候选项,以此类推,直到无法构造更高阶的候选项,或到达频繁项集的最大长度限制。
Apriori.py
# 构建初始候选项集
def createC1(dataSet):
C1 = []
for transaction in dataSet:
for item in transaction:
if [item] not in C1:
C1.append([item])
C1.sort()
return list(map(frozenset, C1))
# 计算并筛选Ck中的项集在数据集合D中的支持度
def scanD(D, Ck, minSupport):
ssCnt = {}
# 计算每个的出现次数
for tid in D:
for can in Ck:
if can.issubset(tid):
ssCnt[can] = ssCnt.get(can, 0) + 1
# 计算满足最小支持度的项集的集合和所有项集支持度信息的字典
numItems = len(D)
retList = []
supportData = {}
for key in ssCnt:
# 每个项集的支持度
support = float(ssCnt[key]) / numItems
# 将满足最小支持度的项集 加入retList
if support >= minSupport:
retList.append(key)
# 汇总支持度数据
supportData[key] = support
return retList, supportData
# 由初始候选项集的集合Lk生成新的候选项集 k表示生成的新项集中所含有的元素个数
def aprioriGen(Lk, k):
retList = []
lenLk = len(Lk)
for i in range(lenLk):
for j in range(i + 1, lenLk):
L1 = list(Lk[i])[:k - 2]
L2 = list(Lk[j])[:k - 2]
L1.sort()
L2.sort()
if L1 == L2:
retList.append(Lk[i] | Lk[j])
return retList
# Aprior算法
def apriori(dataSet, minSupport=0.5):
# 构建初始候选项集C1
C1 = createC1(dataSet)
D = list(map(set, dataSet))
# 构建初始的频繁项集 即所有项集只有一个元素
L, suppData = scanD(D, C1, minSupport)
L = [L]
k = 2
# 最初的L中的每个项集含有一个元素 新生成的项集每个项集应该依次多一个元素
while (len(L) > k - 2):
Ck = aprioriGen(L[k - 2], k)
Lk, supK = scanD(D, Ck, minSupport)
# 将新的项集的支持度数据加入原来的总支持度字典中
suppData.update(supK)
# 将符合最小支持度要求的项集加入L
if len(Lk) > 0:
L.append(Lk)
# 新生成的项集中的元素个数应不断增加
k += 1
# 返回所有满足条件的频繁项集的列表,和所有候选项集的支持度信息
return L, suppData
# 规则生成与评价
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
# 对频繁项集中元素超过2的项集进行合并
def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):
m = len(H[0])
# 查看频繁项集是否大到移除大小为m的子集
if len(freqSet) > m + 1:
# 生产大小大一的子集
Hmp = aprioriGen(H, m + 1)
# 如果不止一条规则满足要求 进一步递归合并
Hmp = calcConf(freqSet, Hmp, supportData, brl, minConf)
if len(Hmp) > 1:
rulesFromConseq(freqSet, Hmp, supportData, brl, minConf)
# 根据频繁项集L和所有项集的支持度supportData和最小可信度来生成规则
def generateRules(L, supportData, minConf=0.7):
bigRuleList = []
for i in range(1, len(L)):
for freqSet in L[i]:
H = [frozenset([item]) for item in freqSet]
# 如果频繁项集中的元素个数大于2 需要进一步合并
if i > 1:
rulesFromConseq(freqSet, H, supportData, bigRuleList, minConf)
else:
calcConf(freqSet, H, supportData, bigRuleList, minConf)
return bigRuleList
def main():
# 创建数据集
def loadDataSet():
return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
myData = loadDataSet()
L, suppData = apriori(myData, 0.5)
print('频繁项集:', L)
print('所有候选项集的支持度信息:')
for data in suppData:
print(data, ' : ', suppData[data])
rules = generateRules(L, suppData, 0.5)
print('生成规则:')
for rule in rules:
print(rule[0], ' --> ', rule[1], ' : ', rule[2])
if __name__ == '__main__':
exit(main())
输出结果:
频繁项集: [[frozenset({1}), frozenset({3}), frozenset({2}), frozenset({5})], [frozenset({1, 3}), frozenset({2, 3}), frozenset({3, 5}), frozenset({2, 5})], [frozenset({2, 3, 5})]]
所有候选项集的支持度信息:
frozenset({1}) : 0.5
frozenset({3}) : 0.75
frozenset({4}) : 0.25
frozenset({2}) : 0.75
frozenset({5}) : 0.75
frozenset({1, 3}) : 0.5
frozenset({2, 3}) : 0.5
frozenset({3, 5}) : 0.5
frozenset({2, 5}) : 0.75
frozenset({1, 2}) : 0.25
frozenset({1, 5}) : 0.25
frozenset({2, 3, 5}) : 0.5
生成规则:
frozenset({3}) --> frozenset({1}) : 0.6666666666666666
frozenset({1}) --> frozenset({3}) : 1.0
frozenset({3}) --> frozenset({2}) : 0.6666666666666666
frozenset({2}) --> frozenset({3}) : 0.6666666666666666
frozenset({5}) --> frozenset({3}) : 0.6666666666666666
frozenset({3}) --> frozenset({5}) : 0.6666666666666666
frozenset({5}) --> frozenset({2}) : 1.0
frozenset({2}) --> frozenset({5}) : 1.0
frozenset({5}) --> frozenset({2, 3}) : 0.6666666666666666
frozenset({3}) --> frozenset({2, 5}) : 0.6666666666666666
frozenset({2}) --> frozenset({3, 5}) : 0.6666666666666666