clc;
clear;
%最小支持度设定
min_sup=2;
%最小置信度
min_conf=0.7;
%读取文件,当前的文件类型是txt文件,事务数据用数字来表示的,测试数据可以用《数据挖掘概念与技术》第三版中的数据为样本
fid=fopen('D:\matlabFile\Apriori\dataApriori.txt','r');
%记录读取的行号,与实际的事务数相对应,同时为了分配存储空间
NumEvent=1;
%新建事务数据集,由于各个事务的长短不一致,所以采用cell类型
Dataset=cell(1,1);
%循环读取文件,按行读取
while(~feof(fid))
lineinfo=fgetl(fid);
%将字符转换为数字组成的数组
c=str2num(lineinfo);
%空行,重新读下一行
if (isempty(lineinfo))
continue;
end
%将一条(一行)事务数据添加到事务数据集中
Dataset{NumEvent,1}=c;
%行号加1
NumEvent=NumEvent+1;
end
%将行号减1,上述的循环在结束时多加了1
NumEvent=NumEvent-1;
%结束文件读取,关闭文件
fclose(fid);
%临时事务数据集,用于运算操作
Dataset_temp=Dataset;
%%%第一次扫描Dataset,统计每一个候选项,并存在二维数组中
%用来控制循环结束的标记
flag=1;
%统计每条事务中包含‘项’的个数
count=1;
%保存频繁项
C_result=[];
%保存频繁项,包含支持度计数,
C1_result=[];
%保存所有临时的频繁项
C=[];
while flag==1
%单项数据集,用来存放事务中包含的所有的单项,不包含其个数
C_temp=zeros(1,1);
%对所有单项进行统计,注意第一次循环与后面的循环用的数组有所区别
if count==1
%获取临时事务集中事务的个数
NumEvent=length(Dataset_temp);
for i=1:NumEvent
%获得第i条事务中单项的个数
for j=1:length(Dataset_temp{i})
%查看第i条事务第j个单项是否已经存在于单项数据集中,如存在则继续循环,否则增加新的单项
result=find(C_temp==Dataset_temp{i}(1,j));
%如果查询的结果为空,则增加新的单项
if isempty(result)
C_temp=cat(1,C_temp,Dataset_temp{i}(1,j));
end
end
end
else
NumEvent=size(C,1);
for i=1:NumEvent
%获得第i条事务中单项的个数
for j=1:length(C(i,:))
%查看第i条事务第j个单项是否已经存在于单项数据集中,如存在则继续循环,否则增加新的单项
result=find(C_temp==C(i,j));
%如果查询的结果为空,则增加新的单项
if isempty(result)
C_temp=cat(1,C_temp,C(i,j));
end
end
end
end
%删除第一行空值,此时所有的单项都已经被统计出来
C_temp(1,:)=[];
%对所有单项按照单项的个数进行组合
C=nchoosek(1:1:length(C_temp),count);
C1=C;
%建立一个零值矩阵,
cc=zeros(size(C1,1),1);
%在C1矩阵的右侧增加一列零值
C1=cat(2,C1,cc);
%将候选项与事务集进行比较,并统计个数
for i=1:size(C,1)
num=0;
%获得事务数据集中事务的个数
for j=1:length(Dataset)
%设定循环结束标记
flag_1=1;
for m=1:size(C,2)
a=num2str(C(i,m));
%将事务数据集中的第j条事务转变为字符串
b=num2str(Dataset{j});
b(find(isspace(b)))=[];
%判断字符串a是否存在于字符串b中
n=strfind(b,a);
if length(n)==0
flag_1=0;
break;
end
end
if flag_1==1
num=num+1;
end
end
C1(i,size(C1,2))=num;
end
%把item数量小于支持度的项删除
col=size(C1,2);
%寻找小于最小支持度的行号
result=find(C1(:,col)<min_sup);
%如果无结果,继续循环,增加维数
if isempty(result)
count=count+1;
continue;
end
%找到上述行号所对应的行
row=unique(result);
%删除这些行
C(row,:)=[];
C1(row,:)=[];
%如果c为空,则终止此次循环
if isempty(C)
flag=0;
else
%否则,计数器加一
count=count+1;
%将符合最小支持度的项加入到结果集中
C_result=C;
%将符合最小支持度的项加入到结果集中,最后一列包含该项的支持度
C1_result=C1;
end
end
association=cell(1,3);
n_conf=1;
%%%%%%%%%%%%% 生成关联规则 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:size(C_result,1)
n=size(C_result,2)-1;
if n==0
continue;
end
for j=1:n
nn=n+1;
R=nchoosek(1:1:nn,j);
for k=1:size(R,1)
c=[];
for m=1:size(R,2)
c=cat(2,c,C_result(i,R(k,m)));
end
buf=C_result(i,:);
%计算置信度
num=0;
for y=1:length(Dataset)
flag_2=1;
for m=1:size(c,2)
result=find(buf==c(1,m));
isempty(result)
if isempty(result)==0
col=unique(result);
buf(:,col)=[];
end
a=num2str(c(1,m));
b=num2str(Dataset{y});
b(find(isspace(b)))=[];
l=strfind(b,a);
if length(l)==0
flag_2=0;
break;
end
end
if flag_2==1
num=num+1;
end
end
if num==0
continue;
end
conf=C1_result(i,n+2)/num;
if conf>=min_conf
%将组合的item放置在关联规则结果中
association{n_conf,1}=c;
%将差值放入第二栏中
association{n_conf,2}=buf;
association{n_conf,3}=conf;
n_conf=n_conf+1;
end
end
end
end
实验数据如下,请下载保存为dataApriori.txt:
1 2 5
2 4
2 3
1 2 4
1 3
2 3
1 3
1 2 3 5
1 2 3