数据挖掘与机器学习:Apripori算法

这篇具有很好参考价值的文章主要介绍了数据挖掘与机器学习:Apripori算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

第一关:候选生成 

任务描述:

相关知识:

一、Apripori算法候选生成:

二、Apripori算法候选生成代码实现:

编程要求:

测试说明:

第二关:候选剪枝

任务描述:

相关知识:

Apripori算法候选剪枝:

Apripori算法候选剪枝代码实现:

编程要求:

测试说明:

第三关:基于遍历的支持度计算

任务描述:

相关知识:

一、基于遍历的支持度计算:

二、基于遍历的支持度计算代码实现:

编程要求:

测试说明:

第四关:基于hash的支持度计算

任务描述:

相关知识:

一、基于hash的支持度计算:

二、基于hash的支持度计算代码实现:

编程要求:

测试说明:


第一关:候选生成 

任务描述:

 本关任务:编写一个能实现Apripori算法候选生成的小程序。

相关知识:

 为了完成本关任务,你需要掌握:1.Apripori 算法候选生成,2.Apripori 算法候选生成代码实现。

一、Apripori算法候选生成:

 Apripori算法利用自连接生成候选集:

自连接:Lk​中的2个k项集l1​l2​,若l1​l2​有且仅有1个项不同,则将l1​l2​加入Ck+1​

直观理解:生成可能的(k+1)项集:

数据挖掘与机器学习:Apripori算法

 上图为频繁3项集L3​生成候选4项集C4​过程示例,可以看到L3​中的2个3项集ABCABD有且仅有1个项不同,则将 ABCABD=ABCD 加入C4​

二、Apripori算法候选生成代码实现:

 Apripori 算法候选1项集生成函数如下:

def create_c1(self, dataset):  # 遍历整个数据集生成c1候选集
    c1 = set()
    for i in dataset:
        for j in i:
            item = frozenset([j])
            c1.add(item)
    return c1

其中 dataset 为数据集列表。

Apripori 算法候选 k 项集生成函数(无剪枝操作)代码思路如下:

  1. 创建Ck集合。
  2. 获取Lk_1的长度。
  3. 将Lk_1转换为列表。
  4. 两次遍历Lk-1,找出前n-1个元素相同的项。
  5. 只有最后一项不同时,生成下一候选项。
  6. 返回Ck集合。

伪代码示例:

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):  
            # 两次遍历Lk-1,找出前n-1个元素相同的项
            # 只有最后一项不同时,生成下一候选项
    return Ck

编程要求:

 根据提示,在右侧编辑器补充代码,生成候选3项集C3​

测试说明:

平台会对你编写的代码进行测试:

预期输出:4

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 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个元素相同的项


                ##########end##########
                if l1[0:size - 2] == l2[0:size - 2]:  
                    ##########begin##########
                    #只有最后一项不同时,生成下一候选项

                    
                    ##########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))

数据挖掘与机器学习:Apripori算法

 数据挖掘与机器学习:Apripori算法

通过代码:
 

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 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##########
                    #只有最后一项不同时,生成下一候选项
                    Ck_item = lk_list[i] | lk_list[j]
                    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))

第二关:候选剪枝

任务描述:

 本关任务:编写一个能实现候选剪枝的小程序。

相关知识:

为了完成本关任务,你需要掌握: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​ ,则将 cCk+1 删除。

数据挖掘与机器学习:Apripori算法

 上图为剪枝过程例图,蓝色表示项集在频繁3项集中,可以看到在生成的候选4项集 ABCE 中,其子集ABE 并不在频繁3项集中,所以剪枝删去。

Apripori算法候选剪枝代码实现:

 剪枝的核心在于检查候选项集 Ck​ 的子集是否都在频繁项集 Lk−1​ 中。 检查函数主体如下:

def has_infrequent_subset(self, Ck_item, Lk_1):  # 检查候选项Ck_item的子集是否都在Lk-1中
    for item in Ck_item:
        sub_Ck = Ck_item - frozenset([item])
        #进行条件判断,如果存在候选项Ck_item子集不在Lk-1中则返回False
    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):  
            # 两次遍历Lk-1,找出前n-1个元素相同的项
            # 只有最后一项不同时,生成下一候选项
            # 检查该候选项的子集是否都在Lk-1中
                Ck.add(Ck_item)
    return Ck

