Apriori算法
Apriori算法是第一个关联规则挖掘算法,也是最经典的算法。它利用逐层搜索的迭代方法找出数据库中项集的关系,以形成规则,其过程由连接(类矩阵运算)与剪枝(去掉那些没必要的中间结果)组成。该算法中项集的概念即为项的集合。包含K个项的集合为k项集。项集出现的频率是包含项集的事务数,称为项集的频率。如果某项集满足最小支持度,则称它为频繁项集。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from numpy import *
# 构造数据
def loadDataSet():
from csv import reader
potus = list(reader(open('../data/EpiData7.0.csv', encoding='UTF-8')))
# print(potus)
return potus
# 将所有元素转换为frozenset型字典,存放到列表中
def createC1(dataSet):
# prinnt('createC1将所有元素转换为frozenset型字典,存放到列表中')
C1 = []
for transaction in dataSet:
for item in transaction:
if not [item] in C1:
C1.append([item])
C1.sort()
# 使用frozenset是为了后面可以将这些值作为字典的键
return list(map(frozenset, C1)) # frozenset一种不可变的集合,set可变集合
# 过滤掉不符合支持度的集合
# 返回 频繁项集列表retList 所有元素的支持度字典
def scanD(D, Ck, minSupport):
# print('scanD过滤掉不符合支持度的集合')
ssCnt = { }
for tid in D:
for can in Ck:
if can.issubset(tid): # 判断can是否是tid的《子集》 (这里使用子集的方式来判断两者的关系)
if can not in ssCnt: # 统计该值在整个记录中满足子集的次数(以字典的形式记录,frozenset为键)
ssCnt[can] = 1
else:
ssCnt[can] += 1
numItems = float(len(D))
retList = [] # 重新记录满足条件的数据值(即支持度大于阈值的数据)
supportData = { } # 每个数据值的支持度
for key in ssCnt:
support = ssCnt[key] / numItems
if support >= minSupport:
retList.insert(0, key)
supportData[key] = support
return retList, supportData # 排除不符合支持度元素后的元素 每个元素支持度
# 生成所有可以组合的集合
# 频繁项集列表Lk 项集元素个数k [frozenset({2, 3}), frozenset({3, 5})] -> [frozenset({2, 3, 5})]
def aprioriGen(Lk, k):
# print('aprioriGen生成所有可以组合的集合')
retList = []
lenLk = len(Lk)
for i in range(lenLk): # 两层循环比较Lk中的每个元素与其它元素
for j in range(i + 1, lenLk):
L1 = list(Lk[i])[:k - 2] # 将集合转为list后取值
L2 = list(Lk[j])[:k - 2]
L1.sort();
L2.sort() # 这里说明一下:该函数每次比较两个list的前k-2个元素,如果相同则求并集得到k个元素的集合
if L1 == L2:
retList.append(Lk[i] | Lk[j]) # 求并集
return retList # 返回频繁项集列表Ck
# 封装所有步骤的函数
# 返回 所有满足大于阈值的组合 集合支持度列表
def apriori(dataSet, minSupport=0.01):
print('apriori')
D = list(map(set, dataSet)) # 转换列表记录为字典 [{1, 3, 4}, {2, 3, 5}, {1, 2, 3, 5}, {2, 5}]
C1 = createC1(
dataSet) # 将每个元素转会为frozenset字典 [frozenset({1}), frozenset({2}), frozenset({3}), frozenset({4}), frozenset({5})]
L1, supportData = scanD(D, C1, minSupport) # 过滤数据
L = [L1]
k = 2
while (len(L[k - 2]) > 0): # 若仍有满足支持度的集合则继续做关联分析
Ck = aprioriGen(L[k - 2], k) # Ck候选频繁项集
Lk, supK = scanD(D, Ck, minSupport) # Lk频繁项集
supportData.update(supK) # 更新字典(把新出现的集合:支持度加入到supportData中)
L.append(Lk)
k += 1 # 每次新组合的元素都只增加了一个,所以k也+1(k表示元素个数)
return L, supportData
dataSet = loadDataSet()
L, suppData = apriori(dataSet)
# print('L',L)
# print('suppData',suppData)
# 获取关联规则的封装函数
def generateRules(L, supportData, minConf=0.8): # supportData 是一个字典
print('获取关联规则的封装函数')
bigRuleList = []
for i in range(1, len(L)): # 从为2个元素的集合开始
for freqSet in L[i]:
# 只包含单个元素的集合列表
H1 = [frozenset([item]) for item in freqSet] # frozenset({2, 3}) 转换为 [frozenset({2}), frozenset({3})]
# 如果集合元素大于2个,则需要处理才能获得规则
if (i > 1):
rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf) # 集合元素 集合拆分后的列表 。。。
else:
calcConf(freqSet, H1, supportData, bigRuleList, minConf)
return bigRuleList
# 对规则进行评估 获得满足最小可信度的关联规则
def calcConf(freqSet, H, supportData, brl, minConf=0.8):
print('对规则进行评估 获得满足最小可信度的关联规则')
prunedH = [] # 创建一个新的列表去返回
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
# 生成候选规则集合
def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.8):
print('#生成候选规则集合')
m = len(H[0])
if (len(freqSet) > (m + 1)): # 尝试进一步合并
Hmp1 = aprioriGen(H, m + 1) # 将单个集合元素两两合并
Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)
if (len(Hmp1) > 1): # need at least two sets to merge
rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)
dataSet = loadDataSet()
L, suppData = apriori(dataSet, minSupport=0.01)
rules = generateRules(L, suppData, minConf=0.8)
# rules = generateRules(L,suppData,minConf=0.5)
print('rules',rules)
运行结果展示
获取关联规则的封装函数
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
对规则进行评估 获得满足最小可信度的关联规则
frozenset({ '神经症'}) --> frozenset({ '女'}) conf: 1.0
对规则进行评估 获得满足最小可信度的关联规则
frozenset({ '神经症'}) --> frozenset({ '无跌倒风险'}) conf: 1.0
对规则进行评估 获得满足最小可信度的关联规则
frozenset({ '神经症'}) --> frozenset({ '跌倒时无妄想或幻觉'}) conf: 1.0
#生成候选规则集合
对规则进行评估 获得满足最小可信度的关联规则
frozenset({ '无后果', '精神分裂', '无跌倒风险', '病室', '中年人'}) --> frozenset({ '跌倒时无妄想或幻觉', '女'}) conf: 0.8571428571428571
frozenset({ '无后果', '精神分裂', '女', '病室', '中年人'}) --> frozenset({ '无跌倒风险', '跌倒时无妄想或幻觉'}) conf: 1.0
frozenset({ '无后果', '跌倒时无妄想或幻觉', '精神分裂', '病室', '中年人'}) --> frozenset({ '无跌倒风险', '女'}) conf: 0.8571428571428571
#生成候选规则集合
对规则进行评估 获得满足最小可信度的关联规则
frozenset({ '无后果', '精神分裂', '病室', '中年人'}) --> frozenset({ '无跌倒风险', '跌倒时无妄想或幻觉', '女'}) conf: 0.8571428571428571
#生成候选规则集合
对规则进行评估 获得满足最小可信度的关联规则
frozenset({ '入院3月内', '无后果', '精神分裂', '中年人'}) --> frozenset({ '跌倒时无妄想或幻觉', '病室', '无跌倒风险', '女'}) conf: 0.8
#生成候选规则集合
对规则进行评估 获得满足最小可信度的关联规则
frozenset({ '无后果', '精神分裂', '女', '年轻老年人', '饭厅', '无跌倒风险'}) --> frozenset({ '入院6月以上', '跌倒时无妄想或幻觉'}) conf: 1.0
frozenset({ '无后果', '入院6月以上', '女', '年轻老年人', '饭厅', '无跌倒风险'}) --> frozenset({ '精神分裂', '跌倒时无妄想或幻觉'}) conf: 1.0
frozenset({ '无后果', '入院6月以上', '精神分裂', '女', '饭厅', '无跌倒风险'}) --> frozenset({ '年轻老年人', '跌倒时无妄想或幻觉'}) conf: 1.0
frozenset({ '无后果', '入院6月以上', '精神分裂', '女', '年轻老年人', '饭厅'}) --> frozenset({ '无跌倒风险', '跌倒时无妄想或幻觉'}) conf: 1.0
frozenset({ '无后果', '跌倒时无妄想或幻觉', '入院6月以上', '女', '饭厅', '无跌倒风险'}) --> frozenset({ '年轻老年人', '精神分裂'}) conf: 1.0
frozenset({ '无后果', '跌倒时无妄想或幻觉', '入院6月以上', '女', '年轻老年人', '饭厅'}) --> frozenset({ '精神分裂', '无跌倒风险'}) conf: 1.0
frozenset({ '无后果', '跌倒时无妄想或幻觉', '入院6月以上', '精神分裂', '女', '饭厅'}) --> frozenset({ '年轻老年人', '无跌倒风险'}) conf: 1.0
#生成候选规则集合
对规则进行评估 获得满足最小可信度的关联规则
frozenset({ '无后果', '入院6月以上', '女', '年轻老年人', '饭厅'}) --> frozenset({ '精神分裂', '跌倒时无妄想或幻觉', '无跌倒风险'}) conf: 1.0
frozenset({ '无后果', '入院6月以上', '女', '饭厅', '无跌倒风险'}) --> frozenset({ '年轻老年人', '精神分裂', '跌倒时无妄想或幻觉'}) conf: 1.0
frozenset({ '无后果', '入院6月以上', '精神分裂', '女', '饭厅'}) --> frozenset({ '年轻老年人', '无跌倒风险', '跌倒时无妄想或幻觉'}) conf: 1.0
frozenset({ '无后果', '跌倒时无妄想或幻觉', '入院6月以上', '女', '饭厅'}) --> frozenset({ '年轻老年人', '精神分裂', '无跌倒风险'}) conf: 1.0
#生成候选规则集合
对规则进行评估 获得满足最小可信度的关联规则
frozenset({ '入院6月以上', '无后果', '饭厅', '女'}) --> frozenset({ '年轻老年人', '跌倒时无妄想或幻觉', '无跌倒风险', '精神分裂'}) conf: 1.0
rules [(frozenset({ '神经症'}), frozenset({ '女'}), 1.0), (frozenset({ '神经症'}), frozenset({ '无跌倒风险'}), 1.0), (frozenset({ '神经症'}), frozenset({ '跌倒时无妄想或幻觉'}), 1.0), (frozenset({ '跌倒时有妄想或幻觉'}), frozenset({ '无跌倒风险'}), 0.8333333333333334), (frozenset({ '跌倒时有妄想或幻觉'}), frozenset({ '精神分裂'}), 0.8333333333333334), (frozenset({ '其他地点'}), frozenset({ '无跌倒风险'}), 1.0), (frozenset({ '其他地点'}), frozenset({ '跌倒时无妄想或幻觉'}), 1.0), (frozenset({ '其他地点'}), frozenset({ '年轻老年人'}), 1.0), (frozenset({ '其他地点'}), frozenset({ '精神分裂'}), 1.0), (frozenset({ '痴呆'}), frozenset({ '跌倒时无妄想或幻觉'}), 1.0), (frozenset({ '入院6月内'}), frozenset({ '无跌倒风险'}), 0.875), (frozenset({ '入院6月内'}), frozenset({ '跌倒时无妄想或幻觉'}), 0.9375), (frozenset({ '走廊'}), frozenset({ '跌倒时无妄想或幻觉'}), 0.9428571428571428), (frozenset({ '重度后果'}), frozenset({ '无跌倒风险'}), 0.8125), (frozenset({ '重度后果'}), frozenset({ '跌倒时无妄想或幻觉'}), 0.9375), (frozenset({ '老年人'}), frozenset({ '跌倒时无妄想或幻觉'}), 0.9230769230769231), (frozenset({ '入院1月内'}), frozenset({ '跌倒时无妄想或幻
还没有评论,来说两句吧...