数据挖掘 | Apriori算法

179 阅读6分钟

Apriori算法

Apriori算法是关联规则挖掘,用于挖掘数据集中频繁项集的算法,生成关联规则。主要应用与数据挖掘、机器学习等领域。

Apriori算法原理

主要是关联规则挖掘的经典算法,关联规则是数据挖掘中的一个分支,目标是发现一个数据集中变量件的关联模式

  1.  关联规则(关联分析)的基本概念

    ①项集:项目的集合;

    ②关联分析:关联分析是一种在大规模数据集中有目的的寻找关系的任务,目的是发现数据项之间隐藏的、有价值的关联模式,为决策提供有意义的信息;

    ③支持度:数据集中包含该项集的记录所占的比例,即某个项集在所有交易中出现的频率。它用于衡量一个项集的普遍性。

    ④置信度或可信度:定义为条件概率,是在A事件出现的情况下,B事件出现的条件概率;

    ⑤频繁项集:经常一起出现的项目的集合,定义为支持度大于某一阀值的集合;

    ⑥关联规则:置信度大于一定阀值的关系。

  2.  关联规则(关联分析)寻找的关系

    ①频繁项集:频繁项集是经常一起出现的项目的集合,具体定义为在数据集中支持度大于某一阈值的项目集合。支持度反映了该项集在整个数据集中出现的频率,是衡量项集频繁程度的重要指标。

    ②关联规则:关联规则表示数据项之间的一种逻辑关系,其置信度大于一定阈值。置信度定义为条件概率,用于衡量在一个项集出现的情况下,另一个项集出现的可能性大小。

算法流程

数据挖掘-Apriori算法.drawio

Apriori算法的两个输入参数是数据集和最小支持度(阈值)。其流程如下:
①生成单个项的所有项集,遍历所有交易事件,筛选出单个项的频繁项集。

②对于包含k个项的频繁项集,两两组合生成k+1项项集,删除非频繁项集,获得k+1频繁项集直到算法收敛。

③返回频繁项集。

实验实现

  1.  实验目的
    掌握Apriori算法的原理。通过实际操作与编程实现,能够运用该算法对数据进行关联分析,挖掘数据集中的频繁项集关联规则,从而提升在数据挖掘领域的实践能力与理论水平,为处理大规模数据中的关联关系提供有效的技术手段。

  2. 数据准备

    使用一行字母代表一次交易事件

    每行内有多个大写字母代表交易元素,每个元素用空格分隔;

    每行(本次交易)结束用回车与下一行(下一个交易)分隔;

    最后用**'end'并回车**表示输入结束。

    # 以下是一次输入记录,表示实验数据
    F O N K A B
    D O N K A BA K A
    F U L K B
    L O O K I A
    end
    # 表示输入五个交易事件
    
  3.  实验流程及代码数据挖掘-Apriori算法.drawio

完整代码

import itertools

def item(dataset):
    # 生成1-项集:生成单项候选集
    c1 = []
    for x in dataset:
        for y in x:
            if [y] not in c1:
                c1.append([y])
    c1.sort()
    return c1

# 计算候选集的支持度,选出k项频繁集
def get_frequent_item(dataset, c, min_support, transaction_count):
    # 计算频繁项集
    cut_branch = {}
    for x in c:
        for y in dataset:
            if set(x).issubset(set(y)):
                if tuple(x) not in cut_branch:
                    cut_branch[tuple(x)] = 1
                else:
                    cut_branch[tuple(x)] += 1
    Fk = []
    sup_dataK = {}
    for i in cut_branch:
        # 实现基于支持度阈值的剪枝操作
        if cut_branch[i] >= transaction_count * min_support:
            Fk.append(list(i))
            sup_dataK[i] = cut_branch[i]
    return Fk, sup_dataK

# 由k项频繁集生成k+1项候选集
def get_candidate(Fk, K):
    ck = []
    for i in range(len(Fk)):
        for j in range(i + 1, len(Fk)):
            L1 = list(Fk[i])[:K - 2]
            L2 = list(Fk[j])[:K - 2]
            L1.sort()
            L2.sort()
            if L1 == L2:
                if K > 2:
                    new = list(set(Fk[i]) ^ set(Fk[j]))
                else:
                    new = set()
                candidate = list(set(Fk[i]) | set(Fk[j]))
                # 进行剪枝操作,检查所有K - 1个子集是否都是频繁项集
                all_subsets_frequent = True
                for subset in itertools.combinations(candidate, K - 1):
                    if list(subset) not in Fk:
                        all_subsets_frequent = False
                        break
                if all_subsets_frequent:
                    for x in Fk:
                        if set(new).issubset(set(x)) and candidate not in ck:
                            ck.append(candidate)
    return ck