比起无剪枝的候选生成,多了一个判断该候选项的子集是否都在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_subset(self, Ck_item, Lk_1):  
        ##########begin##########
        # 检查候选项Ck_item的子集是否都在Lk-1中函数定义

        
        ##########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个元素相同的项


                ##########end##########
                if l1[0:size - 2] == l2[0:size - 2]:  
                    ##########begin##########
                    #只有最后一项不同时,生成下一候选项
                    #检查该候选项的子集是否都在Lk-1中



                    ##########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))

数据挖掘与机器学习:Apripori算法

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_subset(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_subset(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))

第三关:基于遍历的支持度计算

任务描述:

 本关任务:编写一个能实现基于遍历的支持度计算的小程序。

相关知识:

为了完成本关任务,你需要掌握:1.基于遍历的支持度计算,2.基于遍历的支持度计算代码实现。

一、基于遍历的支持度计算:

 数据挖掘与机器学习:Apripori算法

二、基于遍历的支持度计算代码实现:

 基于遍历的支持度计算函数如下:

def generate_lk_by_ck_ergodic(self, data_set, ck, min_support, support_data):  # 通过候选项ck生成lk,基于遍历的支持度计算并将各频繁项的支持度保存到support_data字典中
    item_count = {}  # 用于标记各候选项在数据集出现的次数
    Lk = set()
    for t in tqdm(data_set):  # 遍历数据集
        for item in ck:  
            #检查候选集ck中的每一项是否出现在事务t中
    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 

 其中 data_set 为数据集,ck 为候选 k 项集,min_support为最小支持度, support_data 为各项的支持度记录字典。遍历数据集for循环中检查候选集ck中的每一项是否出现在事务t中请同学自行完成。

编程要求:

根据提示,在右侧编辑器补充代码,使用遍历计算支持度。 

测试说明:

平台会对你编写的代码进行测试:

预期输出:6

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 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):  # 两次遍历Lk-1,找出前n-1个元素相同的项
                l1 = list(lk_list[i])
                l2 = list(lk_list[j])
                l1.sort()
                l2.sort()
                if l1[0:size - 2] == l2[0:size - 2]:  # 只有最后一项不同时,生成下一候选项
                    Ck_item = lk_list[i] | lk_list[j]
                    if self.has_infrequent_subset(Ck_item, Lk_1):  # 检查该候选项的子集是否都在Lk-1中
                        Ck.add(Ck_item)
        return Ck

    def has_infrequent_subset(self, Ck_item, Lk_1):  # 检查候选项Ck_item的子集是否都在Lk-1中
        for item in Ck_item:
            sub_Ck = Ck_item - frozenset([item])
            if sub_Ck not in Lk_1:
                return False
        return True

    def generate_lk_by_ck_ergodic(self, data_set, ck, min_support, support_data):  # 通过候选项ck生成lk,基于遍历的支持度计算并将各频繁项的支持度保存到support_data字典中
        item_count = {}  # 用于标记各候选项在数据集出现的次数
        Lk = set()
        # 基于遍历的支持度计算
        for t in data_set:  # 遍历数据集
            for item in ck:
                ##########begin##########
                # 检查候选集ck中的每一项是否出现在事务t中



                ##########end##########
        t_num = float(len(data_set))
        for item in item_count:
            ##########begin##########
            # 将满足支持度的候选项添加到频繁项集中


            
            ##########end##########
        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)
    print(len(l2))

数据挖掘与机器学习:Apripori算法

 通过代码:

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 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):  # 两次遍历Lk-1,找出前n-1个元素相同的项
                l1 = list(lk_list[i])
                l2 = list(lk_list[j])
                l1.sort()
                l2.sort()
                if l1[0:size - 2] == l2[0:size - 2]:  # 只有最后一项不同时,生成下一候选项
                    Ck_item = lk_list[i] | lk_list[j]
                    if self.has_infrequent_subset(Ck_item, Lk_1):  # 检查该候选项的子集是否都在Lk-1中
                        Ck.add(Ck_item)
        return Ck

    def has_infrequent_subset(self, Ck_item, Lk_1):  # 检查候选项Ck_item的子集是否都在Lk-1中
        for item in Ck_item:
            sub_Ck = Ck_item - frozenset([item])
            if sub_Ck not in Lk_1:
                return False
        return True

    def generate_lk_by_ck_ergodic(self, data_set, ck, min_support, support_data):  # 通过候选项ck生成lk,基于遍历的支持度计算并将各频繁项的支持度保存到support_data字典中
        item_count = {}  # 用于标记各候选项在数据集出现的次数
        Lk = set()
        # 基于遍历的支持度计算
        for t in data_set:  # 遍历数据集
            for item in ck:
                ##########begin##########
                # 检查候选集ck中的每一项是否出现在事务t中
                if item.issubset(t):
                    if item not in item_count:
                        item_count[item] = 1
                    else:
                        item_count[item] += 1
                ##########end##########
        t_num = float(len(data_set))
        for item in item_count:
            ##########begin##########
            # 将满足支持度的候选项添加到频繁项集中
             if item_count[item] / t_num >= min_support:
                Lk.add(item)
                support_data[item] = item_count[item]
            ##########end##########
        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)
    print(len(l2))

