Apriori演算法簡介:
想必大家都知道apriori演算法的原理吧,最著名的關聯規則探索方法R.Agrawal提出的Apriori演算法。 1 Apriori 演算法的基本思想 2 Apriori演算法的基本思想是通過對資料庫的多次掃描來計算項集的支援度,發現的頻繁項集從而產生關聯規則。Apriori演算法對資料集進行多次掃描。第一次掃描得到頻繁1-項集的集合,第k(k>1)次掃描的結果來產生候選k-項集的集合,然後在掃描的過程中確定中元素的支援度,最後在每一次掃描結束時計算頻繁k-項集的集合,演算法在當候選k-項集的集合為空白時結束。 Apriori演算法產生頻繁項集的過程
產生頻繁項集的過程主要分為串連和剪枝兩步:
(1)串連步。為找到(k>=2),通過與自身作串連產生候選k-項集的集合。設和是中的項集。記表示的第j個項。Apriori演算法假定事務或項集中的項按字典次序排序;對於(k-1)項集,對應的項排序為。如果的元素和的前(k-2)個對應項相等,則和。即如果時,和可串連。條件可以保證不產生重複,而按照次序尋找頻繁項集可以避免對交易資料庫中不可能發生的項集所進行的搜尋和統計工作。串連和產生的結果項集為()。
(2)剪枝步。由Apriori演算法的性質可知,頻繁k-項集的任何子集必須是頻繁項集。由串連產生的集合需要進行驗證,去除不滿足支援度的非頻繁k-項集。 Apriori演算法的主要步驟
(1)掃描全部資料,產生候選1-項集的集合.
(2)根據最小支援度,由候1-選項集的集合產生頻繁1-項集的集合。
(3)對k>1,重複執行步驟(4)(5)(6)。
(4)由執行串連和剪枝操作,產生候選(k+1)-項集集合。
(5)根據最小支援度,由候選(k+1)-項集的集合,產生頻繁(k+1)-項集集合。
(6)若L,則k=k+1,跳往步驟(4);否則,跳往步驟(7)。
(7)根據最小信賴度,由頻繁項集產生強關聯規則,結束。 Apriori演算法描述
輸入:資料庫D,最小支援度閾值min_sup。
輸出:D中的頻繁項集L。
(1)Begin
(2)=1-頻繁項集;
(3)for(k=1;);k++)do begin
(4)=Apriori_gen();{調用函數Apriori_gen()}通過頻繁項集(k-1)-項集產生候選項k-項集}
(5)for 所有資料集 do begin{掃描D用於計數}
(6)=subset(,t);{用subset找出該事物中候選的所有子集}
(7)for 所有候選集 do
(8)c.count++;
(9)end
(10)
(11)end
(12)end
(13)Return {形成頻繁集集合}
MATLAB實現Apriori演算法的過程:
演算法一:掃描資料庫產生布爾矩陣後,對這個布爾矩陣進行操作,通過Apriori的串連步剪枝步找到其候選項集,然後把候選項集產生候選項集向量,比如資料庫中的事務集有5個項,5個事務:事務矩陣T
這就是產生的布爾矩陣,其中T代表的是事務,I代表的是項(屬性),怎樣掃描這個事務矩陣呢。這個演算法中是用候選項集向量匹配事務矩陣中的每一行,比如候選2-項集為{}那麼它的候選2-項集的向量為s=[0 1 1 0 0],為了求出此候選集的支援度,直接用s分別和事務矩陣的每行做內積,即sum=s./T(i,:),i為T的行數,第i行
如果 sum==2 則此候選項集的支援度計數+1
這樣就求出了此候選項集的支援度了。
Apriori.m
function Apriori(T, minSup) M = size(T,1);%事務數 N = size(T,2);%屬性數 C=cell(1,N); STCount=sum(T)/M;%候選集的支援度 for r=1:N C{r}=r; end L=C(STCount>minSup);%把count裡面的>=MST的值找出來 LL=L; ICount=sum(T,2);%T矩陣的各行之和 k=1;%頻繁項集的項? disp(numel(L));% Initialize Counter k=1;%頻繁項集的項數 B=[]; BB=reshape(cell2mat(L),1,numel(L)); % Iterations while ~isempty(L)%可以直接用這個isempty()函數來判空。while迴圈是產生頻繁項集的大迴圈41-87行,由L{k}-->L{k+1}變化 C={}; %L={}; u=0; for r=1:numel(L) for i=r:(numel(L)-1) x1=L{r}; x2=L{i+1}; if k==1 c=0; else y1=x1; y2=x2; y1(k)=[]; y2(k)=[]; c = sum(y1==y2);%求兩個候選集的交集 end if (c==k-1)%判斷1.交集長度是否為1,2.判斷交集c和x1前le-1相同的個數是否le-1 NEW=x1; NEW(k+1)=x2(k); sub_set=subset(NEW);%求NEW的子集 %產生該候選項的所有K-1項子集 len=length(sub_set); %判斷這些K-1項自己是否都為頻繁的 p=1; n=0; while(p && n<len) n=n+1;%計數子集屬於頻繁項集的個數 if k==1 p=in(sub_set{n},BB);%in函數判斷NEW子集是否屬於L頻繁項集 else p=in(sub_set{n},B);%in函數判斷NEW子集是否屬於L頻繁項集 end end if n==len%如果計數n和len相等,則其子集全部屬於頻繁項集 u=u+1; %候選k項集 C{u}=NEW;%把這個合格NEW集歸於C候選集合 end else break; end end end L={}; w=0; for r=1:numel(C) SS=zeros(N,1); SS(C{r})=1; Sup=sum(T*SS==k+1)/M; if Sup > minSup w=w+1; L{w}=C{r}; end end B=reshape(cell2mat(L),k+1,numel(L)); disp(numel(L));%%%%%%%%%%%%%%%%%% clear C; k=k+1; endend
BooleMatrix.m把資料轉化為布爾矩陣,注意讀入的資料一定是每行資料的個數一致
function [ B ] = BooleMatrix(A)%UNTITLED Summary of this function goes here% Detailed explanation goes hereM=size(A,1);N=size(A,2);B=zeros(M,119);for i=1:M for j=1:N B(i,A(i,j))=1; end endend
in.m判斷候選項集的子集是否頻繁項集
function [re]=Copy_of_in(a,b)re=0;b=b';m=size(b,1);n=length(a); if(sum(all(b == repmat(a,size(b,1),1),2))==1) re=1; endend
Main.m主函數,運行這個檔案就可以
function Main() load mushroom.mat; MushroomBooleMatrix=BooleMatrix(mushroom); minSup = 0.2; Apriori(MushroomBooleMatrix,minSup);end
subset.m求出候選項集的子集
function [a]=subset(b)%對於含有k個元素的集合,產生該集合的所有k-1項子集%產生過程,用全集分別減去某一個元素就可以得到一個K-1項子集m=length(b);a{1}=b(2:m); for i=2:m NEW=b; NEW(i)=[]; a{i}=NEW; endend
演算法二:這個演算法和上個演算法不同之處在於,這個演算法求支援度時是把候選項集所對應的事務矩陣的列找出來進行求“與”操作,比如某候選2-項集為{},則取出這兩列的事務矩陣進行相”與”操作,即:[11011]&[11100]=[1 1 0 0 0]則此候選2-項集的支援度計數為2;其他類此。代碼如下:
Apriori找頻繁項集的函數
function Apriori(T, minSup) M = size(T,1);%事務數 % Number of attributes in the dataset N = size(T,2);%屬性數 % Find frequent item sets of size 1 (list of all items with minSup) L={}; for i = 1:N S = sum(T(:,i))/M; if S >= minSup L = [L; i]; end end LL=L; %Find frequent item sets of size >=2 and from those identify rules with minConf % Initialize Counter disp(numel(LL));%%%%%%%%%%%%%%%%%%%%%%%% Initialize Counter k=1;%頻繁項集的項數% Iterations while ~isempty(LL)%可以直接用這個isempty()函數來判空。while迴圈是產生頻繁項集的大迴圈41-87行,由L{k}-->L{k+1}變化 C={}; L={}; w=0; for r=1:numel(LL) for i=r:(numel(LL)-1) Ecount=0; for j=1:(k-1) if(LL{r}(j)==LL{i+1}(j)) Ecount=Ecount+1; else break; end end if(Ecount==(k-1)) w=w+1; NEW=LL{r}; NEW(k+1)=LL{i+1}(k); C{w}=NEW; else break; end end end w=0; for r=1:numel(C) S=T(:,C{r}); [~, x]=size(S); SS=ones(M,1); for i=1:x SS=SS&(S(:,i)); end Sup=sum(SS)/M; if Sup >= minSup w=w+1; L{w}=C{r}; end end LL=L; disp(numel(LL));%%%%%%%%%%%%%%%%%% % Increment Counter k=k+1; endend
BooleMatrix.m產生布爾矩陣
function [ B ] = BooleMatrix(A)%UNTITLED Summary of this function goes here% Detailed explanation goes hereM=size(A,1);N=size(A,2);B=zeros(M,N);for i=1:M for j=1:N B(i,A(i,j))=1; end endend
Main.m主函數,執行此函數就可以
%%%看記憶體% % % % % profile on -memory% % % % % myprog% % % % % profile viewerfunction Main()load mushroom.mat;MushroomBooleMatrix=BooleMatrix(mushroom);minSup = 0.2;Apriori(MushroomBooleMatrix,minSup);end