分解过程如下,完整代码在最后。
不知道apriori算法规则的小伙伴可以看看我写的另一个文章

def load_data_set():
    """
    加载一个示例数据集(来自数据挖掘:概念和技术,第3版)
    返回:数据集:事务列表。每个事务包含若干项。
    """
    data_set = [
        ['l1', 'l2', 'l5']
        , ['l2', 'l4']
        , ['l2', 'l3']
        , ['l1', 'l2', 'l4']
        , ['l1', 'l3']
        , ['l2', 'l3']
        , ['l1', 'l3']
        , ['l1', 'l2', 'l3', 'l5']
        , ['l1', 'l2', 'l3']
    ]
    return data_set


def create_C1(data_set):
    """
    通过扫描数据集创建频繁的候选1-itemset c1。
    参数:
        data_set:事务列表。每个事务包含若干项。
    返回:
        C1:包含所有频繁候选的1-项集的集合
    """
    C1 = set()
    for t in data_set:
        for item in t:
            item_set = frozenset([item])
            C1.add(item_set)
    return C1


if __name__ == "__main__":
    data_set = load_data_set()
    C1 = create_C1(data_set)
    for item in C1:
        print(item)

set函数的作用:
set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等

x = set(‘runoob’)
 y = set(‘google’)
 x, y (set([‘b’, ‘r’, ‘u’, ‘o’, ‘n’]), set([‘e’, ‘o’, ‘g’, ‘l’])) # 重复的被删除
 x & y # 交集 set([‘o’])
 x | y # 并集 set([‘b’, ‘e’, ‘g’, ‘l’, ‘o’, ‘n’, ‘r’, ‘u’])
 x - y # 差集 set([‘r’, ‘b’, ‘u’, ‘n’])

frozenset()函数: 返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。

为什么需要冻结的集合(即不可变的集合)呢?因为在集合的关系中,有集合的中的元素是另一个集合的情况,但是普通集合(set)本身是可变的,那么它的实例就不能放在另一个集合中(set中的元素必须是不可变类型)。

所以,frozenset提供了不可变的集合的功能,当集合不可变时,它就满足了作为集合中的元素的要求,就可以放在另一个集合中了。

输出结果
PS D:\Program Files\Anaconda\workplaces>  cd 'd:\Program Files\Anaconda\workplaces'; & 'D:\Program Files\Anaconda\python.exe' 'c:\Users\laowu\.vscode\extensions\ms-python.python-2020.9.114305\pythonFiles\lib\python\debugpy\launcher' '49700' '--' 'd:\Program Files\Anaconda\workplaces\test.py' 
frozenset({'l3'})
frozenset({'l4'})
frozenset({'l5'})
frozenset({'l2'})
frozenset({'l1'})

在代码中增加以下函数

def is_apriori(Ck_item, Lksub1):
    """
    判断一个频繁候选的k项集是否满足Apriori性质。
    参数:
        Ck_item:Ck中包含所有频繁候选k项集的频繁候选k项集。
        Lksub1: Lk-1,一个包含所有频繁候选(k-1)项集的集合。
    返回:
        真:满足先验性质。
        假:不满足先验性质。
    """
    for item in Ck_item:
        sub_Ck = Ck_item - frozenset([item])
        if sub_Ck not in Lksub1:
            return False
    return True


def create_Ck(Lksub1, k):
    """
    通过Lk-1自己的连接操作创建包含所有频繁候选k-itemset的集合ck。
    参数:
        Lksub1: Lk-1,一个包含所有频繁候选(k-1)项集的集合。
        k:频繁项目集的项目编号。
    返回:Ck:包含所有频繁候选k项集的集合。
    """
    Ck = set()
    len_Lksub1 = len(Lksub1)
    list_Lksub1 = list(Lksub1)
    for i in range(len_Lksub1):
        for j in range(1, len_Lksub1):
            l1 = list(list_Lksub1[i])
            l2 = list(list_Lksub1[j])
            l1.sort()
            l2.sort()
            if l1[0:k-2] == l2[0:k-2]:
                Ck_item = list_Lksub1[i] | list_Lksub1[j]
                # pruning
                if is_apriori(Ck_item, Lksub1):
                    Ck.add(Ck_item)
    return Ck
def generate_Lk_by_Ck(data_set, Ck, min_support, support_data):
    """
    通过从ck执行删除策略生成Lk。
    参数:
        data_set:事务列表。每个事务包含若干项。
        ck:包含所有频繁候选k项集的集合。
        min_support:最小支持。
        support_data:字典。关键是频繁项集,值是支持。
    返回:
        Lk:一个包含所有常见k项集的集合。
    """
    Lk = set()
    item_count = {}
    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] / t_num
    return Lk