第四关:基于hash的支持度计算

任务描述:

 本关任务:编写一个能实现基于 hash 的支持度计算的小程序。

相关知识:

为了完成本关任务,你需要掌握:1.基于 hash 的支持度计算,2.基于 hash 的支持度计算代码实现。 

一、基于hash的支持度计算:

基于遍历的支持度计算非常耗时间,而基于 hash 的支持度计算可以将所有候选项集以 hash 结构中,每条事务只需要匹配其对应桶里的候选项集,从而节省时间开销。

 数据挖掘与机器学习:Apripori算法

假设有15个候选3-项集: {1 4 5}, {1 2 4}, {4 5 7}, {1 2 5}, {4 5 8}, {1 5 9}, {1 3 6}, {2 3 4}, {5 6 7}, {3 4 5}, {3 5 6}, {3 5 7}, {6 8 9}, {3 6 7}, {3 6 8}

可构建如下 hash 树: 树的每个内部结点都使用hash函数h(p)=p mod 3来确定应当沿着当前结点的哪个分支向下。例如,项 1,4 和 7 应当散列到相同的分支(即最左分支),因为除以 3 之后它们都具有相同的余数。所有的候选项集都存放在hash树的叶结点中。下图图中显示的 hash 树包含 15个候选 3-项集,分布在 9 个叶结点中。

数据挖掘与机器学习:Apripori算法

构建过程如下:

数据挖掘与机器学习:Apripori算法

数据挖掘与机器学习:Apripori算法

数据挖掘与机器学习:Apripori算法

给定一个事务 t , 跟哪些候选 3 项集匹配?例如下图中的例子:

数据挖掘与机器学习:Apripori算法

匹配过程如下:

数据挖掘与机器学习:Apripori算法

数据挖掘与机器学习:Apripori算法

数据挖掘与机器学习:Apripori算法

考虑一个事务 t={1,2,3,5,6} 。为了更新候选项集的支持度计数,必须这样遍历 Hash 树:所有包含属于事务 t 的候选 3 -项集的叶结点至少访问一次。

注意:包含在t中的候选 3 -项集必须以项 1,2或3 开始,如上图中第一层前缀结构所示。这样,在Hash树的根结点,事务中的项 1,2 和 3 将分别散列。项 1 被散列到根结点的左子女,项 2 被散列到中间子女,而项 3 被散列到右子女。在树的下一层,事务根据上图中的第二层结构列出的第二项进行散列。

例如,在根结点散列项1之后,散列事务的项 2、3 和 5 。项 2 和 5 散列到中间子女,而 3 散列到右子女,如上图所示。继续该过程,直至到达 Hash 树的叶结点。存放在被访问的叶结点中的候选项集与事务进行比较,如果候选项集是该事务的子集,则增加它的支持度计数。在这个例子中,访问了 9 个叶结点中的 5 个, 15 个项集中的 9 个与事务进行比较。可以看到匹配过程只需要进行 11 次比较。

二、基于hash的支持度计算代码实现:

基于 hash 的支持度计算关键在于 hash 树的构建。 首先构建节点类:

#Hash节点类定义
class Hash_node:
    def __init__(self):
        self.children = {}           #指向子节点的指针
        self.Leaf_status = True      #了解当前节点是否为叶子节点的状态
        self.bucket = {}             #在储存桶中包含项目集 

 然后构建hash树类:

