mushroom.dat
1 3 9 13 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 107 113
2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114
2 4 9 15 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 108 115
1 3 10 15 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 98 107 113
2 3 9 16 24 28 34 37 39 40 53 54 59 63 67 76 85 86 90 94 99 109 114
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76 85 86 90 93 98 108 114
2 4 9 15 23 26 34 36 39 42 52 55 59 63 67 76 85 86 90 93 98 108 115
2 4 10 15 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 107 115
1 3 10 15 23 25 34 36 38 43 52 54 59 63 67 76 85 86 90 93 98 110 114
2 4 9 14 23 26 34 36 39 42 52 55 59 63 67 76 85 86 90 93 98 107 115
2 3 10 14 23 27 34 36 39 42 52 55 59 63 67 76 85 86 90 93 99 108 114
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76 85 86 90 93 98 107 115
2 4 9 14 23 26 34 36 39 44 52 55 59 63 67 76 85 86 90 93 99 107 114
1 3 10 15 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 99 110 113
2 3 11 13 24 28 34 37 39 41 53 54 59 64 67 76 85 86 90 94 98 109 114
2 5 11 16 24 28 34 36 38 40 52 54 59 63 67 76 85 86 90 93 99 111 113
2 6 11 15 24 28 34 37 39 40 53 54 59 63 67 76 85 86 90 94 99 109 114
1 3 9 13 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 98 107 114
1 3 10 15 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 99 107 113
1 3 9 13 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 99 107 113
2 4 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 107 115
1 3 10 13 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 99 110 114
2 4 10 14 23 27 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 107 115
2 4 10 15 23 26 34 36 39 44 52 55 59 63 67 76 85 86 90 93 99 108 115
2 4 9 15 23 27 34 36 39 42 52 55 59 63 67 76 85 86 90 93 98 107 115
1 6 9 15 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 99 110 114
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 108 115
2 3 10 15 23 27 34 36 39 44 52 55 59 63 67 76 85 86 90 93 99 108 115
2 6 11 13 24 28 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 111 113
2 3 9 14 23 26 34 37 38 41 53 56 59 63 67 76 85 86 90 93 99 110 116
2 4 9 14 23 27 34 36 39 42 52 55 59 63 67 76 85 86 90 93 99 108 115
1 3 10 15 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 99 107 113
2 3 10 14 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 108 115
2 3 10 13 23 27 34 36 39 43 52 57 59 65 67 76 85 86 90 93 99 111 117
2 4 10 14 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 107 115
2 3 11 14 23 27 34 37 38 44 53 56 59 63 67 76 85 86 90 93 99 110 116
2 5 11 16 24 28 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 110 113
1 3 10 13 23 25 34 36 38 44 52 54 59 63 67 76 85 86 90 93 99 107 113
2 3 11 14 23 26 34 37 38 43 53 56 59 63 67 76 85 86 90 93 99 110 116
2 4 9 14 23 27 34 36 39 40 52 55 59 63 67 76 85 86 90 93 98 107 115
#-*- coding: utf-8 -*-
from numpy import *
#生成原始数据,用于测试
def loadDataSet():
return [[1, 3, 4],
[2, 3, 5],
[1, 2, 3, 5],
[1, 2, 3, 4,5],
[2, 5]]
# return [['A', 'C', 'D'],
# ['B', 'C', 'E'],
# ['A', 'B', 'C', 'E'],
# ['B', 'E'],
# ['A', 'B', 'C','D', 'E'],
# ['A', 'B', 'C','E', 'F']]
# return [[1, 3, 4],
# [2, 3, 5],
# [1, 2, 3, 5],
# [2, 5]]
# return [[1,2,3,4],
# [2,5,4,6],
# [1,3,6],
# [1,2,3,5,4,6],
# [2,3,4],
# [2,3,6],
# [1,3,4],
# [1,2,3,7,4],
# [1,2,7,4]]
# return [[1,2,3,4],
# [2,5,4,6],
# [1,3,5,6],
# [1,2,3,5,6],
# [2,3,4,5,6],
# [2,3,4],
# [2,3,6],
# [1,3,4]]
#遍历数据集每项交易记录,建立候选1-项集
def createC1(dataSet):
#记录每项物品的列表
C1 = []
#遍历每条记录
for transaction in dataSet:
#遍历每条记录中的物品
for item in transaction:
#判断如果该物品没在列表中
if not [item] in C1:
#将该物品加入到列表中
C1.append([item])
#对所有物品进行排序
C1.sort()
#frozenset数据类型,指被冰冻的集合
#集合一旦完全建立,就不能被修改
return map(frozenset, C1)
#输入:数据集D、候选集Ck、最小支持度
#用最小支持度minSupport对候选集Ck过滤
#输出:本层(第k层)的频繁项集Lk,Ck中的每项的支持度
def scanD(D, Ck, minSupport):
#建立字典<key,value>
#key-->候选集Ck中的每项
#value-->该项在所有记录中出现的次数
ssCnt = {}
#遍历数据库D的每条记录
for tid in D:
#遍历候选集Ck中的每一项
for can in Ck:
#如果候选集Ck中该项在原数据库某条记录中出现
if can.issubset(tid):
#如果选集Ck中该项第一次被统计到,次数记为1
if not ssCnt.has_key(can): ssCnt[can]=1
#否则次数累加
else: ssCnt[can] += 1
#数据库D的总商品购买记录总数,用于计算支持度
numItems = float(len(D))
#记录经最小支持度过滤后的频繁项集
retList = []
#记录候选集中满足条件的项的支持度<key,value>结构
#key-->候选集中满足条件的项
#value-->该项支持度
supportData = {}
#遍历候选集中的每项出现次数
for key in ssCnt:
#计算每项的支持度
support = ssCnt[key]/numItems
#用最小支持度过滤,
if support >= minSupport:
#在列表的首部插入大于最小支持度的项
retList.insert(0,key)
#记录每项的支持度
supportData[key] = support
#返回频繁项集,以及每项的支持度
return retList, supportData
#由频繁k-1项集Lk1,生成候选项集Ck
#输入:频繁k-1项集Lk1,新的候选集元素个数k
#输出:候选集Ck
def aprioriGen(Lk1, k):
#保存新的候选集
retList = []
#频繁项集记录数
lenLk1 = len(Lk1)
#比较频繁项集中的两个子集元素
#若两子集元素的前面k-2项都相同,那么就将两子集合并。
#两个子集元素比较,通过使用两个for循环实现
for i in range(lenLk1):
for j in range(i+1, lenLk1):
#取频繁项集Lk中的一个子集元素的前k-2个项
L1 = list(Lk1[i])[:k-2]
#取频繁项集Lk中的另一子集元素的前k-2个项
L2 = list(Lk1[j])[:k-2]
L1.sort()
L2.sort()
#两元素的前k-2相同,则合并
if L1==L2:
#合并生成大小为k的集合
retList.append(Lk1[i] | Lk1[j])
#返回生成的候选k项集
return retList
#输入:数据集、最小支持度
def apriori(dataSet, minSupport = 0.5):
#生成1-项集
C1 = createC1(dataSet)
#对数据集进行映射至D,去掉某条记录中重复的商品
print'C1=',C1
D = map(set, dataSet)
#候选项集C1->频繁1-项集L1
#supportData存放所有项集的支持度
L1, supportData = scanD(D, C1, minSupport)
print'L1=',L1
#候选1项集所有元素对应的支持度
print 'supportData1=',supportData
#L存放所有的频繁项集,会包含L1、L2、L3...
L = [L1]
#由L1->C2,设定最初的k项集参数
k = 2
#由L1->C2->L2->C3...,用while循环实现
#随着k值增加,循环查找更新Lk,直到Lk为空时退出
#索引从0开始,L[k-2]即为频繁k-1项集
while (len(L[k-2]) > 0):
#由频繁k-1项集,->候选k项集Ck
Ck = aprioriGen(L[k-2], k)
print'C',k,'=',Ck
#Ck->频繁k项集Lk
Lk, supK = scanD(D, Ck, minSupport)
print'L',k,'=',Lk
#更新支持度字典,用于加入新的支持度
supportData.update(supK)
#候选集Ck中所有元素对应的支持度
print 'supportData',k,'=',supK
#累计已经计算的支持度
print 'supportDataupdate=',supportData
#将新的频繁k项集加入已有频繁项集的列表中
L.append(Lk)
#k加1,用于产生下一项集
k += 1
#返回所有频繁项集及支持度列表
return L, supportData
#=================================================================
###注意:1,2,3—>4
###上述规则就只有两部分,箭头前称为前件,箭头后称为后件
##
###产生后件为1项的关联规则,频繁项集{1,2,3,4}
###H=[[1],[2],[3],[4]]。
###H中元素依次做关联规则的后项
###1,2,3——>4
###1,2,4——>3
###1,3,4——>2
###2,3,4——>1
##
###产生后件为2项的关联规则,频繁项集{1,2,3,4}
###H = [[3,4],[2,4],[2,3],[1,4],[1,3],[1,2]]。
###H中元素依次做关联规则的后项
###1,2——>3,4
###1,3——>2,4
###1,4——>2,3
###2,3——>1,4
###2,4——>1,3
###3,4——>1,2
#=================================================================
#***产生关联规则
#输入:频繁项集列表L,支持度列表,最小置信度
#输出:满足最小置信度的规则列表
def generateRules(L, supportData, minConf=0.7):
#置信度规则列表,最后返回
bigRuleList = []
#无法从频繁1-项集L[0]中构建关联规则
#所以从频繁2-项集开始遍历(索引从1开始)
for i in range(1, len(L)):
#遍历当前频繁项集的每一个项集
#如频繁2项集为:[[1,2],[3,4]]
for freqSet in L[i]:
#如取项集为[1,2],则H1为[[1],[2]],单个元素组成
H1 = [frozenset([item]) for item in freqSet]
#H1为规则后件
#频繁项集中元素个数大于2,H1需要不断合并作为整体
#并利用最小置信度进行过滤
if (i > 1):
#L3,L4...项集
rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)
else: #L2
#项集只有2个元素即频繁2项集,直接计算置信度进行过滤
calcConf(freqSet, H1, supportData, bigRuleList, minConf)
#返回最后满足最小置信的规则列表
return bigRuleList
#根据最小置信度过滤候选的关联规则,并返回过滤后的规则的后件
###输入freqSet:某频繁项集、
### H:关联规则的后件
###supportData:所有项集的支持度
###brl:填充关联规则:前件,后件,置信度
###minConf:最小置信度
def calcConf(freqSet, H, supportData, brl, minConf=0.7):
#满足最小可信度要求的后件
prunedH = []
#遍历H中的所有项,用作关联规则的后件
for conseq in H:
#置信度计算
conf = supportData[freqSet]/supportData[freqSet-conseq]
#过滤
if conf >= minConf:
#显示:前件 -->后件:置信度
print freqSet-conseq,'-->',conseq,'conf:',conf
#保存关联规则:前件,后件,置信度
brl.append((freqSet-conseq, conseq, conf))
#满足最小可信度要求的后件
prunedH.append(conseq)
#返回满足条件的后项
return prunedH
#***基于某个频繁项集,生成关联规则
#输入:频繁项集、关联规则后件列表H、支持度列表
#brl需要填充的规则列表,最后返回
def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):
#后件中的项的个数
m = len(H[0])
#规则后件H的项的个数 比频繁项集freqSet中的项的个数少1,
#超过该条件无法产生关联规则
if m==1: #后件只有一个项
#过滤只有一个项的后件(产生规则如1,2,3->4,并返回过滤后的后件)
H = calcConf(freqSet, H, supportData, brl, minConf)
if (len(freqSet) > (m + 1)):
#对后件H元素组合,产生更多的候选规则后件
#由[1,2],[1,3]组合成[1,2,3]
Hmp1 = aprioriGen(H, m+1)
Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)
#过滤后Hmp1
#如果满足要求的规则不止一条
#继续使用Hmp1调用函数rulesFromConseq()
#判断是否可以进一步组合这些规则。
if (len(Hmp1) > 1):
rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)
if __name__ == "__main__":
#***生成频繁项集
dataSet=loadDataSet()
print 'dataSet=',dataSet
L,supportdata=apriori(dataSet,minSupport = 0.4)
print'L=',L
print'supportdata=',supportdata
print'-------------------------------------'
#***产生关联规则
rules=generateRules(L,supportdata,minConf=0.5)
print 'rules=',rules
# #***毒蘑菇数据测试
# mushDatSet=[line.split() for line in open('mushroom.dat').readlines()]
# L,supportdata=apriori(mushDatSet,minSupport=0.3)
# #与毒蘑菇出现频繁的1项:
# for item in L[1]:
# if item.intersection('2'):
# print item
# #与毒蘑菇出现频繁的3项:
# for item in L[3]:
# if item.intersection('2'):
# print item