def generate_L(data_set, k, min_support):
    """
    生成所有频繁项集。
    参数:
        data_set:事务列表。每个事务包含若干项。
        k:所有频繁项集的最大项数。
        min_support:最小支持。
    返回:
        L: Lk的清单
        support_data:字典。关键是频繁项集,值是支持。
    """
    support_data = {}
    C1 = create_C1(data_set)
    L1 = generate_Lk_by_Ck(data_set, C1, min_support, support_data)
    Lksub1 = L1.copy()
    L = []
    L.append(Lksub1)
    for i in range(2, k+1):
        Ci = create_Ck(Lksub1, i)
        Li = generate_Lk_by_Ck(data_set, Ci, min_support, support_data)
        Lksub1 = Li.copy()
        L.append(Lksub1)
    return L, support_data
if __name__ == "__main__":
    data_set = load_data_set()
    C1 = create_C1(data_set)
    print("请输入最大频繁项:")
    n=int(input())
    L, support_data = generate_L(data_set, n, 0.2)
    for item in support_data:
        print(item, ": ", support_data[item])

issubset函数作用:判断是否在集合中
输出结果

PS D:\Program Files\Anaconda\workplaces>  cd 'd:\Program Files\Anaconda\workplaces'; & 'D:\Program Files\Anaconda\python.exe' 'c:\Users\laowu\.vscode\extensions\ms-python.python-2020.9.114305\pythonFiles\lib\python\debugpy\launcher' '51052' '--' 'd:\Program Files\Anaconda\workplaces\test.py' 
请输入最大频繁项:
5
frozenset({'l1'}) :  0.6666666666666666
frozenset({'l2'}) :  0.7777777777777778
frozenset({'l5'}) :  0.2222222222222222
frozenset({'l4'}) :  0.2222222222222222
frozenset({'l3'}) :  0.6666666666666666
frozenset({'l1', 'l2'}) :  0.4444444444444444
frozenset({'l1', 'l5'}) :  0.2222222222222222
frozenset({'l5', 'l2'}) :  0.2222222222222222
frozenset({'l4', 'l2'}) :  0.2222222222222222
frozenset({'l3', 'l2'}) :  0.4444444444444444
frozenset({'l1', 'l3'}) :  0.4444444444444444
frozenset({'l1', 'l5', 'l2'}) :  0.2222222222222222
frozenset({'l1', 'l3', 'l2'}) :  0.2222222222222222

最大频繁项集为3,则4,5为空。
在代码中增加以下函数

def generate_big_rules(L, support_data, min_conf):
    """
    从频繁的项目集生成大规则。
    参数:
        L: Lk的清单。
        support_data:一本字典。关键是频繁项集,值是支持。
        min_conf:最小信任
    返回:
        大规则列表:包含所有大规则的列表。每个大的规则都被表现出来作为一个r3。
    """
    big_rule_list = []
    sub_set_list = []
    for i in range(0, len(L)):
        for freq_set in L[i]:
            for sub_set in sub_set_list:
                if sub_set.issubset(freq_set):
                    conf = support_data[freq_set] / support_data[freq_set - sub_set]
                    big_rule = (freq_set - sub_set, sub_set, conf)
                    if conf >= min_conf and big_rule not in big_rule_list:
                        # print freq_set-sub_set, " => ", sub_set, "conf: ", conf
                        big_rule_list.append(big_rule)
            sub_set_list.append(freq_set)
    return big_rule_list
if __name__ == "__main__":
    data_set = load_data_set()
    C1 = create_C1(data_set)
    print("请输入最大频繁项:")
    n=int(input())
    L, support_data = generate_L(data_set, n, 0.2)
    rule_list = generate_big_rules(L, support_data, 0.7)
    for item in rule_list:
        print(item[0], "=>", item[1], "'s conf:", item[2])

输出结果

frozenset({'l5'}) => frozenset({'l2'}) 's conf: 1.0
frozenset({'l4'}) => frozenset({'l2'}) 's conf: 1.0
frozenset({'l5'}) => frozenset({'l1'}) 's conf: 1.0
frozenset({'l1', 'l5'}) => frozenset({'l2'}) 's conf: 1.0
frozenset({'l5', 'l2'}) => frozenset({'l1'}) 's conf: 1.0
frozenset({'l5'}) => frozenset({'l1', 'l2'}) 's conf: 1.0

完整代码

def load_data_set():
    """
    加载一个示例数据集(来自数据挖掘:概念和技术,第3版)
    返回:数据集:事务列表。每个事务包含若干项。
    """
    data_set = [
        ['l1', 'l2', 'l5']
        , ['l2', 'l4']
        , ['l2', 'l3']
        , ['l1', 'l2', 'l4']
        , ['l1', 'l3']
        , ['l2', 'l3']
        , ['l1', 'l3']
        , ['l1', 'l2', 'l3', 'l5']
        , ['l1', 'l2', 'l3']
    ]
    return data_set