#构造得到Hash树类
class HashTree:
    # class constructor
    def __init__(self, max_leaf_count, max_child_count):
        self.root = Hash_node()
        self.max_leaf_count = max_leaf_count
        self.max_child_count = max_child_count
        self.frequent_itemsets = []
    # 进行递归插入以生成hashtree
    def recursively_insert(self, node, itemset, index, count):
        if index == len(itemset):
            if itemset in node.bucket:
                node.bucket[itemset] += count
            else:
                node.bucket[itemset] = count
            return
        if node.Leaf_status:                             #如果node是叶结点
            if itemset in node.bucket:
                node.bucket[itemset] += count
            else:
                node.bucket[itemset] = count
            if len(node.bucket) == self.max_leaf_count:  #如果储存桶容量增加
                for old_itemset, old_count in node.bucket.items():
                    hash_key = self.hash_function(old_itemset[index])  #对下一个索引做哈希
                    if hash_key not in node.children:
                        node.children[hash_key] = Hash_node()
                    self.recursively_insert(node.children[hash_key], old_itemset, index + 1, old_count)
                del node.bucket
                node.Leaf_status = False
        else:                                            
            #如果node不是是叶结点
            #需要进行递归式的嵌入
    def insert(self, itemset):
        itemset = tuple(itemset)
        self.recursively_insert(self.root, itemset, 0, 0)
    # 添加支持度到候选项集中. 遍历树并找到该项集所在的储存桶.
    def add_support(self, itemset):
        Transverse_HNode = self.root
        itemset = tuple(itemset)
        index = 0
        while True:
            if Transverse_HNode.Leaf_status:
                if itemset in Transverse_HNode.bucket:    #在此储存桶中找到项集
                    Transverse_HNode.bucket[itemset] += 1 #增加此项目集的计数
                break
            hash_key = self.hash_function(itemset[index])
            if hash_key in Transverse_HNode.children:
                Transverse_HNode = Transverse_HNode.children[hash_key]
            else:
                break
            index += 1
    def get_frequent_itemsets(self, node, support_count,frequent_itemsets):
        if node.Leaf_status:
            for key, value in node.bucket.items():
                if value >= support_count:                       #如果满足支持数条件
                    frequent_itemsets.append(list(key))          #将其添加到频繁项集中
                    Frequent_items_value[key] = value
            return
        for child in node.children.values():
            self.get_frequent_itemsets(child, support_count,frequent_itemsets)
    # 用于构造hash树的hash函数定义
    def hash_function(self, val):
        return int(val) % self.max_child_count 

其中如果node不是叶结点,需要进行递归式的嵌入,请同学自行完成。
提示:

调用hash函数计算hash值。
判断hash值是否在子节点中。
如果不在就构建新节点。
调用recursively_insert嵌入。

编程要求:

 根据提示,在右侧编辑器补充代码,构造正确的hash树类实现hash的支持度计算。

测试说明:

平台会对你编写的代码进行测试:

预期输出:

  1. ['1 3 5', '2 4', '1 2 3 4', '1 2', '2 3', '1 2', '2 3', '1 2 3 5', '1 2 3', '1 3 5']
  2. [['1'], ['3'], ['5'], ['2'], ['4']]
  3. {('1',): 7, ('3',): 7, ('5',): 3, ('2',): 8, ('4',): 2}
  4. All frequent itemsets with their support count:
  5. {('1',): 7, ('3',): 7, ('5',): 3, ('2',): 8, ('4',): 2, ('1', '3'): 5, ('1', '5'): 3, ('1', '2'): 5, ('3', '5'): 3, ('2', '3'): 5, ('2', '4'): 2, ('1', '3', '5'): 3, ('1', '2', '3'): 3}

开始你的任务吧,祝你成功!文章来源地址https://www.toymoban.com/news/detail-469740.html

import itertools
import time

filename = "data.csv"

min_support = 2

#读取数据集
with open(filename) as f:
    content = f.readlines()

content = [x.strip() for x in content]
print(content)

Transaction = []                  #保存事务列表
Frequent_items_value = {}         #保存所有频繁项集字典

#将数据集的内容添加到事物列表
for i in range(0,len(content)):
    Transaction.append(content[i].split())

#获得频繁一项集
def frequent_one_item(Transaction,min_support):
    candidate1 = {}

    for i in range(0,len(Transaction)):
        for j in range(0,len(Transaction[i])):
            if Transaction[i][j] not in candidate1:
                candidate1[Transaction[i][j]] = 1
            else:
                candidate1[Transaction[i][j]] += 1

    frequentitem1 = []                      #获得满足最小支持度的频繁一项集
    for value in candidate1:
        if candidate1[value] >= min_support:
            frequentitem1 = frequentitem1 + [[value]]
            Frequent_items_value[tuple(value)] = candidate1[value]

    return frequentitem1

values = frequent_one_item(Transaction,min_support)
print(values)
print(Frequent_items_value)


# 从事物中删除不频繁的一项集
Transaction1 = []
for i in range(0,len(Transaction)):
    list_val = []
    for j in range(0,len(Transaction[i])):
        if [Transaction[i][j]] in values:
            list_val.append(Transaction[i][j])
    Transaction1.append(list_val)


