matlab 关联规则挖掘,数据挖掘实验(六)Matlab实现Apriori算法【关联规则挖掘】...
本文代碼均已在 MATLAB R2019b 測試通過,如有錯誤,歡迎指正。
(一)關聯規則挖掘
關聯規則挖掘(Association rule mining)是數據挖掘中最活躍的研究方法之一,可以用來發現不同事物之間的聯系,最早是為了發現超市交易數據庫中不同的商品之間的關系。
例如一個超市的經理想要更多的了解顧客的購物習慣,比如“哪組商品可能會在一次購物中同時被購買?”或者“某顧客購買了個人電腦,那該顧客三個月后購買數碼相機的概率有多大?”。利用關聯規則挖掘,他可能會發現在面包和牛奶間存在較強的關聯性,顧客在購買面包的同時大都會同時購買牛奶。這樣的關聯規則對超市進行促銷銷售是很有幫助的,如:如果需要對面包進行促銷,可通過將其與牛奶捆綁銷售的方式來進行,從而提高二者共同的銷量。
支持度(support): 支持度是模式為真的任務相關的元組(或事務)所占的百分比。對于形如“A?B”的關聯規則,支持度定義為:
支 持 度 ( A ? B ) = 包 含 A 和 B 的 元 組 數 元 組 總 數 支持度(A?B)= \frac {包含A和B的元組數}{元組總數}支持度(A?B)=元組總數包含A和B的元組數?,其中A、B是項目的集合。
置信度(certainty): 每個發現的模式都有一個表示其有效性或值得信賴性的度量。對于形如“A?B”的關聯規則,其有效性度量為置信度,定義為:
置 信 度 ( A ? B ) = 包 含 A 和 B 的 元 組 數 包 含 A 的 元 組 數 置信度(A?B)= \frac {包含A和B的元組數}{包含A的元組數}置信度(A?B)=包含A的元組數包含A和B的元組數?,其中A、B是項目的集合。
強關聯規則(合格的關聯規則): 同時滿足用戶定義的最小置信度和最小支持度閾值的關聯規則,稱為強關聯規則(strong association rule),并被認為是有趣的。
(二)Apriori關聯規則挖掘算法的基本思想
Apriori算法的主要思想是找出存在于事務數據集中最大的頻繁項集,利用得到的最大頻繁項集與預先設定的最小置信度閾值生成強關聯規則。
(1)Apriori 算法原理
任何一個頻繁項集的子集必定是頻繁項集。
任何一個非頻繁項集的超集必定是非頻繁項集。
(2)Apriori算法實現的兩個過程
a)找出所有的頻繁項集(支持度必須大于等于給定的最小支持度閾值),在這個過程中連接步和剪枝步互相融合,最終得到最大的頻繁項集L k L_kLk?。
連接步: 連接步的目的是找到K項集。
對給定的最小支持度閾值,分別對候選1項集C 1 C_1C1?,剔除小于該閾值的項集得到頻繁1項集L 1 L_1L1?;
下一步由L 1 L_1L1?自身連接(L 1 ? L 1 L_1*L_1L1??L1?)產生候選2項集C 2 C_2C2?,保留C 2 C_2C2?中滿足約束條件的項集得到頻繁2項集,記為L 2 L_2L2?;
再下一步由L 2 L_2L2?自身連接(L 2 ? L 2 L_2*L_2L2??L2?)產生候選3項集C 3 C_3C3?,保留C 3 C_3C3?中滿足約束條件的項集得到頻繁3項集,記為L 3 L_3L3?,等等。
這樣循環下去,得到最大頻繁項集L k L_kLk?。
剪枝步: 剪枝步緊接著連接步,在產生候選k項集C k C_kCk?的過程中起到減小搜索空間的目的。由于C k C_kCk?是L k ? 1 L_{k-1}Lk?1?與L k ? 1 L_{k-1}Lk?1?連接產生的,根據Apriori的性質,頻繁項集的所有非空子集也必須是頻繁項集,所以不滿足該性質的項集將不會存在于C k C_kCk?中,該過程就是剪枝。
b)由頻繁項集產生強關聯規則:在過程a)可知未超過預定的最小支持度閾值的項集已被剔除,如果剩下這些規則又滿足了預定的最小置信度閾值,那么就挖掘出了強關聯規則。
(三)問題描述
下表給出了某超市的交易記錄。該記錄中共包含7次交易,7次交易共涉及5種不同的商品。如果某次交易過程中購買了某商品,則在該次交易中,商品的取值為1,否則為0。要求利用Apriori算法,從該交易記錄中發掘關聯規則。
(四)Matlab實現Apriori挖掘算法,提取關聯規則
代碼需要說明的地方:
支持度(A?B)=sum(AB)/n,應該是一個小數,但是由于總元組個數n相同,用分子sum(AB)這個整數來表示支持度。
代碼中沒有寫剪枝步,剪枝步是要對每次生成的候選集C k C_kCk?的所有非空子集判斷是否為頻繁項集(大于等于最小支持度),而每次求所有子集的時間復雜度是指數級別的,比較大。我寫的代碼是直接求C k C_kCk?的置信度,然后選出大于等于最小置信度的C k C_kCk?作為L k L_kLk?。
數據集寫在代碼里了,保證你復制粘貼就能運行(Matlab R2019b版本)。 但是對于工程來說,應該用文件形式輸入數據,分多個代碼文件寫函數模塊比較好。
clear; clc;
data=[
11001
01010
01100
11010
10100
11101
11100
];
min_sup=input("請輸入最小支持度(正整數,示例:2)\n"); % 最小支持度(未除以n)
min_con=input("請輸入最小置信度([0,1]的小數,示例:0.75)\n"); % 最小置信度(已除以n)
[n,m]=size(data);
for i=1:n
x{i}=find(data(i,:)==1); % 求每行購買商品的編號
end
k=0;
while 1
k=k+1;
L{k}={};
%% 生成候選集C{k}
if k==1
C{k}=(1:m)';
else
[nL,mL]=size(L{k-1});
cnt=0;
for i=1:nL
for j=i+1:nL
tmp=union(L{k-1}(i,:),L{k-1}(j,:)); % 兩集合并集
if length(tmp)==k
cnt=cnt+1;
C{k}(cnt,1:k)=tmp;
end
end
end
C{k}=unique(C{k},'rows'); % 去掉重復的行
end
%% 求候選集的支持度C_sup{k}
[nC,mC]=size(C{k}); % 候選集大小
for i=1:nC
cnt=0;
for j=1:n
if all(ismember(C{k}(i,:),x{j}),2)==1 % all函數判斷向量是否全為1,參數2表示按行判斷
cnt=cnt+1;
end
end
C_sup{k}(i,1)=cnt; % 每行存候選集對應的支持度
end
%% 求頻繁項集L{k}
L{k}=C{k}(C_sup{k}>=min_sup,:);
if isempty(L{k}) % 這次沒有找出頻繁項集
break;
end
if size(L{k},1)==1 % 頻繁項集行數為1,下一次無法生成候選集,直接結束
k=k+1;
C{k}={};
L{k}={};
break
end
end
fprintf("\n");
for i=1:k
fprintf("第%d輪的候選集為:",i); C{i}
fprintf("第%d輪的頻繁集為:",i); L{i}
end
fprintf("第%d輪結束,最大頻繁項集為:",k); L{k-1}
[nL,mL]=size(L{k-1});
rule_count=0;
for p=1:nL % 第p個頻繁集
L_last=L{k-1}(p,:); % 之后將L_last分成左右兩個部分,表示規則的前件和后件
%% 求ab一起出現的次數cnt_ab
cnt_ab=0;
for i=1:n
if all(ismember(L_last,x{i}),2)==1 % all函數判斷向量是否全為1,參數2表示按行判斷
cnt_ab=cnt_ab+1;
end
end
len=floor(length(L_last)/2);
for i=1:len
s=nchoosek(L_last,i); % 選i個數的所有組合
[ns,ms]=size(s);
for j=1:ns
a=s(j,:);
b=setdiff(L_last,a);
[na,ma]=size(a);
[nb,mb]=size(b);
%% 關聯規則a->b
cnt_a=0;
for i=1:na
for j=1:n
if all(ismember(a,x{j}),2)==1 % all函數判斷向量是否全為1,參數2表示按行判斷
cnt_a=cnt_a+1;
end
end
end
pab=cnt_ab/cnt_a;
if pab>=min_con % 關聯規則a->b的置信度大于等于最小置信度,是強關聯規則
rule_count=rule_count+1;
rule(rule_count,1:ma)=a;
rule(rule_count,ma+1:ma+mb)=b;
rule(rule_count,ma+mb+1)=ma; % 倒數第二列記錄分割位置(分成規則的前件、后件)
rule(rule_count,ma+mb+2)=pab; % 倒數第一列記錄置信度
end
%% 關聯規則b->a
cnt_b=0;
for i=1:na
for j=1:n
if all(ismember(b,x{j}),2)==1 % all函數判斷向量是否全為1,參數2表示按行判斷
cnt_b=cnt_b+1;
end
end
end
pba=cnt_ab/cnt_b;
if pba>=min_con % 關聯規則b->a的置信度大于等于最小置信度,是強關聯規則
rule_count=rule_count+1;
rule(rule_count,1:mb)=b;
rule(rule_count,mb+1:mb+ma)=a;
rule(rule_count,mb+ma+1)=mb; % 倒數第二列記錄分割位置(分成規則的前件、后件)
rule(rule_count,mb+ma+2)=pba; % 倒數第一列記錄置信度
end
end
end
end
fprintf("當最小支持度為%d,最小置信度為%.2f時,生成的強關聯規則:\n",min_sup,min_con);
fprintf("強關聯規則\t\t置信度\n");
[nr,mr]=size(rule);
for i=1:nr
pos=rule(i,mr-1); % 斷開位置,1:pos為規則前件,pos+1:mr-2為規則后件
for j=1:pos
if j==pos
fprintf("%d",rule(i,j));
else
fprintf("%d∧",rule(i,j));
end
end
fprintf(" => ");
for j=pos+1:mr-2
if j==mr-2
fprintf("%d",rule(i,j));
else
fprintf("%d∧",rule(i,j));
end
end
fprintf("\t\t%f\n",rule(i,mr));
end
(五)運行結果
(1)輸入最小支持度為2,最小置信度為0.75
請輸入最小支持度(正整數,示例:2)
2
請輸入最小置信度([0,1]的小數,示例:0.75)
0.75
第1輪的候選集為:
ans =
1
2
3
4
5
第1輪的頻繁集為:
ans =
1
2
3
4
5
第2輪的候選集為:
ans =
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
第2輪的頻繁集為:
ans =
1 2
1 3
1 5
2 3
2 4
2 5
第3輪的候選集為:
ans =
1 2 3
1 2 4
1 2 5
1 3 5
2 3 4
2 3 5
2 4 5
第3輪的頻繁集為:
ans =
1 2 3
1 2 5
第4輪的候選集為:
ans =
1 2 3 5
第4輪的頻繁集為:
ans =
空的 0×4 double 矩陣
第4輪結束,最大頻繁項集為:
ans =
1 2 3
1 2 5
當最小支持度為2,最小置信度為0.75時,生成的強關聯規則:
強關聯規則置信度
2∧5 => 11.000000
1∧5 => 21.000000
5 => 1∧21.000000
(2)輸入最小支持度為2,最小置信度為0
請輸入最小支持度(正整數,示例:2)
2
請輸入最小置信度([0,1]的小數,示例:0.75)
0
第1輪的候選集為:
ans =
1
2
3
4
5
第1輪的頻繁集為:
ans =
1
2
3
4
5
第2輪的候選集為:
ans =
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
第2輪的頻繁集為:
ans =
1 2
1 3
1 5
2 3
2 4
2 5
第3輪的候選集為:
ans =
1 2 3
1 2 4
1 2 5
1 3 5
2 3 4
2 3 5
2 4 5
第3輪的頻繁集為:
ans =
1 2 3
1 2 5
第4輪的候選集為:
ans =
1 2 3 5
第4輪的頻繁集為:
ans =
空的 0×4 double 矩陣
第4輪結束,最大頻繁項集為:
ans =
1 2 3
1 2 5
當最小支持度為2,最小置信度為0.00時,生成的強關聯規則:
強關聯規則置信度
1 => 2∧30.400000
2∧3 => 10.666667
2 => 1∧30.333333
1∧3 => 20.666667
3 => 1∧20.500000
1∧2 => 30.500000
1 => 2∧50.400000
2∧5 => 11.000000
2 => 1∧50.333333
1∧5 => 21.000000
5 => 1∧21.000000
1∧2 => 50.500000
本文同步分享在 博客“nefu_ljw”(CSDN)。
如有侵權,請聯系 support@oschina.cn 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。
總結
以上是生活随笔為你收集整理的matlab 关联规则挖掘,数据挖掘实验(六)Matlab实现Apriori算法【关联规则挖掘】...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 水利水电安全员考试单选练习题库(5)
- 下一篇: matlab信号仿真模型,对Matlab