Educoder-候选剪枝Apriori算法
任务描述
本关任务:编写一个能实现候选剪枝的小程序。
相关知识
为了完成本关任务,你需要掌握:1.Apripori 算法候选剪枝,2.Apripori 算法候选剪枝代码实现。
Apripori 算法候选剪枝
候选集的剪枝操作基于两个定理: 定理1:若某项集是频繁项集,则它的所有子集都是频繁项集。 例如:{a, b, c}是频繁项集,则{a}、{b}、{c}、{a, b}、{b, c}、{a, c}也是频繁项集。
定理2:若某项集不是频繁项集,则它的所有超集都不是频繁项集。 例如:{a, b}不是频繁项集,则{a, b, c}也不是频繁项集。
基于以上两个定理,我们需要对进行连接操作后的候选集进行剪枝操作,减小搜索空间。
剪枝:对 Ck+1 中的某项集 c ,若 c 的某大小为 k 的子集 s 不存在于Lk ,则将 c 从 Ck+1 删除。
上图为剪枝过程例图,蓝色表示项集在频繁3项集中,可以看到在生成的候选4项集 ABCE 中,其子集ABE 并不在频繁3项集中,所以剪枝删去。
Apripori 算法候选剪枝代码实现
剪枝的核心在于检查候选项集 Ck 的子集是否都在频繁项集 Lk−1 中。 检查函数主体如下:
在候选生成中添加剪枝伪代码示例
比起无剪枝的候选生成,多了一个判断该候选项的子集是否都在Lk-1中的条件判断。
根据提示,在右侧编辑器补充代码,对生成的候选集剪枝。
预期输出:2
class Apriori(): def create_c1(self, dataset): # 遍历整个数据集生成c1候选集 c1 = set() for i in dataset: for j in i: item = frozenset([j]) c1.add(item) return c1 def has_infrequent_setdata(self, Ck_item, Lk_1): ##########begin########## # 检查候选项Ck_item的子集是否都在Lk-1中函数定义 for item in Ck_item: sub_Ck = Ck_item - frozenset([item]) if sub_Ck not in Lk_1: return False ##########end########## return True def create_ck(self, Lk_1, size): # 通过频繁项集Lk-1创建ck候选项集 Ck = set() l = len(Lk_1) lk_list = list(Lk_1) for i in range(l): for j in range(i + 1, l): ##########begin########## # 两次遍历Lk-1,找出前n-1个元素相同的项 l1 = list(lk_list[i]) l2 = list(lk_list[j]) l1.sort() l2.sort() #小写英文字母也可以排序 ##########end########## if l1[0:size - 2] == l2[0:size - 2]: ##########begin########## #只有最后一项不同时,生成下一候选项 #检查该候选项的子集是否都在Lk-1中 Ck_item = lk_list[i] | lk_list[j] if self.has_infrequent_setdata(Ck_item, Lk_1): Ck.add(Ck_item) ##########end########## return Ck def generate_lk_by_ck_ergodic(self, data_set, ck, min_support, support_data): item_count = {} Lk = set() for t in data_set: for item in ck: if item.issubset(t): if item not in item_count: item_count[item] = 1 else: item_count[item] += 1 t_num = float(len(data_set)) for item in item_count: if item_count[item] / t_num >= min_support: Lk.add(item) support_data[item] = item_count[item] return Lk if __name__ == "__main__": data = [[a,c,e],[b,d],[b,c],[a,b,c,d],[a,b],[b,c],[a,b], [a,b,c,e],[a,b,c],[a,c,e]] apriori = Apriori() support_data = {} c1 = apriori.create_c1(data) l1 = apriori.generate_lk_by_ck_ergodic(data_set=data, ck=c1, min_support=0.2, support_data=support_data) c2 = apriori.create_ck(l1,size=2) l2 = apriori.generate_lk_by_ck_ergodic(data_set=data,ck=c2,min_support=0.2,support_data=support_data) c3 = apriori.create_ck(l2, size=3) print(len(c3))
下一篇:
线程设置优先级与性能倒置