Apriori算法|关联规则挖掘


〇.相关基础概念


1.购物篮数据的二元表示

  1. 事务:购物篮数据可以用一个列表来表示,列表中的每一行都对应一个事务
  1. 项:表格中的每一列则对应一个数据项
  2. 项的二元表示:如果该项在这个事务中出现了则值为1,否则值为0.

2.项集与支持度计数

  1. 项的集合:I = {i1,i2,…,id}是购物篮数据中所有项的集合
  1. 事务集合:T = {t1,t2,…tN}是所有事务的集合。
    每个事务ti包含的项集都是I的子集
  1. (k-)项集:包含0个或多个项的集合被称为项集,项集中含有k个项,则把这个项集称为k-项集。
    空集是指不包含任何项的项集。
    e.g.{啤酒,尿布,牛奶}是一个3-项集
  1. 项集的支持度计数
    ①事务包含项集:若某一个项集是事务的子集,则称这个事务包括项集。
    ②项集的支持度计数:包含这个项集的事务的个数。
    σ(X)=|{ti|X∈ti,ti∈T}|

3.关联规则与支持度和置信度

  1. 关联规则:形如X→Y的蕴含表达式,且X∩Y=∅。
  1. 关联规则的支持度:描述该项集在给定数据集的频繁程度
    s(X→Y)=σ(X∪Y)/N
  1. 关联规则的置信度:确定集合Y在包含X得到事务中出现的频繁程度
    c(X→Y)=σ(X∪Y)/σ(X)


一.问题定义与分解


1.问题描述

  1. 关联规则发现
    给定事务的集合T,关联规则发现是指找出支持度大于或等于minsup且置信度大于或等于minconf的所有规则,其中minsup和minconf是对应的支持度和置信度阈值。
  1. 任务分解
    ①频繁项集的产生——发现满足最小支持度的所有项集。
    ②规则的产生——对于找到的频繁项集进行二划分产生规则提取出所有高置信度的规则。

2.复杂度分析与完善

  1. 频繁项集产生所需要的计算开销远大于产生规则所需要的计算开销
    原因:在同一个项集中通过二划分产生的规则,则这些项的支持度都是相同的,如果进行划分的项集不是频繁的,那么自然结果不会是好的规则,所以进行关联规则生成之前已经对项集进行了剪枝。
  1. 暴力解法的复杂度估计
    ①所谓暴力解法就是指将所有候选的规则与支持度阈值逐个比较;将每个规则的置信度与置信度阈值逐个比较,留下满足条件的项。
    ②从包含d个项的数据集中提取可能的规则总数为:R = 3d -2d+1 +1;且找出来所有的规则之后还要进行筛选,故前面的大部分计算都是无用的
    ③一个包含k个项的数据集可能产生2k -1个频繁项集(实质上就是项集的所有非空子集都是候选频繁项集)
    ④设N为事务总数,M为候选项集总数,w是事务的最大宽度,则暴力算法中求解频繁项集的复杂度为O(NMw)

3.降低算法复杂度的思路
①使用剪枝策略减少候选频繁项集的个数
②使用高效的数据结构存储候选项集和事务以减少二者在计算置信度和支持度时的比较次数。


二.频繁项集的产生


1.项集的格结构

项集的格结构常常用来枚举所有可能的项集,如下图所示,图中显示的就是I={a,b,c,d,e}的项集格

2.先验原理

作用:可以减少候选项集的个数,降低复杂度
本质:基于支持度的剪枝策略
理论基础:支持度度量是一种反单调性的度量
实际操作:一旦发现某个项集是非频繁的,那么包含这个项集及其超集的子图都可以被立即剪枝

定理描述:
①如果一个项集是频繁的,那么该项集的所有子集也一定是频繁的

②如果一个项集是非频繁的,那么该项集的所有超集也一定都是非频繁的

理解:如果一个项集是频繁的,那么说明具有一定数目的事务是包含这个项集的,那么至少也有相同数目的事务包含该项集的子集。

单调性与反单调性

3.候选项集的产生

综述
频繁项集的产生核心分为两个部分,其一是候选项集的产生,其二是候选项集的剪枝。候选项集的策略以下会谈到,候选项集的剪枝就需要选择合适的支持度的计算方法,再按照之前说明的基于支持度的剪枝策略进行剪枝。

3.1蛮力解决:把所有的k-项集都看做是候选频繁项集

3.2 Fk-1*F1方法
①基本描述:使用频繁1-项集来扩展频繁(k-1)-项集。

②问题

③解决方案——规定合并时的顺序要求
频繁(k-1)-项集X只用字典序比X中所有项都大的频繁项进行拓展。