#Hash节点类定义
class Hash_node:
    def __init__(self):
        self.children = {}           #指向子节点的指针
        self.Leaf_status = True      #了解当前节点是否为叶子节点的状态
        self.bucket = {}             #在储存桶中包含项目集

#构造得到Hash树类
class HashTree:
    # class constructor
    def __init__(self, max_leaf_count, max_child_count):
        self.root = Hash_node()
        self.max_leaf_count = max_leaf_count
        self.max_child_count = max_child_count
        self.frequent_itemsets = []

    # 进行递归插入以生成hashtree
    def recursively_insert(self, node, itemset, index, count):
        if index == len(itemset):
            if itemset in node.bucket:
                node.bucket[itemset] += count
            else:
                node.bucket[itemset] = count
            return

        if node.Leaf_status:
            ##########begin##########
            #如果node是叶结点所进行的操作代码


            ##########end##########                             
            
        else:
            ##########begin##########
            #如果node不是是叶结点所进行的操作代码


            ##########end##########
            

    def insert(self, itemset):
        itemset = tuple(itemset)
        self.recursively_insert(self.root, itemset, 0, 0)

    # 添加支持度到候选项集中. 遍历树并找到该项集所在的储存桶.
    def add_support(self, itemset):
        Transverse_HNode = self.root
        itemset = tuple(itemset)
        index = 0
        while True:
            if Transverse_HNode.Leaf_status:
                if itemset in Transverse_HNode.bucket:    #在此储存桶中找到项集
                    Transverse_HNode.bucket[itemset] += 1 #增加此项目集的计数
                break
            hash_key = self.hash_function(itemset[index])
            if hash_key in Transverse_HNode.children:
                Transverse_HNode = Transverse_HNode.children[hash_key]
            else:
                break
            index += 1


    # 基于hash的支持度计算
    def get_frequent_itemsets(self, node, support_count,frequent_itemsets):
        ##########begin##########
        #获取频繁项集函数定义


        
        ##########end##########
    # hash function for making HashTree
    def hash_function(self, val):
        return int(val) % self.max_child_count

#生成hashTree
def generate_hash_tree(candidate_itemsets, max_leaf_count, max_child_count):
    htree = HashTree(max_child_count, max_leaf_count)             #create instance of HashTree
    for itemset in candidate_itemsets:
        htree.insert(itemset)                                     #to insert itemset into Hashtree
    return htree

#to generate subsets of itemsets of size k
def generate_k_subsets(dataset, length):
    subsets = []
    for itemset in dataset:
        subsets.extend(map(list, itertools.combinations(itemset, length)))
    return subsets

def subset_generation(ck_data,l):
    return map(list,set(itertools.combinations(ck_data,l)))


# 候选生成

def apriori_generate(dataset,k):
    ck = []
    #join step
    lenlk = len(dataset)
    for i in range(lenlk):
        for j in range(i+1,lenlk):
            L1 = list(dataset[i])[:k - 2]
            L2 = list(dataset[j])[:k - 2]
            if L1 == L2:
                ck.append(sorted(list(set(dataset[i]) | set(dataset[j]))))

    #prune step
    final_ck = []
    for candidate in ck:
        all_subsets = list(subset_generation(set(candidate), k - 1))
        found = True
        for i in range(len(all_subsets)):
            value = list(sorted(all_subsets[i]))
            if value not in dataset:
                found = False
        if found == True:
            final_ck.append(candidate)

    return ck,final_ck


# 候选剪枝

def generateL(ck,min_support):
    support_ck = {}
    for val in Transaction1:
        for val1 in ck:
            value = set(val)
            value1 = set(val1)

            if value1.issubset(value):
                if tuple(val1) not in support_ck:
                    support_ck[tuple(val1)] = 1
                else:
                    support_ck[tuple(val1)] += 1
    frequent_item = []
    for item_set in support_ck:
        if support_ck[item_set] >= min_support:
            frequent_item.append(sorted(list(item_set)))
            Frequent_items_value[item_set] = support_ck[item_set]

    return frequent_item

