基于Hash表的改进Apriori算法
Apriori算法

数据挖掘算法实验报告1)实验题目Apriori算法是一种最有影响的挖掘布尔关联规则频繁项集的算法。
它将关联规则挖掘算法的设计分解为两个子问题:(1)找到所有支持度大于最小支持度的项集,这些项集称被为频繁项集(Frequent Itemset)。
(2)使用第一步产生的频繁集产生期望的规则。
在图书馆管理系统中积累了大量的读者借还书的历史记录,基于Apriori算法挖掘最大频繁项目集,由此产生关联规则。
数据格式可参阅文献参考文献:彭仪普,熊拥军: 关联挖掘在文献借阅历史数据分析中的应用.情报杂志. 2005年第8期(本实验我用的是书上的例题AllElectronics事物数据库的数据做的)2)算法基本思想的描述Apriori算法是一种最有影响的挖掘布尔关联规则频繁项集的算法。
其核心是基于两阶段频集思想的递推算法。
该关联规则在分类上属于单维、单层、布尔关联规则。
在这里,所有支持度大于最小支持度的项集称为频繁项集,简称频集。
该算法的基本思想是:首先找出所有的频集,这些项集出现的频繁性至少和预定义的最小支持度一样。
然后由频集产生强关联规则,这些规则必须满足最小支持度和最小可信度。
然后使用第1步找到的频集产生期望的规则,产生只包含集合的项的所有规则,其中每一条规则的右部只有一项,这里采用的是中规则的定义。
一旦这些规则被生成,那么只有那些大于用户给定的最小可信度的规则才被留下来。
为了生成所有频集,使用了递推的方法。
(1)L1 = find_frequent_1-itemsets(D);(2)for (k=2;Lk-1 ≠Φ ;k++) {(3)Ck = apriori_gen(Lk-1 ,min_sup);(4)for each transaction t ∈D{//scan D for counts(5)Ct = subset(Ck,t);//get the subsets of t that are candidates(6)for each candidate c ∈ Ct(7) c.count++;(8)}(9)Lk ={c ∈ Ck|c.count≥min_sup} (10)}(11)return L= ∪ k Lk;3)编程实现算法#include <stdio.h>#include <math.h>int l1[5]={0};int l2[5][5]={0};int l3[5][5][5]={0};void LoadIteml1(int data[9][4]){int i,j;for(i=0;i<9;i++){for(j=0;j<4;j++){switch(data[i][j]){case 0:break;case 1:l1[0]++;break;case 2:l1[1]++;break;case 3:l1[2]++;break;case 4:l1[3]++;break;case 5:l1[4]++;break;}}}printf("频繁一项集:\n");for(i=0;i<5;i++){printf("I%d:%d\n",i+1,l1[i]);}}int count2(int data[9][4],int m,int n){int i,j;int flag1=0,flag2=0,count=0;for(i=0;i<9;i++){for(j=0;j<4;j++){if(data[i][j]==m) flag1=1;else if(data[i][j]==n) flag2=1;}if(flag1==1 && flag2==1) count++;flag1=flag2=0;}return count;}void LoadIteml2(int data[9][4]){int i,j;for(i=0;i<5;i++){for(j=i+1;j<5;j++){l2[i][j]=count2(data,i+1,j+1);}}printf("频繁二项集:\n");for(i=0;i<5;i++){for(j=0;j<5;j++){if(l2[i][j]>1)printf("I%d I%d:%d\n",i+1,j+1,l2[i][j]);}}}int count3(int data[9][4],int m,int n,int a){int i,j,flag1=0,flag2=0,flag3=0;int count=0;for(i=0;i<9;i++){if(data[i][2]==0) continue;for(j=0;j<5;j++){if(data[i][j]==m) flag1=1;if(data[i][j]==n) flag2=1;if(data[i][j]==a) flag3=1;}if(flag1==1 && flag2==1 && flag3==1)count++;flag1=flag2=flag3=0;}return count;}void LoadIteml3(int data[9][4]){int i,j,k;for(i=0;i<5;i++){for(j=i+1;j<5;j++){for(k=j+1;k<5;k++){l3[i][j][k]=count3(data,i+1,j+1,k+1);}}}printf("频繁三项集:\n");for(i=0;i<5;i++){for(j=0;j<5;j++){for(k=0;k<5;k++){if(l3[i][j][k]>1)printf("I%d I%d I%d:%d\n",i+1,j+1,k+1,l3[i][j][k]);}}}}void LoadIteml4(int data[9][4]){printf("没有频繁四项集!算法结束!\n");}int main(){int data[9][4]={{1,2,5,0},{2,4,0,0},{2,3,0,0},{1,2,4,0},{1,3,0,0},{2,3,0,0},{1,3,0,0},{1,2,3,5},{1,2,3,0},};LoadIteml1(data);LoadIteml2(data);LoadIteml3(data);LoadIteml4(data);return 0;}4)输出运算结果。
apriori算法代码c语言

apriori算法代码c语言Apriori算法是一种常用的关联规则挖掘算法,用于发现数据集中的频繁项集。
本文将使用C语言编写Apriori算法的代码,并解释算法的原理和实现步骤。
一、算法原理Apriori算法是基于频繁项集的产生和剪枝来挖掘关联规则的。
其基本思想是通过迭代的方式,从项集中生成候选项集,并对候选项集进行计数和剪枝,最终得到频繁项集。
二、算法步骤1. 初始化:读取数据集,设置最小支持度阈值和最小置信度阈值。
2. 第一次扫描:统计每个项的支持度计数,得到频繁1-项集。
3. 迭代生成候选项集:根据频繁k-1项集,生成候选k项集。
首先将频繁k-1项集自连接,得到候选k项集的候选项,然后对候选项集进行剪枝,删除不满足最小支持度阈值的候选项集。
4. 第k次扫描:统计候选k项集的支持度计数,得到频繁k项集。
5. 重复步骤3和步骤4,直到无法生成候选项集为止。
6. 生成关联规则:根据频繁项集生成关联规则,并计算规则的置信度。
对于每个频繁项集,可以生成多个关联规则,通过计算规则的置信度来筛选出满足最小置信度阈值的关联规则。
三、代码实现以下是Apriori算法的C语言实现代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>// 数据集char dataset[100][100] = {"A B C","A C","B D","B C","A B D","B C","A","B C D","A B C D","A D"};// 最小支持度阈值int minSupport = 2;// 最小置信度阈值float minConfidence = 0.5;// 项集节点typedef struct itemsetNode {char itemset[100];int support;struct itemsetNode *next;} ItemsetNode;// 频繁项集链表头节点ItemsetNode *head = NULL;// 获取数据集中的所有项void getItems(char *items) {int i, j;char temp[100];strcpy(temp, dataset[0]);strcat(items, strtok(temp, " ")); for (i = 1; i < 100; i++) {strcpy(temp, dataset[i]);char *item = strtok(temp, " "); while (item != NULL) {int flag = 0;for (j = 0; j < strlen(items); j++) { if (items[j] == item[0]) {flag = 1;break;}}if (flag == 0) {strcat(items, item);}item = strtok(NULL, " ");}}}// 判断候选项集是否是频繁项集int isFrequentItemset(char *candidate) { char temp[100];strcpy(temp, candidate);char *item = strtok(temp, " ");while (item != NULL) {int count = 0;for (int i = 0; i < 100; i++) {if (strstr(dataset[i], item) != NULL) {count++;}}if (count < minSupport) {return 0;}item = strtok(NULL, " ");}return 1;}// 生成候选k项集void generateCandidateItemsets(ItemsetNode *k_1Itemsets, ItemsetNode **candidateItemsets) {ItemsetNode *p = k_1Itemsets;while (p != NULL) {ItemsetNode *q = p->next;while (q != NULL) {char candidate[100];strcpy(candidate, p->itemset);strcat(candidate, " ");strcat(candidate, q->itemset);if (isFrequentItemset(candidate)) {ItemsetNode *newNode = (ItemsetNode *)malloc(sizeof(ItemsetNode));strcpy(newNode->itemset, candidate);newNode->support = 0;newNode->next = *candidateItemsets;*candidateItemsets = newNode;}q = q->next;}p = p->next;}}// 计算候选项集的支持度计数void countSupport(ItemsetNode *candidateItemsets) {ItemsetNode *p = candidateItemsets;while (p != NULL) {char temp[100];strcpy(temp, p->itemset);char *item = strtok(temp, " ");while (item != NULL) {for (int i = 0; i < 100; i++) {if (strstr(dataset[i], item) != NULL) {p->support++;}}item = strtok(NULL, " ");}p = p->next;}}// 添加频繁项集到链表void addFrequentItemset(ItemsetNode *candidateItemsets) { ItemsetNode *p = candidateItemsets;while (p != NULL) {if (p->support >= minSupport) {ItemsetNode *newNode = (ItemsetNode *)malloc(sizeof(ItemsetNode));strcpy(newNode->itemset, p->itemset);newNode->support = p->support;newNode->next = head;head = newNode;}p = p->next;}}// 生成关联规则void generateAssociationRules(ItemsetNode *frequentItemsets) {ItemsetNode *p = frequentItemsets;while (p != NULL) {char temp[100];strcpy(temp, p->itemset);int len = strlen(temp);for (int i = 1; i < len - 1; i++) {char left[100], right[100];strncpy(left, temp, i);left[i] = '\0';strcpy(right, temp + i + 1);float confidence = (float)p->support / head->support; if (confidence >= minConfidence) {printf("%s => %s, support: %d, confidence: %.2f\n", left, right, p->support, confidence);}}p = p->next;}}int main() {char items[100] = "";getItems(items);printf("所有项:%s\n", items);// 生成频繁1-项集ItemsetNode *frequent1Itemsets = NULL;for (int i = 0; i < strlen(items); i++) {char item[2] = {items[i], '\0'};int count = 0;for (int j = 0; j < 100; j++) {if (strstr(dataset[j], item) != NULL) {count++;}}if (count >= minSupport) {ItemsetNode *newNode = (ItemsetNode *)malloc(sizeof(ItemsetNode));strcpy(newNode->itemset, item);newNode->support = count;newNode->next = frequent1Itemsets;frequent1Itemsets = newNode;}}// 生成频繁项集head = frequent1Itemsets;ItemsetNode *k_1Itemsets = frequent1Itemsets;while (k_1Itemsets != NULL) {ItemsetNode *candidateItemsets = NULL;generateCandidateItemsets(k_1Itemsets,&candidateItemsets);countSupport(candidateItemsets);addFrequentItemset(candidateItemsets);k_1Itemsets = k_1Itemsets->next;}// 输出频繁项集ItemsetNode *p = head;while (p != NULL) {printf("频繁项集:%s, 支持度计数:%d\n", p->itemset, p->support);p = p->next;}// 生成关联规则。
apriori算法的最小置信度和支持度原则

apriori算法的最小置信度和支持度原则一、Apriori算法简介Apriori算法是一种用于频繁项集挖掘和关联规则学习的经典算法。
它通过发现数据库中项目之间的关联关系,生成频繁项集,并利用这些频繁项集来生成关联规则。
在Apriori算法中,最小置信度和支持度原则是两个重要的概念,它们决定了生成的规则的可靠性和有效性。
二、最小置信度原则最小置信度原则是指规则的置信度至少要达到一个最低的阈值。
规则的置信度是表示一个项集的出现能够导致另一个项集的出现的能力的度量。
在Apriori算法中,最小置信度原则是指在挖掘关联规则时,必须保证规则的置信度不低于给定的最小置信度阈值。
在实际应用中,最小置信度原则可以帮助我们过滤掉那些低置信度的规则,从而提高规则的质量和可信度。
通过设定合适的最小置信度阈值,我们可以更好地理解数据中的关联关系,并生成更有价值的规则。
三、支持度原则支持度原则是Apriori算法中的另一个重要原则,它决定了规则的可行性。
支持度是指规则中左部项集在数据集中出现的频率。
支持度原则要求规则左部项集的支持度不低于给定的支持度阈值。
在实际应用中,支持度原则可以帮助我们筛选出那些具有实际意义的关联规则。
只有当规则左部项集的支持度达到一定水平时,规则才具有实际意义,因为这意味着在数据集中有足够多的数据支持该规则的成立。
四、如何设定最小置信度和支持度原则设定最小置信度和支持度原则时,需要根据数据的特点和实际需求进行权衡和调整。
一般来说,最小置信度原则和最小支持度原则都是通过经验或参考其他类似数据集的结果来设定。
对于不同类型的数据和不同应用场景,可能存在不同的最佳实践和阈值选择。
五、其他注意事项在应用Apriori算法时,还需要注意其他一些事项,如数据预处理、算法优化、安全性等。
例如,在进行数据预处理时,需要清理和规范化数据,以便更好地挖掘隐藏在数据中的关联关系。
同时,对于敏感数据,需要采取适当的安全措施,以保护用户隐私和数据安全。
apriori算法的应用场景

apriori算法的应用场景
Apriori算法是一种广泛应用于数据挖掘中的关联规则学习算法,其应用场景包括以下几个方面:
1. 商业领域:Apriori算法可以用于发现商品之间的关联规则,帮助商家制定营销策略,如推荐系统、交叉销售等。
通过对商品集合进行挖掘,可以发现一些有趣的关联模式,如购买尿布的同时也购买啤酒的客户群体,从而制定更加精准的营销策略。
2. 网络安全领域:Apriori算法可以用于检测网络入侵和异常行为。
通过对网络流量和日志数据进行挖掘,可以发现异常模式和关联规则,从而及时发现潜在的攻击行为。
3. 高校管理领域:Apriori算法可以用于高校贫困生资助工作。
通过对贫困生相关数据的挖掘,可以发现一些关联规则和群体特征,从而为资助工作提供更加科学和精准的决策支持。
总之,Apriori算法是一种广泛应用于数据挖掘中的关联规则学习算法,其应用场景非常广泛,可以帮助企业和组织更好地理解和利用数据,制定更加科学和精准的决策。
h a r s h 表 算 法

python数据结构课堂笔记5:排序与查找排序与查找文章目录排序与查找查找算法顺序查找算法分析二分查找算法分析排序算法冒泡排序和选择排序算法冒泡排序Bubble Sort算法分析选择排序插入排序谢尔排序归并排序算法分析快速排序算法分拣+分裂快速排序的递归三要素算法分析总结稳定排序其他排序睡眠排序散列:Harshing完美散列函数区块链技术散列函数设计折叠法平方取中法对比非数项散列函数不能成为存储过程和查找过程的负担冲突解决方案开放定址法线性探测的改进再散列rehashing数据项链映射抽象数据类型抽象数据类型映射:Map散列算法分析总结查找过程的信息排序过程中的比较信息一阶信息二阶隐含信息具有先验信息的排序算法查找算法顺序查找如果数据项保存在列表这样的集合中,我们会称这些数据项具有线性或者顺序关系在python list中,这些数据项的存储位置称为下标(index),这些下标都是有序的整数通过下标,我们就可以按照顺序来访问和查找数据项,这种技术叫做“顺序查找”要确定列表中是否存在需要查找的数据项首先从列表的第一个数据项开始,按照下标增长的顺序,逐个比对数据项如果到最后一个都未发现要查找的项,那么查找失败无序表中进行顺序查找:def sequentialSearch(alist, item):found = Falsewhile pos len(alist) and not found:if alist[pos] == item:found = Truepos = pos+1#下标顺序增长return foundtestlist = [1, 2, 32, 8, 17, 19, 42, 13, 0]print(sequentialSearch(testlist, 3))print(sequentialSearch(testlist, 13))算法分析要对查找算法进行分析,首先要确定其中的计算步骤基本计算步骤必须足够简单,并且在算法中反复执行在查找算法中,这种基本步骤就是进行数据项的比对当前数据项等于还是不等于要查找的数据项,比对的次数决定了算法复杂度在顺序的查找算法中,为了保证是讨论的一般情况,需要假定列表中的数据项并没有按值排序,而是随机放置在表中的各个位置。
基于散列的频繁项集分组算法

基于散列的频繁项集分组算法作者:王红梅胡明来源:《计算机应用》2013年第11期摘要:Apriori算法是频繁项集挖掘的经典算法。
针对Apriori算法的剪枝操作和多次扫描数据集的缺点,提出了基于散列的频繁项集分组(HFG)算法。
证明了2项集剪枝性质,采用散列技术存储频繁2项集,将Apriori算法剪枝操作的时间复杂度从O(k×|Lk|)降低到O(1);定义了首项的子项集概念,将数据集划分为以Ii为首项的数据子集并采用分组索引表存储,在求以Ii为首项的频繁项集时,只扫描以Ii为首项的数据子集,减少了对数据集扫描的时间代价。
实验结果表明,由于HFG算法的剪枝操作产生了累积效益,以及分组扫描排除了无效的项集和元组,使得HFG算法在时间性能方面与Apriori算法相比有较大提高。
关键词:频繁项集;2项集剪枝;散列表;首项分组;索引表0引言随着频繁项集挖掘应用领域的扩展,吸引了很多学者加入研究,提出了许多频繁项集挖掘算法,其中,美国学者Agrawal等[1]提出的Apriori算法是一个里程碑,其基本原理是用频繁k项集找出候选频繁(k+1)项集,再扫描数据集得到频繁(k+1)项集及其支持度。
Apriori算法的缺点是产生大量候选频繁项集,并且需要多次扫描数据集。
针对Apriori算法的缺点,很多学者对Apriori算法进行了改进研究,如采用FP树(FrequentPattern tree)存储数据集[2-4]、采用垂直格式存储数据集[5-6]、采用散列表存储候选频繁项集[7]、分段计算支持度[6,8-10]、不产生候选项集[2-3]等。
近年来,有学者提出基于概念格的挖掘算法[11]、基于滑动窗口的挖掘算法[12]等。
本文针对Apriori算法的剪枝操作和多次扫描数据集的缺点,证明了非频繁2项集剪枝性质,采用散列表存储频繁2项集,在O(1)时间完成了与Apriori算法同样的剪枝操作;定义了首项的子项集概念,将数据集按首项进行分组,在求以Ii为首项的频繁项集时,只扫描以Ii 为首项的数据子集,从而减小了对数据集扫描的时间代价;在此基础上,提出了基于散列的频繁项集分组(Hashbased Frequent itemsets Grouping, HFG)算法。
pcy算法、多阶段算法、多哈希算法、xfp-tree算法、gpapriori算法等关联规则算法

PCY算法、多阶段算法、多哈希算法、XFP-Tree算法和GPApriori算法都是关联规则挖掘中的重要算法。
这些算法在处理大规模数据集、提高挖掘效率和精度等方面各有优势。
PCY算法是一种概率计数算法,主要用于挖掘频繁项集和关联规则。
该算法基于哈希函数和Bloom Filter实现,通过扫描数据集统计候选项集的出现次数,并利用支持度阈值筛选出频繁项集。
PCY 算法在内存消耗和时间效率方面优于Apriori算法,适用于大数据集的关联规则挖掘。
多阶段算法将关联规则挖掘过程分为多个阶段,每个阶段处理数据的一部分,并逐步缩小候选项集的范围。
这种算法通过将问题拆解为多个小问题来解决,提高了挖掘过程的灵活性和效率。
多哈希算法是一种利用多个哈希函数将数据映射到固定长度的字符串中的方法,常用于关联规则挖掘中的项集计数。
通过多个哈希函数将数据分散到不同的桶中进行计数,可以减少碰撞和提高计数精度。
XFP-Tree算法是一种基于树的数据结构,用于关联规则挖掘中的频繁项集挖掘。
该算法利用多核并行处理技术,在不同的CPU核上构建FP树,提高了挖掘效率。
XFP-Tree算法通过位图矢量记录事务信息,支持项集的快速计数和频繁项集的生成。
GPApriori算法是对Apriori算法的一种改进,利用GPU进行并行计算,提高了挖掘速度。
该算法使用字典树保存候选项集,通过纵向事务列表实现支持度计算的可并行化,从而提高了大规模数
据集上的关联规则挖掘效率。
这些算法在关联规则挖掘中各自发挥其优势,根据具体应用场景和数据特点选择合适的算法可以提高挖掘的效率和精度。
如需更多信息,建议查阅相关文献或咨询专业人士。
apriori算法例题详解

apriori算法例题详解Apriori算法是数据挖掘中比较常用的一种关联规则挖掘方法。
它的原理是通过一系列的频繁项集发现和剪枝来发现数据集中的规律关联性。
今天,我们来看一下Apriori算法的一个例题。
假如我们有一个包含多个交易记录的购物篮数据集,每个记录包含了一些商品(例如牛奶,面包,黄油等),我们想要根据这些记录来挖掘出一些常见的商品组合以及它们之间的关联性。
下面是一个具体的例子:交易记录商品------------------T100 牛奶、面包、黄油T200 牛奶、面包、黄油、葡萄酒T300 牛奶、面包、黄油T400 牛奶、豆腐、葡萄酒T500 面包、黄油、豆腐首先,我们需要根据这些记录来生成一个物品集合表,表中记录着每一件商品在数据集中出现的频率以及它们的支持度。
可以看一下下表:物品集合支持度------------------牛奶 4面包 4黄油 4豆腐 2葡萄酒 2由于我们只想保留那些在数据集中出现频率较高的商品组合,因此需要设定一个最小支持度的阈值。
我们假设最小支持度的阈值为50%。
接下来,我们可以使用Apriori算法来发现频繁项集。
Apriori算法的基本思路是,首先找出所有的频繁1项集(即单独的商品),然后通过组合形成频繁2项集,接着通过组合频繁2项集来形成频繁3项集,以此类推。
根据Apriori算法的原理,不可能存在一个k项集是不频繁的,同时它的所有子集都是频繁的。
因此,在生成候选k+1项集的时候,我们只需要保留那些所有k项子集都是频繁的候选项集,这样就避免了无意义的计算。
假设我们首先要找出频繁2项集。
根据上述物品集合表,我们可以获得所有的频繁1项集:{牛奶},{面包},{黄油},{豆腐},{葡萄酒}。
然后我们可以通过这些频繁1项集来生成候选2项集,如下表所示:候选2项集支持度------------------{牛奶,面包} 3{牛奶,黄油} 3{牛奶,豆腐} 1{牛奶,葡萄酒} 1{面包,黄油} 3{面包,豆腐} 1{面包,葡萄酒} 1{黄油,豆腐} 1{黄油,葡萄酒} 1{豆腐,葡萄酒} 0由于最小支持度的阈值为 50%,因此我们只需要保留那些支持度值大于等于 2 的候选2项集,如下表所示:频繁2项集支持度------------------{牛奶,面包} 3{牛奶,黄油} 3{面包,黄油} 3接下来,我们需要根据这些频繁2项集来找出频繁3项集。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于Hash表的改进Apriori算法 钟育彬;李健标 【摘 要】Apriori algorithm is a classic association analysis mining algorithm, but the Apriori algorithm is inefficient and requires multiple scans in the database. In response to these problems, an Improved Apriori Algorithm Based on Hash Tables is proposed here. When the Improved Apriori Algorithm Based on the Hash Tables is calculating, only the corresponding items in the corresponding frequent itemset Hash table need to be scanned, the scanning range is reduced, the calculation efficiency is improved significantly, and the database needs to be only scanned once. Compared with the classic Apriori algorithm, the performance is significantly improved.%Apriori算法是一种经典的关联分析挖掘算法.经典Apriori算法计算效率偏低, 并且需要多次扫描数据库.针对这些问题, 文章提出了基于Hash表改进的Apriori算法.基于Hash表的改进Apriori算法计算时只需扫描对应频繁项集Hash表中对应的项, 缩小了扫描范围, 并且只需要扫描一次数据库.对比经典的Apriori算法, 性能具有显著提高.
【期刊名称】《广州大学学报(自然科学版)》 【年(卷),期】2018(017)006 【总页数】3页(P7-9) 【关键词】Apriori算法;最小支持度;频繁项集;Hash表 【作 者】钟育彬;李健标 【作者单位】广州大学数学与信息科学学院, 广东 广州 510006;广州大学数学与信息科学学院, 广东 广州 510006
【正文语种】中 文 【中图分类】O24
Apriori算法是由AGRAWAL等[1]提出的经典关联规则挖掘算法[2-3], 广泛应用在各个领域, 通过其关联分析和挖掘, 为政府和企业分析决策提供客观本质的具参考价值的信息. 经典的Apriori算法通过逐层迭代的方法从低阶频繁项集中产生高阶频繁项集[4],候选项目支持度的计算是通过多次扫描整个数据库, 计算效率低, 随着项集数量的增加, 计算的数量会急剧增加, 运行时间也会急剧增加. 笔者根据实际情况提出的企业综合评价系统中的模糊层次综合评价模型涉及到关联分析[5], 可以解决数据量巨大并且运行时间长的问题, 因此,本文与经典的Apriori算法结合改进, 提高计算效率. 1 相关概念 1.1 k-项集和支持度计数 令I={i1,i2,…,id}是数据中所有项的集合, T={t1,t2,…,tN}是所有事务的集合. 每个事务包含的项集都是I的子集. 如果一个项集包含k个项, 则称其为k-项集. 事务的宽度定义为事务中出现项的个数. 如果项集X是事务tj的子集, 则称事务tj包括项集X. 项集X的支持度计数σ(X)可表示为 σ(X)=|{ti|X⊆ti,ti⊆T}|. 1.2 关联规则 关联规则是形如X→Y的蕴涵表达式, 其中不相关的项集关联规则的强度可以用它的支持度和置信度度量. 支持度确定规则可以用于给定数据集的频繁程度, 而置信度确定Y在包含X的事务中出现的频繁程度. 支持度(s)和置信度(c)的形式定义为 1.3 最小支持度计数与频繁项集 最小支持度计数:设最小支持度为minsup, N为事务数量, 最小支持度计数n=N×minsup, 如果n有小数部分, 则n进1. 频繁项集:支持度计数大于等于最小支持度计数的所有项集称为频繁项集. 1.4 频繁项集产生 初始扫描整个数据库, 计算候选1-项集支持度计数, 删除非频繁项, 得到频繁1-项集. 候选k-项集(k≥2)由频繁(k-1)-项集产生, 再扫描整个描数据库计算支持度计数, 删除非频繁项, 得到频繁k-项集. 以此类推迭代, 直到不能产生频繁项集, 则算法停止. 由于每次计算候选k-项集的支持度都要扫描整个数据库, 因此计算量很大, 随着项集数量的增加, 计算的数量会急剧增加, 运行时间也会急剧增加. 2 算法的改进 设最小支持度为30%, 最小支持计数n为9×30%=2.7, n取3, 见表1. 表1表示项目和事务, 有6个项目和9个事务. 扫描数据库, 转换为Hash表储存事务数据[6], 构造1-项集Hash表, 见表2. 表1 事务与项目Table 1 Transactions and itemsets事务项目1I1 I2 I62I3 I63I4 I54I3 I45I1 I2 I66I1 I2 I4 I67I2 I4 I58I1 I2 I49I1 I2 I6 表2 1-项集Hash表Table 2 1-itemset Hash table项目事务I11 5 6 8 9I21 5 6 7 8 9I32 4I43 4 6 7 8I53 7I61 2 5 6 9 根据最小支持计数可以舍弃I3和I5. 删除非频繁项, 构造频繁1-项集Hash表, 见表3. 表3 频繁1-项集Hash表Table 3 Frequent 2-itemset Hash table项目事务I11 5 6 8 9I21 5 6 7 8 9I43 4 6 7 8I61 2 5 6 9 对于k-项集(k≥2),k-项集候选项Ii1i2…ik-2ii-1ik的事务由Ii1j2…ik-2ik-1与Ii1j2…kk-2Iik相交得到,并且iiIi1j2…ik-2Iik属于频繁(k-1)-项集Hash表,并且前(k-2)-项相同,Iiij2…ik-2ik-1ik=Ii1i2…ik-2ik-1∩Ii1j2…ik-2Iik. 计算完成后构造k-项集Hash表,删除非频繁项,构造频繁k-项集的Hash表.之后删除频繁(k-1)-项集Hash表,这样做可以避免造成不必要的内存浪费. 对于候选项Iij的支持度计数, 由频繁1-项集Hash表中的Ii与Ij相交得到, 即Iij=Ii∩Ij. Ii与Ij属于频繁1-项集Hash表. 2-项集的候选项为I12, I14, I16, I24, I26, I46.构造2-项集Hash表, 见表4. 删除非频繁项, 构造频繁2-项集Hash表, 见表5. 对于3-项集, 候选项集为I126和I246,I126=I12∩I16, I246=I24∩I26, 其中I12, I16, I24, I26属于频繁2-项集的Hash表. 构造3-项集Hash表, 见表6. 表4 2-项集Hash表Table 4 2-itemset Hash table项目事务I121 5 6 8 9I146 8I161 5 6 9I246 7 8I261 5 6 9I466 表5 频繁2-项集Hash表Table 5 Frequent 2-itemset Hash table项目事务I121 5 6 8 9I161 5 6 9I246 7 8I261 5 6 9 表6 3-项集Hash表Table 6 3-itemset Hash table项目事务I1261 5 6 9I2466 删除非频繁项, 构造频繁3-项集Hash表, 见表7. 表7 频繁3-项集Hash表Table 7 Frequent 3-itemset Hash table项目事务I1261 5 6 9 由于没有候选4-项集, 因此没有频繁4-项集, 计算停止. 基于Hash表的改进Apriori算法先将事务转换为Hash表保存, 因此,只需要扫描1次整个数据库. 计算候选k-项集(k≥2)的支持度只需要扫描频繁(k-1)-项集Hash表中对应的2个频繁(k-1)-项集, 对比需要扫描整个数据库计算候选k-项集的支持度的经典Apriori算法,缩小了扫描范围, 提高了效率. 3 实验对比分析 为了比较基于Hash表改进的Apriori算法与经典Apriori算法的效率, 该文对进行了实验对比. 测试环境为:电脑Intel(R)Core(TM)i5-4660S, CPU为2.9 GHz, 内存为8 G, 操作系统为Windows10, 编译软件为python3.6. 数据库为关联规则挖掘Apriori算法的改进与实现中提供的蘑菇数据[4], 有8 124条记录, 22个属性. 实验结果如表8所示, 基于Hash表的改进Apriori算法对比经典Apriori算法在支持度较小的时候具有绝对优势. 从表8可见,在最小支持度为0.3时, 基于Hash表改进的Apriori算法对比经典Apriori算法运行的时间具有绝对优势, 在最小支持度为0.35时, 虽然经典Apriori算法的运行时间快了很多, 但基于Hash表的改进Apriori算法依然占据优势. 随着支持度的增加, 2者运行时间不断降低,并且差距缩小. 表8 运行时间对比Table 8 Comparation of running time最小支持度/%基于Hash表的改进Apriori算法/s经典Apriori算法/s3058.67699.283511.75152.49404.5628.71452.6910.74500.982.75550.641.19 4 总 结 经典的Apriori算法计算候选k-选项集的支持度需要多次扫描整个数据库, 并且随着事务的增加候选项集会急剧增加, 运行时间也会急剧增加. 基于Hash表的改进Apriori算法先将事务转换为Hash表保存, 因此,只需要扫描一次整个数据库, 节省了扫描数据库的时间开支, 计算k-项集(k≥2)候选项的支持度计数只需扫描频繁(k-1)-项集Hash表中对应的2个(k-1)-项集, 对比经典的Apriori算法缩小了扫描