3.3.Fk-1*Fk-1方法
①基本描述:当两个(k-1)-频繁项集的前k-2个项都相同时,A={a1,a2,…,ak-1},B={b1,b2,…,bk-1},则对A和B进行合并,当且仅当
ai = bi (i=1,2,…,k-2) and ak-1≠bk-1

②示例

4.候选项集的剪枝

剪枝策略在先验原理部分已经讲解过了,此处主要探讨支持度计算方法

4.1 蛮力方法
将每个事务和候选项集进行比较,如果该事务包含了这个候选项集,则对应的候选项集的支持度计数+1

4.2事务枚举法
①基本描述:对于每一个事务,若当前需要对k-候选项集进行支持度计数,则考虑该事务选出k个元素的组合方案,如果有和k-候选项集相契合的,则该候选项集的支持度+1
②树形结构
为了避免枚举时的重复,规定枚举的时候元素按照递增的字典序进行排列。

③利用Hash树进行支持度计数
a.首先关于所有的候选项集建立一个hash树,比如按照下图,有三个分叉,则1,4,7往左子树,2,5,8往中间子树,3,6,9往右子树;每一层都按照这个规律,直到最后到叶节点。(下列图是关于3-候选项集建立hash树,所以所有叶节点含有3个元素)
b.在将事务中所有3个元素的子集按照上述hash结构进行同样的散列,直到到达了叶节点,若有匹配的,支持度+1,否然忽略即可。


三.关联规则的产生


关联规则产生的思维图

1.使用二分法从频繁项集到候选规则

①候选规则产生:对于给定的频繁项集L,找到所有非空子集f,形如f→L-f的满足最小置信度的规则就为所求

②计算量评估:如果频繁项集L的长度为k(即:该频繁项集中有k个元素),那么会有2k -2个候选规则(所有可能的子集除去空集出现在左右两侧的情况)

2.规则产生方法

①反单调性性质
一般而言,规则的置信度评估并不具有反单调性的性质

但是对于从同一个频繁项集产生的规则具有反单调性——关于规则右边的项的数目呈反单调性

②规则生成方法
核心:合并具有两个相同的前缀的规则
剪枝规则:若生成的规则D=>ABC的子集AD=>BC没有较高的置信度,
那么就要把AD=>BC及其衍生出来的规则全都淘汰

③支持度分布偏斜问题
a.问题描述:比如说一些较贵重的商品,买的人相比一般便宜的商品,自然会买的比较少,所以支持度占比会相对较低,但是这不意味着在贵重的商品之中不存在关联规则
b.支持度阈值分析
最小支持度设置得过高,会错过一些可能包含规则的项;
最小支持度设置得过低,则计算代价会很昂贵,而且得到的数据项的数目会很大
c.解决措施:设置最小支持度MS,对于不同的物体有不同的MS阈值

d.MS计算方法

特点:设置了MS之后,支持度已经不再是反单调性的了


四.Apriori算法


1.产生频繁项集


注:Apriori算法使用Fk-1*Fk-1的策略

2.规则产生



设置MS后对Apriori算法的改进


五.代码实现


  1. 实验内容
    使用Apriori算法,对美国国会投票数据进行高置信度规则的挖掘;其中支持度设为30%,置信度设为90%。
    数据来源:http://archive.ics.uci.edu/ml/datasets/Congressional+Voting+Records

  2. 实验分析与设计

  3. 源代码

