Apriori演算法Matlab實現
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