# apriori算法主函数
def apriori(L1,min_support):
    k = 2;
    L = []
    L.append(0)
    L.append(L1)
    max_leaf_count = 6  #每个hash树节点的最大容量
    max_child_count = 6  #每个hash树节点的最大子节点数

    start = time.time()
    while(len(L[k-1])>0):
        ck,final_ck = apriori_generate(L[k-1],k)                 #生成候选项集
        # print("C%d" %(k))
        # print(final_ck)
        h_tree = generate_hash_tree(ck,max_leaf_count,max_child_count)       #生成hash树
        if (k > 2):
            while(len(L[k-1])>0):
                l = generateL(final_ck, min_support)
                L.append(l)
                # print("Frequent %d item" % (k))
                # print(l)
                k = k + 1
                ck, final_ck = apriori_generate(L[k - 1], k)
                # print("C%d" % (k))
                # print(final_ck)
            break
        k_subsets = generate_k_subsets(Transaction1,k)                  #生成事物子集
        for subset in k_subsets:
            h_tree.add_support(subset)                                  #像hash树的项集添加支持数
        lk = []
        h_tree.get_frequent_itemsets(h_tree.root,min_support,lk)                  #获取频繁项集
        # print("Frequent %d item" %(k))
        # print(lk)
        L.append(lk)
        k = k + 1
    end = time.time()
    return L,(end-start)

L_value,time_taken = apriori(values,min_support)
#print("final L_value")
#print(L_value)
print("All frequent itemsets with their support count:")
print(Frequent_items_value)
import itertools
import time

filename = "data.csv"

min_support = 2

#读取数据集
with open(filename) as f:
    content = f.readlines()

content = [x.strip() for x in content]
print(content)

Transaction = []                  #保存事务列表
Frequent_items_value = {}         #保存所有频繁项集字典

#将数据集的内容添加到事物列表
for i in range(0,len(content)):
    Transaction.append(content[i].split())

#获得频繁一项集
def frequent_one_item(Transaction,min_support):
    candidate1 = {}

    for i in range(0,len(Transaction)):
        for j in range(0,len(Transaction[i])):
            if Transaction[i][j] not in candidate1:
                candidate1[Transaction[i][j]] = 1
            else:
                candidate1[Transaction[i][j]] += 1

    frequentitem1 = []                      #获得满足最小支持度的频繁一项集
    for value in candidate1:
        if candidate1[value] >= min_support:
            frequentitem1 = frequentitem1 + [[value]]
            Frequent_items_value[tuple(value)] = candidate1[value]

    return frequentitem1

values = frequent_one_item(Transaction,min_support)
print(values)
print(Frequent_items_value)


# 从事物中删除不频繁的一项集
Transaction1 = []
for i in range(0,len(Transaction)):
    list_val = []
    for j in range(0,len(Transaction[i])):
        if [Transaction[i][j]] in values:
            list_val.append(Transaction[i][j])
    Transaction1.append(list_val)


#Hash节点类定义
class Hash_node:
    def __init__(self):
        self.children = {}           #指向子节点的指针
        self.Leaf_status = True      #了解当前节点是否为叶子节点的状态
        self.bucket = {}             #在储存桶中包含项目集

#构造得到Hash树类
class HashTree:
    # class constructor
    def __init__(self, max_leaf_count, max_child_count):
        self.root = Hash_node()
        self.max_leaf_count = max_leaf_count
        self.max_child_count = max_child_count
        self.frequent_itemsets = []

    # 进行递归插入以生成hashtree
    def recursively_insert(self, node, itemset, index, count):
        if index == len(itemset):
            if itemset in node.bucket:
                node.bucket[itemset] += count
            else:
                node.bucket[itemset] = count
            return

        if node.Leaf_status:
            ##########begin##########
            #如果node是叶结点所进行的操作代码
            if itemset in node.bucket:
                node.bucket[itemset]+=count
            else:
                node.bucket[itemset]=count
                if len(node.bucket)==self.max_leaf_count:
                    如果储存桶容量增加
                for old_itemset, old_count in node.bucket.items():
                    hash_key = self.hash_function(old_itemset[index])  #对下一个索引做哈希
                    if hash_key not in node.children:
                        node.children[hash_key] = Hash_node()
                    self.recursively_insert(node.children[hash_key], old_itemset, index + 1, old_count)
                del node.bucket
                node.Leaf_status = False



            ##########end##########                             
            
        else:
            ##########begin##########
            #如果node不是是叶结点所进行的操作代码
            hash_key=self.hash_function(itemset[index])
            if hash_key not in node.children:
                node.children[hash_key]=Hash_node()
            self.recursively_insert(node.children[hash_key],itemset,index+1,count)



            ##########end##########
            

    def insert(self, itemset):
        itemset = tuple(itemset)
        self.recursively_insert(self.root, itemset, 0, 0)

    # 添加支持度到候选项集中. 遍历树并找到该项集所在的储存桶.
    def add_support(self, itemset):
        Transverse_HNode = self.root
        itemset = tuple(itemset)
        index = 0
        while True:
            if Transverse_HNode.Leaf_status:
                if itemset in Transverse_HNode.bucket:    #在此储存桶中找到项集
                    Transverse_HNode.bucket[itemset] += 1 #增加此项目集的计数
                break
            hash_key = self.hash_function(itemset[index])
            if hash_key in Transverse_HNode.children:
                Transverse_HNode = Transverse_HNode.children[hash_key]
            else:
                break
            index += 1


    # 基于hash的支持度计算
    def get_frequent_itemsets(self, node, support_count,frequent_itemsets):
        ##########begin##########
        #获取频繁项集函数定义
        if node.Leaf_status:
            for key, value in node.bucket.items():
                if value >= support_count: 
                    #如果满足支持数条件
                    frequent_itemsets.append(list(key))          #将其添加到频繁项集中
                    Frequent_items_value[key] = value
            return
        for child in node.children.values():
            self.get_frequent_itemsets(child, support_count,frequent_itemsets)



        
        ##########end##########
    # hash function for making HashTree
    def hash_function(self, val):
        return int(val) % self.max_child_count