#coding:gbk
def loadData(path=''):'''加载原始数据'''f = open(path + 'house-votes-84.data')txt = f.read()f.close()lst_txt = txt.split('\n')data = []for txt_line in lst_txt:tmp = txt_line.split(',')data.append(tmp)return datadef preProcessing(data, vote_y_n):'''数据预处理以按 y 或 n 寻找关联规则'''data_pre = []for data_line in data:tmp_data = []for i in range(1, len(data_line)):#从第二列开始,将数据文件中的记录与当前的选择vote_y_n进行比较,若找到了相关记录,把下标存进去if (data_line[i] == vote_y_n):tmp_data.append(i)if (tmp_data == []):continue#如果当前这一条记录中没有任何一个项是vote_y_n对应的选项,那么不存储空列表,直接进行下一个记录的查找data_pre.append(tmp_data)return data_pre
def ppreProcessing(data, vote_y_n, party):'''数据预处理以按 y 或 n 和议员所属党派来寻找关联规则'''data_pre = []for data_line in data:tmp_data = []if data_line[0] == party:for i in range(1, len(data_line)):# 从第二列开始,将数据文件中的记录与当前的选择vote_y_n进行比较,若找到了相关记录,把下标存进去if (data_line[i] == vote_y_n):tmp_data.append(i)if (tmp_data == []):continue#如果当前这一条记录中没有任何一个项是vote_y_n或者这条记录不是对应party的议员对应的选项,那么不存储空列表,直接进行下一个记录的查找data_pre.append(tmp_data)return data_predef rule_mining(data, support, confidence):'''挖掘关联规则'''dic_1 = mining_first(data, support, confidence)# print(dic_1)dic_2 = mining_second(data, dic_1, support, confidence)# print(dic_2)dic_before = dic_2dic_r = []#频繁项集产生的终止条件就是不再有新的频繁项集产生为止while (dic_before != {}):#dict_r里面存储的是频繁2-项集及之后的所有频繁项集dic_r.append(dic_before)dic_3 = mining_third(data, dic_before, support, confidence)dic_before = dic_3return dic_rpassdef mining_first(data, support, confidence):'''进行第一次挖掘挖掘候选1-项集'''dic = {}count = len(data)for data_line in data:#对于数据集中的每一行投票数据for data_item in data_line:#对于每一行数据中的下标(对应某个议题)if (data_item in dic):#以键值对的形式进行存储和计数dic[data_item] += 1else:dic[data_item] = 1assert (support >= 0) and (support <= 1), 'suport must be in 0-1'#依靠给定的支持度阈值和投票数据的总数的得到满足条件的最小支持度值val_suport = int(count * support)assert (confidence >= 0) and (confidence <= 1), 'coincidence must be in 0-1'#如果键值对中的值大于或等于当前支持度阈值,则可以将该键值对作为频繁1-项集保留dic_1 = {}for item in dic:#如果对每一个议题的所选定的(y|n)进行计数,若计数总值超过了支持度所需要的计数,就把它放到下一个字典中if (dic[item] >= val_suport):dic_1[item] = dic[item]return dic_1def mining_second(data, dic_before, support, confidence):'''进行关联规则的二次挖掘挖掘出候选2-项集注:所有挖掘出来的频繁项集都是以字典的形式存储的,字典的键是频繁项集,1频繁项集用1-16个整数,表示这些议题在原数据集中的下标;多频繁集就是这些下标的一个元组隐藏含义是这些议题共同被投票为vote_y_n,字典的值就是这样的组合出现的次数'''#每一次扩展频繁项集的时候产生一个临时dict用于保存那些通过频繁项集生成算法可以留下的项集#但是还要对其中的结果进行支持度判断,才能确定最终留下的算法dic = {}count = len(data)count2 = 0for data_line in data:# 获取元素数量count_item = len(data_line)# 每两个组合计数for i in range(0, count_item - 1):#外层循环,控制频繁2-项集中的第一个元素的取值for j in range(i + 1, count_item):#内层循环,控制频繁2-项集中的第二个元素的取值if (data_line[i] in dic_before and data_line[j] in dic_before):count2 += 1tmp = (data_line[i], data_line[j])if (tmp in dic):#上同,使用键值对集合计数,只不过此时元素是二元的元组dic[tmp] += 1else:dic[tmp] = 1else:continue#当两个项中有一个不是频繁1-项集,根据剪枝策略,这样组成的项不是频繁2-项集# print(dic)assert (support >= 0) and (support <= 1), 'suport must be in 0-1'assert (confidence >= 0) and (confidence <= 1), 'confidence must be in 0-1'dic_2 = {}for item in dic:count_item0 = dic_before[item[0]]count_item1 = dic_before[item[1]]# 判断 支持度 和 置信度#判断置信度的时候对于一个无序的元组,任何一种方向的规则都有可能,都要进行比较if ((dic[item] >= support * count) and ((dic[item] >= confidence * count_item0) or (dic[item] >= confidence * count_item1))):dic_2[item] = dic[item]return dic_2def mining_third(data, dic_before, support,confidence):'''进行关联规则的三次挖掘挖掘出候选3-项集或者4-项集乃至n-项集'''#频繁项集的产生使用Fk-1*Fk-1的策略dic_3 = {}for item0 in dic_before:#外层循环控制频繁k-1项集中的某一项for item1 in dic_before:#内层循环控制频繁k-1项集中的另一项if (item0 != item1):# print(item0,item1)item_len = len(item0)equal = Truetmp_item3 = []# 判断前n-1项是否一致for i in range(item_len - 1):tmp_item3.append(item0[i])if (item0[i] != item1[i]):equal = Falsebreakif (equal == True):#如果两个Fk-1项具有k-2个公共前缀,那么就按照顺序,将其组合起来minitem = min(item0[-1], item1[-1])maxitem = max(item0[-1], item1[-1])tmp_item3.append(minitem)tmp_item3.append(maxitem)tmp_item3 = tuple(tmp_item3)dic_3[tmp_item3] = 0else:continue# print('dic_3:',dic_3)#暴力统计支持度的方法,对于每一个数据项,看每个新找到的k项集是否包含在数据项中#比较的方法,是对项的每一位进行判断,看这一位是否在数据项中for data_line in data:for item in dic_3:is_in = Truefor i in range(len(item)):if (item[i] not in data_line):is_in = False#该候选k项集中的所有项都在数据项中,则可以将该项保留if (is_in == True):dic_3[item] += 1assert (support >= 0) and (support <= 1), 'suport must be in 0-1'assert (confidence >= 0) and (confidence <= 1), 'coincidence must be in 0-1'count = len(data)dic_3n = {}for item in dic_3:#前一项的支持度计数,就是现在的项除去末尾的数字,通过键值对在原来的字典中查询的值count_item0 = dic_before[item[:-1]]# 判断 支持度 和 置信度if ((dic_3[item] >= support * count) and (dic_3[item] >= confidence * count_item0)):dic_3n[item] = dic_3[item]return dic_3ndef association_rules(freq_sets, min_conf):'''根据产生的频繁项集生成满足置信度要求的规则:param dict: 频繁项集的字典:param dict: 频繁项集字典中的频繁项集列表:param min_conf: 最小置信度:return: 规则列表'''rules = []max_len = len(freq_sets)for k in range(max_len - 1):for freq_set in freq_sets[k]:for sub_set in freq_sets[k + 1]:if set(freq_set).issubset(set(sub_set)):conf = freq_sets[k+1][sub_set] / freq_sets[k][freq_set]rule = (set(freq_set), set(sub_set) - set(freq_set), conf)if conf >= min_conf:rules.append(rule)return rulesif (__name__ == '__main__'):data_row = loadData()data_y = preProcessing(data_row, 'y')data_n = preProcessing(data_row, 'n')data_y_republican = ppreProcessing(data_row, 'y', 'republican')data_y_democrat = ppreProcessing(data_row, 'y', 'democrat')data_n_republican = ppreProcessing(data_row, 'n', 'republican')data_n_democrat = ppreProcessing(data_row, 'n', 'democrat')# 支持度support = 0.3# 置信度confidence = 0.9#总的y规则与两个党派的y规则r_y = rule_mining(data_y, support, confidence)print('vote `y`:\n', r_y)rule_y = association_rules(r_y, confidence)print('rule `y`:\n', rule_y)r_y_republican = rule_mining(data_y_republican, support, confidence)print('vote_republican `y`:\n', r_y_republican)rule_y_republican = association_rules(r_y_republican, confidence)print('rule_republican `y`:\n', rule_y_republican)r_y_democrat = rule_mining(data_y_democrat, support, confidence)print('vote_democrat `y`:\n', r_y_democrat)rule_y_democrat = association_rules(r_y_democrat, confidence)print('rule_democrat `y`:\n', rule_y_democrat)#总的n规则与两个党派的n规则r_n = rule_mining(data_n, support, confidence)print('vote `n`:\n', r_n)rule_n = association_rules(r_n, confidence)print('rule `n`:\n', rule_n)r_n_republican = rule_mining(data_n_republican, support, confidence)print('vote_republican `n`:\n', r_n_republican)rule_n_republican = association_rules(r_n_republican, confidence)print('rule `n`:\n', rule_n_republican)r_n_democrat = rule_mining(data_n_democrat, support, confidence)print('vote_democrat `n`:\n', r_n_democrat)rule_n_democrat = association_rules(r_n_democrat, confidence)print('rule_democrat `n`:\n', rule_n_democrat)f = open('result_mining.txt', 'w')f.write('vote `y`:\n')f.write(str(r_y))f.write('rule `y`:\n')f.write(str(rule_y))f.write('\n\nvote `n`:\n')f.write(str(r_n))f.write('rule `n`:\n')f.write(str(rule_y))f.close()

