研究生课程《数据仓库与数据挖掘》实验报告
实验题目: 频繁模式挖掘试验
——Apriori 算法
指导教师:李爱国
学生姓名:刘二恩 201008378
程 城 201008374
专 业:计算机应用技术
完成日期:2011-07-06
西安科技大学计算机科学与技术学院
实验题目:
频繁模式挖掘实验——Apriori 算法
学生姓名: 刘二恩 程 城 学号: 201008378 201008374
完成日期: 2011.07.06
1 实验目的
(1)理解频繁模式挖掘的思想;
(2)理解 Apriori 挖掘算法的原理;
(3)通过 Apriori 算法找出 ch6 关联规则挖掘数据集所有的频繁模式集;
2 实验步骤
2.1 算法原理
Aprior 使用一种称作逐层搜索的迭代方法,K 项集用于搜索(K+1)项集。首先,通过
扫描数据库,累积每个项的计数,并收集满足最小支持度的项,找出频繁 1 项集的集合。该
集合记作 L1。然后,L1 用于寻找频繁 2 项集的集合 L2,L2 用于寻找 L3,如此下去,直到
不能再找到频繁 K 项集。
为提高频繁项集逐层产生的效率,一种称作 Apriori 的重要性质用于压缩搜索空间。
Apriori 性质:频繁项集的所有非空子集也必须是频繁的。如何在算法中使用 Apriori 性质?
主要有两步过程组成:连接步和剪枝步。
(1) 连接步:为找 L(k),通过将 L(k-1)与自身连接产生候选 K 项集的集合。该候选项
集合记作 C(K)。设 l1 和 l2 是 L(k-1)中的项集。记号 l(i)[j]表示 l(i)中的第 j 项。执行
L(k-1)连接 L(k-1),如果它们的前(K-2)项相同的话,其中 L(k-1)的元素是可连接的。
(2) 剪枝步:为压缩 C(K),可以用 Apriori 的性质:任何非频繁的(K-1)项集都不是
频繁 K 项集的子集。因此,如果候选 K 项集的(K-1)项子集不在 L(k-1)中,则该候选也不
可能是频繁的,从而可以从 C(K)中删除。
2.2 算法步骤
算法第一步是简单统计所有含一个元素的项集出现的频率,来决定最大的一维项目
集,在第 k 步,分两个阶段,首先用一函数 sc_candidate,通过第(k-1)步中生成最大项
目集 1kL 来生成候选项目集 kC ,然后搜素数据库计算候选项目集 kC 的支持度。
Apriori 算法描述如下:
(1)
1C ={candidate 1-itemset};
1
(2)
1L ={c 1C |c.count minsupport};
(3)For (k=2,
1kL
,k++)
(4)
(5)for
kC =sc_candidate(
1kL
all transaction tD
);
(6)
1C =count_support(
kC ,t)
(7) for
all candidates c 1C
(8) c.count=c.count + 1;
(9) next
(10)
kL ={c kC |c.count minsupport};
(11)Next
(12)Resultset=resultset kL
其中,D 表示数据库;minsupport 表示给定的最小支持度;resultset 表示所有最大项目
集。k-itemset 表示 k 维项目集;
kL :具有最小支持度的最大 k-itemset;
kC :候选的 k-
itemset(潜在最大项目集)
2.3 程序流程图
程序的主体部分首先接收用户输入的最小支持度,之后读取原始数据。产生频繁 1 项
集的集合
1L ,之后用 1kL 产生候选
kC ,以找出
如图 1 所示是 Apriori 算法的程序流程图。
kL ,其中 k>=2;
2
图 1 Apriori 算法流程图
3 实验结果分析
1.当输入的最小支持度为 2 的时候,此时程序的运行时间是比较长的。运行结果如图 2 所示:
图 2 最小支持度=2 时的结果图
3
2.当当输入的最小支持度较大的时候,此算法产生频繁项集的效率挺快的。
例如,最小支持度 7 的时候,程序运行结果如图 3 所示:
图 3 最小支持度=7 时的结果图
4 实验心得体会
问题:当原始数据较多并且最小支持度设置的较小的时候,运行效率较低。
现象:程序在较长时间内一直在运行。
分析:当最小支持度设置的较小的时候,算法需要重复扫描原始数据,这就使得
程序的运行效率比较低。
解决:可以改变算法的数据结构,使算法不需要重复扫描原始数据或者较少的扫描原
始数据。
5 参考文献
[1] Jiawei Han Micheline Kamber 著.范明 孟小峰译,数据挖掘感念于技术,机械工业出版
社,2007.3
[2] 王运峰,张蕾,韩纪富等,数据库中关联规则的并行挖掘算法.计算机工程与应用,2001
4
附录(源代码)
1. Apriori.h
#pragma once //此头文件只被编译一次
#include
#include
#include
using namespace std;
class Apriori
{
struct ITEM
{
vector ContentLst;
//此项的内容
long nCol;
long nCount;
//此项的列数
//此项的计数
};
private:
string *m_pData;
//数据集的地址
long m_nRowCount;
//数据集的项的个数
long m_nColCount;
//数据集的项的列数的最大值
int m_minSupport;
//最小支持度
vector- m_Result;
//最后的筛选结果
public:
Apriori(void);
bool SetData(string *pData, int nRowCount, int nColCount);
//设置数据
bool Statistics(vector
- &contentLst);
//统计候选
集里所有项的计数
bool Link(ITEM *pItem1, ITEM *pItem2, ITEM &itemResult);
//链接
5
bool Link(vector- &contentLst);
bool Pruning(vector
- &contentLst, int nCount);
bool Run(void);
Apriori 算法
void PrintResult(void);
果
void SetMinSupport(int nSupport);
//剪枝
//运行
//打印结
//设置最
小支持度
~Apriori(void);
};
2. Apriori.cpp
#include "Apriori.h"
Apriori::Apriori(void)
{
}
m_nRowCount = 0;
m_nColCount = 0;
m_pData = NULL;
m_minSupport = -1;
Apriori::~Apriori(void)
{
}
m_pData = NULL;
bool Apriori::SetData(string *pData, int nRowCount, int nColCount)
{
if (pData == NULL)
{
6
return false;
}
m_pData = pData;
m_nRowCount = nRowCount;
m_nColCount = nColCount;
return true;
}
bool Apriori::Statistics(vector- &contentLst)
{
int nLength = contentLst.size();
int i,j,r;
ITEM itemTmp;
string str;
for (int nrow=0; nrow