#生成hashTree
def generate_hash_tree(candidate_itemsets, max_leaf_count, max_child_count):
    htree = HashTree(max_child_count, max_leaf_count)             #create instance of HashTree
    for itemset in candidate_itemsets:
        htree.insert(itemset)                                     #to insert itemset into Hashtree
    return htree

#to generate subsets of itemsets of size k
def generate_k_subsets(dataset, length):
    subsets = []
    for itemset in dataset:
        subsets.extend(map(list, itertools.combinations(itemset, length)))
    return subsets

def subset_generation(ck_data,l):
    return map(list,set(itertools.combinations(ck_data,l)))


# 候选生成

def apriori_generate(dataset,k):
    ck = []
    #join step
    lenlk = len(dataset)
    for i in range(lenlk):
        for j in range(i+1,lenlk):
            L1 = list(dataset[i])[:k - 2]
            L2 = list(dataset[j])[:k - 2]
            if L1 == L2:
                ck.append(sorted(list(set(dataset[i]) | set(dataset[j]))))

    #prune step
    final_ck = []
    for candidate in ck:
        all_subsets = list(subset_generation(set(candidate), k - 1))
        found = True
        for i in range(len(all_subsets)):
            value = list(sorted(all_subsets[i]))
            if value not in dataset:
                found = False
        if found == True:
            final_ck.append(candidate)

    return ck,final_ck


# 候选剪枝

def generateL(ck,min_support):
    support_ck = {}
    for val in Transaction1:
        for val1 in ck:
            value = set(val)
            value1 = set(val1)

            if value1.issubset(value):
                if tuple(val1) not in support_ck:
                    support_ck[tuple(val1)] = 1
                else:
                    support_ck[tuple(val1)] += 1
    frequent_item = []
    for item_set in support_ck:
        if support_ck[item_set] >= min_support:
            frequent_item.append(sorted(list(item_set)))
            Frequent_items_value[item_set] = support_ck[item_set]

    return frequent_item

# apriori算法主函数
def apriori(L1,min_support):
    k = 2;
    L = []
    L.append(0)
    L.append(L1)
    max_leaf_count = 6  #每个hash树节点的最大容量
    max_child_count = 6  #每个hash树节点的最大子节点数

    start = time.time()
    while(len(L[k-1])>0):
        ck,final_ck = apriori_generate(L[k-1],k)                 #生成候选项集
        # print("C%d" %(k))
        # print(final_ck)
        h_tree = generate_hash_tree(ck,max_leaf_count,max_child_count)       #生成hash树
        if (k > 2):
            while(len(L[k-1])>0):
                l = generateL(final_ck, min_support)
                L.append(l)
                # print("Frequent %d item" % (k))
                # print(l)
                k = k + 1
                ck, final_ck = apriori_generate(L[k - 1], k)
                # print("C%d" % (k))
                # print(final_ck)
            break
        k_subsets = generate_k_subsets(Transaction1,k)                  #生成事物子集
        for subset in k_subsets:
            h_tree.add_support(subset)                                  #像hash树的项集添加支持数
        lk = []
        h_tree.get_frequent_itemsets(h_tree.root,min_support,lk)                  #获取频繁项集
        # print("Frequent %d item" %(k))
        # print(lk)
        L.append(lk)
        k = k + 1
    end = time.time()
    return L,(end-start)

L_value,time_taken = apriori(values,min_support)
#print("final L_value")
#print(L_value)
print("All frequent itemsets with their support count:")
print(Frequent_items_value)