实验报告+源码

[DM复习]Apriori算法-国会投票记录关联规则挖掘(上)相关推荐

  1. Apriori算法——中医病症辩证关联规则分析

    数据读取与预处理 import pandas as pd df = pd.read_excel('中医辨证.xlsx') df.head() # 简单演示下tolist()函数 df['病人症状']. ...

  2. apriori算法代码_sklearn(九)apriori 关联规则算法,以及FP-growth 算法

    是什么: apriori算法是第一个关联规则挖掘算法,利用逐层搜索的迭代方法找出数据库中的项集(项的集合)的关系,以形成规则,其过程由连接(类矩阵运算)与剪枝(去掉没必要的中间结果)组成.是一种挖掘关 ...

  3. php关联规则,如何理解关联规则apriori算法

    理解关联规则apriori算法:Apriori算法是第一个关联规则挖掘算法,也是最经典的算法,它利用逐层搜索的迭代方法找出数据库中项集的关系,以形成规则,其过程由连接[类矩阵运算]与剪枝[去掉那些没必 ...

  4. python apriori算法 sklearn_sklearn(九)apriori 关联规则算法,以及FP-growth 算法

    是什么: apriori算法是第一个关联规则挖掘算法,利用逐层搜索的迭代方法找出数据库中的项集(项的集合)的关系,以形成规则,其过程由连接(类矩阵运算)与剪枝(去掉没必要的中间结果)组成.是一种挖掘关 ...

  5. 机器学习之关联规则(支持度和置信度、Apriori算法)

    关联规则及其基础: 表1:购物篮例子的分析 关联分析:用于发现隐藏在大型数据集中的有意义的联系.所发现的联系可以用关联规则或频繁项集的形式表示. 例如,从表1中可以提取出:{尿布} ⟹ {啤酒}(该规 ...

  6. 关联规则—Apriori算法—FPTree

    文章目录 一.关联规则 1.1 概念 1.2 示例 二.关联规则挖掘推论(Apriori 算法) 2.1 关联规则挖掘方法: 2.3 FP-growth 三.FP-growth原理 3.1 生成项头表 ...

  7. Apriori算法学习和java实现

    关联规则挖掘可以发现大量数据中项集之间有趣的关联或相关联系.一个典型的关联规则挖掘例子是购物篮分析,即通过发现顾客放入其购物篮中的不同商品之间的联系,分析顾客的购物习惯,从而可以帮助零售商指定营销策略 ...

  8. Apriori 算法原理以及python实现详解

    Apriori 算法原理以及python实现 ​ Apriori算法是第一个关联规则挖掘算法,也是最经典的算法.它利用逐层搜索的迭代方法找出数据库中项集的关系,以形成规则,其过程由连接(类矩阵运算)与 ...

  9. Java实现Apriori算法

    简介: Apriori算法是第一个关联规则挖掘算法,也是最经典的算法.它利用逐层搜索的迭代方法找出数据库中项集的关系,以形成规则,其过程由连接(类矩阵运算)与剪枝(去掉那些没必要的中间结果)组成.该算 ...

最新文章

  1. Unet网络实现叶子病虫害图像分割
  2. Intel汇编语言程序设计学习-第六章 条件处理-上
  3. docker -v 文件夹下没有数据_详细!快速入门指南!Docker
  4. 【PHP】文件写入和读取详解
  5. Java 对用户密码加密(Jeecg 登录密码加密方式)MD5andDES方式
  6. vi中如何跳到指定行
  7. python 排序统计滤波器_数字图像处理的python实现(8)——中值滤波
  8. git add多个文件_10个节省时间和改善工作流的Git技巧
  9. linux下 根目录扩展
  10. 16进制储存的农历信息的正确打开方式
  11. DSP6678入门必看
  12. [NOIP2016 普及组] 海港
  13. 什么是EJB?EJB到底是什么?
  14. shopex admincore.php,Shopex后台登录页面注入漏洞附利用POC
  15. 配置Hadoop格式化namenode时报错cannot create directory /usr/local/hadoop/tmp/dfs/name/current
  16. zgb老师关于java集合的总结
  17. 般若堂--Spring Boot系列之参数校验
  18. python医院自动化抢号脚本
  19. Navicat Premium安装和激活
  20. 【Kali安全渗透测试实践教程】第9章 无线网络渗透

热门文章

  1. idea 鼠标变量_IDEA在debug时修改变量值
  2. lol3.17服务器维护,LOL3.17全区维护长达16个小时 官方补偿3胜经验卡
  3. 【数据原理及应用 学习总结】第二章 关系数据库标准语言SQL(1)
  4. [架构之路-148]-《软考-系统分析师》- 7-企业信息化战略与实施-5-企业信息系统、电子政务
  5. 浏览器返回按钮跳转到指定页面
  6. 机器学习识别身份证信息代码
  7. notepad++下载 地址真实有效
  8. java synthetic_Java冷知识(三)编译器的花招之synthetic
  9. 电子游戏究竟能对人造成什么影响?——近几年内基于ERP分析游戏影响的研究解读(一)
  10. 羟基法舒地尔单盐酸盐 Cas:155558-32-0 Hydroxyfasudil hydrochloride 活性氧分子