Apriori演算法:使用候選項找頻繁項集
Apriori演算法是關聯分析中一種基本演算法,用於挖掘布爾關聯規則頻繁項集。原理:利用頻繁項集的先驗知識,使用逐層搜尋的迭代方法,使用k項集探索(k+1)項集。這裡先看哈二維Apriori演算法。(一般資料庫都是二維的嘛。。hehe)
Apriori性質:頻繁項集的所有非空子集都必須也是頻繁的。(一種反單調性質)
演算法描述:
1、連結步:通過L<k-1>自串連產生候選k項集C<k>。
2、剪枝步:C<k>是L<k>的超集。利用Apriori性質,如果一個k項集的(k-1)項集不在L<k-1>中,則該k項集從C<k>中刪除。(這種子集測試可以使用所有頻繁項集的散列樹快速完成)
上Pseudo Code:
Apriori
輸入:交易資料D;最小支援度閥值min_sup。
輸出:D中的頻繁項集L。
L<1> = find_frequent_1-itemset(D);
For (k = 2; L<k-1> != empty; k++) {
C<k> = apriori_gen(L<k-1>, min_sup);
For each transaction t in D {
C<t> = subset(C<k>, t); //找出t中是候選集的所有C<k>的子集
For each candidate c in C<t>
c.count++;
}
L<k> = {c in C<k> | c.count >= min_sup}
}
Return L = set of L<k>
Procedure apriori_gen(L<k-1>, min_sup)
For each itemset l1 in L<k-1>
For each itemset l2 in L<k-1>
If (l1[i] = l2[1]) && (l1[2] = l2[2]) && … && (l1[k-2] = l2[k-2]) && (l1[k-1] < l2[k-1]) then {
c = l1 * l2; //union
if has_infrequent_subset(c, L<k-1>) then
delete c;
else
add c to C<k>;
}
Return C<k>;
Procedure has_infrequent_subset(c, L<k-1>)
For each (k-1)-subset s of c
If s not in L<k-1> then
Return TRUE;
Return FALSE;
由頻繁項集產生關聯規則:
Confidence(A => B) = P(A | B)
= support(AB) / support(B) = support_count(AB) / support_count(B)
對於前面Apriori找出的每個頻繁項集l,產生l的非空子集;(記得Apriori性質哦)
對於每個非空子集s,如果 support_count(l) / support_count(s) >= min_conf,則輸出“s => (l – s)”(為什麼用support_count(l)不用(l-s)?)
提高Apriori的有效性?資料結構的改進,掃描次數的降低等。
1、散列項集計數,增加效率。
一個土一點的比喻:在Java裡面用HashMap<Key, Val>來存。。還有種用trie樹的,等我補習過Algorithms in C++再說。。
2、事務壓縮:不包含k項集的事務不可能包含(k+1)項集。這樣,可以給事務加刪除標記,下次迭代不考慮之。
3、劃分(Er。。不是等價類別,是看程式設計的方便亂劃,比如一次能裝入記憶體多少就劃多少)
兩次掃描。第一次,將D中事務劃分為n個非重疊部分,如果D中事務最小支援閥值為min_sup,則每個部分最小支持度計數為(min_sup * 該部分事務數)。對每一部分,找出局部頻繁項集。
局部頻繁項集可能不是整個資料庫D的頻繁項集,但D的任何頻繁項集必是局部頻繁項集(WHY?)。所有局部頻繁項集合并為全域候選項集。第二次掃描D,評估每個候選的實際支援度。
4、選樣:就是抽樣+檢測手段,以精度換速度。
5、動態項集計數:不像Apriori僅在每次完整掃描前確定新的候選,現在在任何開始點添加候選集。(編程怎麼實現比較好?)