到了这里,关于数据挖掘与机器学习:Apripori算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ElasticSearch的数据挖掘与机器学习

    ElasticSearch是一个开源的搜索和分析引擎,它基于Lucene库构建,具有高性能、易用性和扩展性。ElasticSearch可以用于实时搜索、数据分析和机器学习等应用场景。本文将涵盖ElasticSearch的数据挖掘与机器学习方面的核心概念、算法原理、最佳实践以及实际应用场景。 在ElasticSear

    2024年02月22日
    浏览(57)
  • 机器学习——数据仓库与数据挖掘——期末复习(简答题)

    1 、试述真正例率(TPR)、假正例率(FPR)与查准率(P)、查全率(R)之间的联系。 查全率: 真实正例被预测为正例的比例 真正例率: 真实正例被预测为正例的比例 查全率与真正例率是相等的。 查准率:预测为正例的实例中真实正例的比例 假正例率: 真实反例被预测为正例的

    2024年02月10日
    浏览(63)
  • Python 数据挖掘与机器学习教程

    详情点击链接:Python 数据挖掘与机器学习 一: Python编程 Python编程入门 1、Python环境搭建( 下载、安装与版本选择)。 2、如何选择Python编辑器?(IDLE、Notepad++、PyCharm、Jupyter…) 3、Python基础(数据类型和变量、字符串和编码、list和tuple、条件判断、循环、函数的定义与调

    2024年02月16日
    浏览(57)
  • 机器学习和数据挖掘01- lasso regularization

    Lasso正则化是一种线性回归中的正则化技术,旨在减少模型的复杂性并防止过拟合。Lasso(Least Absolute Shrinkage and Selection Operator)通过在损失函数中添加正则项,促使模型的系数变得稀疏,即某些系数会被压缩到零,从而实现特征选择。 在Lasso正则化中,我们引入了一个惩罚项

    2024年02月09日
    浏览(52)
  • 机器学习——数据仓库与数据挖掘复习(选择题、判断题)

    1. 以下不是分类问题的是(  B )。 A. 用户流失模型 B. 身高和体重关系 C. 信用评分 D. 营销响应 2. 对于回归分析,下列说法错误的是( D ) A. 在回归分析中,变量间的关系若是非确定关系,那么因变量不能由自变量唯一确定 B. 线性相关系数可以是正的,也可以是负的 C. 回归

    2024年02月06日
    浏览(59)
  • 机器学习和数据挖掘03-模型性能评估指标

    概念:模型正确预测的样本数量与总样本数量的比例。 公式:Accuracy = (TP + TN) / (TP + TN + FP + FN) TP (True Positives):正确预测为正例的样本数。即模型正确地将正例判定为正例。 TN (True Negatives):正确预测为负例的样本数。即模型正确地将负例判定为负例。 FP (False Positives):错误

    2024年02月10日
    浏览(181)
  • 机器学习和数据挖掘04-PowerTransformer与 MinMaxScaler

    PowerTransformer 是用于对数据进行幂变换(也称为Box-Cox变换)的预处理工具。幂变换可以使数据更接近正态分布,这有助于某些机器学习算法的性能提升。它支持两种常用的幂变换:Yeo-Johnson变换和Box-Cox变换。 MinMaxScaler 是用于将数据进行最小-最大缩放的预处理工具。它将数据

    2024年02月10日
    浏览(55)
  • 大数据和智能数据应用架构系列教程之:大数据挖掘与机器学习

    作者:禅与计算机程序设计艺术 随着互联网的普及、移动互联网的爆炸性增长以及电子商务的兴起,传统的基于数据库的数据分析已不能满足当前信息社会对海量数据的处理需求。如何有效地进行大数据分析已经成为众多行业面临的共同难题。而数据挖掘和机器学习(Machi

    2024年02月08日
    浏览(51)
  • 机器学习和数据挖掘02-Gaussian Naive Bayes

    贝叶斯定理: 贝叶斯定理是概率中的基本定理,描述了如何根据更多证据或信息更新假设的概率。在分类的上下文中,它用于计算给定特征集的类别的后验概率。 特征独立性假设: 高斯朴素贝叶斯中的“朴素”假设是,给定类别标签,特征之间是相互独立的。这个简化假设

    2024年02月10日
    浏览(55)
  • 基于数据挖掘机器学习的心脏病患者分类建模与分析

    首先,读取数据集,该数据集是UCI上的心脏病患者数据集,其中包含了 303 条患者信息,每一名患者有 13 个字段记录其基本信息(年龄、性别等)和身体健康信息(心率、血糖等),此外有一个类变量记录其是否患有心脏病。详细的字段信息可见 此处。 类别字段 target 有两

    2024年01月19日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包