挖掘频繁模式是挖掘频繁出现在数据集中的模式。Apriori算法是用于挖掘频繁项集的经典方法。所谓频繁项集也就是出现频度不低于最小支持度阈值support的项集,support可以是绝对支持度(频度),也可以是相对支持度(频率)。支持度support:包含该项集或者模式的样本在全体样本中出现的次数(绝对)或所占的比例(相对)。
Apriori算法原理
为了挖掘频繁K项集,用Lk表示,可以将Lk-1与其自身进行连接,产生候选的Lk并记为Ck。Ck是Lk的超级,因为其中包含许多非频繁的K项集。为了提前删除一些非频繁的K项集,Apriori算法提出了一种启发式策略,Apriori性质用于剪枝:频繁项集的所有非空自己也必须是频繁的。我们可以采用这条性质对产生候选K项集Ck进行修剪。修剪方法是对Ck中的每个候选K项集,看其是否存在K-1项的子集不包含于Lk-1,如果有则该候选项集是非频繁的,将其从Ck中删除,从而实现剪枝。
算法伪代码
/// 生成候选K项集,包括链接和剪枝
FrequentSet Generate_candidates(FrequentSet Lk_1)
{
foreach(l1 in Lk_1) { //对Lk-1进行链接
foreach(l2 in Lk_1) {
l = l1链接l2;
if(l是k项集 && Ck不包含l) {
L = Generate_subset(l); //生成候选项集l的k-1项子集
bool flag = false;
foreach(sl in L) {
if(Lk-1 not contains sl) { //候选K项集l的K-1项子集sl不是频繁K-1项集,因此l必然不可能是频繁K项集(Apriori性质),此为剪枝。
flag = true;
break;
}
}
if(!flag){
Ck.add(l);
}
}
}
}
return Ck;
}
FrequentSet Apriori(DataSet S)
{
L1 = find_frequent_itemset(S, 1); // 挖掘频繁一项集
int k = 2;
while (Lk_1 != NULL) {
Ck = Generate_candidates(Lk_1); // 产生候选K项集
foreach(l in Ck) { // 对每个候选K项集计数,剔除不满足最小支持度阈值的K项集
frequency = Calculate_frequency(S, l); //统计K项集l在全集S中出现的次数
if(frequency >= min_support) {
k.add(l);
}
}
k++;
}
return Lk_1;
}
由此我们可以清晰的看出Apriori算法的执行步骤:
1.链接:由频繁K-1项集Lk-1与其自身链接,产生候选K项集Ck。
2.剪枝:验证Ck中的每个候选K项集c产生的K个K-1项集是否包含在Lk-1中,从而判断是否进行剪枝。
3.统计:对剪枝后的Ck统计每个候选K项集c出现在全集S中的频度。
Reference
1.韩家炜, 《数据挖掘:概念与技术》