# Apriori算法的主要实现部分
# 通过不断迭代生成更高层次的频繁项集,直到无法再找到新的频繁项集为止
def Apriori(dataset, min_support):
    # 执行Apriori算法
    c1 = item(dataset)
    transaction_count = len(dataset)
    f1, sup_1 = get_frequent_item(dataset, c1, min_support, transaction_count)
    F = [f1]
    sup_data = sup_1
    K = 2
    while (len(F[K - 2]) > 1):
        ck = get_candidate(F[K - 2], K)
        fk, sup_k = get_frequent_item(dataset, ck, min_support, transaction_count)
        F.append(fk)
        sup_data.update(sup_k)
        K += 1
    return F, sup_data


# 实现发现强关联规则
def generate_association_rules(patterns, confidence_threshold, support_data):
    # 生成关联规则
    rules = []
    for itemset in patterns.keys():
        upper_support = patterns[itemset]
        for i in range(1, len(itemset)):
            for antecedent in itertools.combinations(itemset, i):
                antecedent = tuple(sorted(antecedent))
                consequent = tuple(sorted(set(itemset) - set(antecedent)))
                if antecedent in patterns and consequent in patterns:
                    lower_support = patterns[antecedent]
                    confidence = float(upper_support) / lower_support
                    lift = float(upper_support) / (support_data[antecedent] * support_data[consequent] / len(dataset))
                    if confidence >= confidence_threshold and lift>=1.0:
                        rules.append([antecedent, consequent, confidence, lift])
    return rules

# 打印输出实验数据及结果
def printPatterns(patterns):
    # 打印频繁项集
    keys1 = list(patterns.keys())
    values1 = list(patterns.values())
    for i in range(len(keys1)):
        keys1[i] = list(keys1[i])
        for j in range(len(keys1[i])):
            print(keys1[i][j]end=" ")
        for i2 in range(10 - 2 * len(keys1[i])):
            print(" ", end="")
        print(" : ", end="")
        print(values1[i]end="\n")

# 打印强关联规则及其置信度
def printRules2(rules):
    # 打印关联规则
    for rule in rules:
        antecedent, consequent, confidence, lift = rule
        print(' '.join(antecedent), ' --> ', ' '.join(consequent), ': Confidence: ', confidence, ' Lift: ', lift)

if __name__ == '__main__':
    # 用户输入数据集
    dataset = []
    print("请输入交易事件(每行一个交易,交易内各元素用空格分隔,每个交易以回车键结束,输入'end'并回车结束输入过程):")
    while True:
        line = input()
        if line == "end":
            break
        dataset.append(line.split())

    # 用户输入最小支持度阈值
    min_support = float(input("请输入最小支持度阈值:"))

    F, sup_data = Apriori(dataset, min_support)

    print("各频繁集及其出现次数", end="\n")
    printPatterns(sup_data)
    print('---------------------------------')

    min_confidence = float(input("请输入最小置信度阈值:"))
    rules = generate_association_rules(sup_data, min_confidence, sup_data)

    print("各强关联规则及其置信度和提升度", end="\n")
    printRules2(rules)

实验结果

87cac1fb-02d1-449c-8168-0bde597cf34a

ee50aba9bd48e8f25067dc72c2250ef3

请输入交易事件(每行一个交易,交易内各元素用空格分隔,每个交易以回车键结束,输入'end'并回车结束输入过程):
F O N K A B
D O N K A B
F A K A
F U L K B
L O O K I A
end
请输入最小支持度阈值:0.6
各频繁集及其出现次数
A          : 4
B          : 3
F          : 3
K          : 5
O          : 3
K A        : 4
O A        : 3
K B        : 3
K F        : 3
K O        : 3
K O A      : 3
---------------------------------
请输入最小置信度阈值:0.7
各强关联规则及其置信度和提升度
K  -->  A : Confidence:  0.8  Lift:  1.0
A  -->  K : Confidence:  1.0  Lift:  1.0
O  -->  A : Confidence:  1.0  Lift:  1.25
A  -->  O : Confidence:  0.75  Lift:  1.25
B  -->  K : Confidence:  1.0  Lift:  1.0
F  -->  K : Confidence:  1.0  Lift:  1.0
O  -->  K : Confidence:  1.0  Lift:  1.0
A  -->  K O : Confidence:  0.75  Lift:  1.25
K O  -->  A : Confidence:  1.0  Lift:  1.25

按照提示输入五个交易事件,并以end结束。我输入的支持阀值为0.6,根据频繁集的定义,则需要输出出现次数大于等于3次的频繁级。如上结果可知,已正确实现输出符合最小支持度阀值的频繁集。且经过计算和验证,以上结果符合强关联规则的要求。