def create_C1(data_set):
    """
    通过扫描数据集创建频繁的候选1-itemset c1。
    参数:
        data_set:事务列表。每个事务包含若干项。
    返回:
        C1:包含所有频繁候选的1-项集的集合
    """
    C1 = set()
    for t in data_set:
        for item in t:
            item_set = frozenset([item])
            C1.add(item_set)
    return C1


def is_apriori(Ck_item, Lksub1):
    """
    判断一个频繁候选的k项集是否满足Apriori性质。
    参数:
        Ck_item:Ck中包含所有频繁候选k项集的频繁候选k项集。
        Lksub1: Lk-1,一个包含所有频繁候选(k-1)项集的集合。
    返回:
        真:满足先验性质。
        假:不满足先验性质。
    """
    for item in Ck_item:
        sub_Ck = Ck_item - frozenset([item])
        if sub_Ck not in Lksub1:
            return False
    return True


def create_Ck(Lksub1, k):
    """
    通过Lk-1自己的连接操作创建包含所有频繁候选k-itemset的集合ck。
    参数:
        Lksub1: Lk-1,一个包含所有频繁候选(k-1)项集的集合。
        k:频繁项目集的项目编号。
    返回:Ck:包含所有频繁候选k项集的集合。
    """
    Ck = set()
    len_Lksub1 = len(Lksub1)
    list_Lksub1 = list(Lksub1)
    for i in range(len_Lksub1):
        for j in range(1, len_Lksub1):
            l1 = list(list_Lksub1[i])
            l2 = list(list_Lksub1[j])
            l1.sort()
            l2.sort()
            if l1[0:k-2] == l2[0:k-2]:
                Ck_item = list_Lksub1[i] | list_Lksub1[j]
                # pruning
                if is_apriori(Ck_item, Lksub1):
                    Ck.add(Ck_item)
    return Ck


def generate_Lk_by_Ck(data_set, Ck, min_support, support_data):
    """
    通过从ck执行删除策略生成Lk。
    参数:
        data_set:事务列表。每个事务包含若干项。
        ck:包含所有频繁候选k项集的集合。
        min_support:最小支持。
        support_data:字典。关键是频繁项集,值是支持。
    返回:
        Lk:一个包含所有常见k项集的集合。
    """
    Lk = set()
    item_count = {}
    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] / t_num
    return Lk


def generate_L(data_set, k, min_support):
    """
    生成所有频繁项集。
    参数:
        data_set:事务列表。每个事务包含若干项。
        k:所有频繁项集的最大项数。
        min_support:最小支持。
    返回:
        L: Lk的清单
        support_data:字典。关键是频繁项集,值是支持。
    """
    support_data = {}
    C1 = create_C1(data_set)
    L1 = generate_Lk_by_Ck(data_set, C1, min_support, support_data)
    Lksub1 = L1.copy()
    L = []
    L.append(Lksub1)
    for i in range(2, k+1):
        Ci = create_Ck(Lksub1, i)
        Li = generate_Lk_by_Ck(data_set, Ci, min_support, support_data)
        Lksub1 = Li.copy()
        L.append(Lksub1)
    return L, support_data


def generate_big_rules(L, support_data, min_conf):
    """
    从频繁的项目集生成大规则。
    参数:
        L: Lk的清单。
        support_data:一本字典。关键是频繁项集,值是支持。
        min_conf:最小信任
    返回:
        大规则列表:包含所有大规则的列表。每个大的规则都被表现出来作为一个r3。
    """
    big_rule_list = []
    sub_set_list = []
    for i in range(0, len(L)):
        for freq_set in L[i]:
            for sub_set in sub_set_list:
                if sub_set.issubset(freq_set):
                    conf = support_data[freq_set] / support_data[freq_set - sub_set]
                    big_rule = (freq_set - sub_set, sub_set, conf)
                    if conf >= min_conf and big_rule not in big_rule_list:
                        # print freq_set-sub_set, " => ", sub_set, "conf: ", conf
                        big_rule_list.append(big_rule)
            sub_set_list.append(freq_set)
    return big_rule_list


if __name__ == "__main__":
    data_set = load_data_set()
    L, support_data = generate_L(data_set, k=3, min_support=0.2)
    big_rules_list = generate_big_rules(L, support_data, min_conf=0.7)
    for Lk in L:
        print("="*50)
        print("frequent " + str(len(list(Lk)[0])) + "-itemsets\t\tsupport")
        print("="*50)
        for freq_set in Lk:
            print(freq_set, support_data[freq_set])
    print
    print("关联规则:")
    for item in big_rules_list:
        print(item[0], "=>", item[1], "conf: ", item[2])