1. 程式人生 > >Apriori演算法Matlab實現

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