Apriori算法
Apriori算法是关联规则挖掘,用于挖掘数据集中频繁项集的算法,生成关联规则。主要应用与数据挖掘、机器学习等领域。
Apriori算法原理
主要是关联规则挖掘的经典算法,关联规则是数据挖掘中的一个分支,目标是发现一个数据集中变量件的关联模式。
-
关联规则(关联分析)的基本概念
①项集:项目的集合;
②关联分析:关联分析是一种在大规模数据集中有目的的寻找关系的任务,目的是发现数据项之间隐藏的、有价值的关联模式,为决策提供有意义的信息;
③支持度:数据集中包含该项集的记录所占的比例,即某个项集在所有交易中出现的频率。它用于衡量一个项集的普遍性。
④置信度或可信度:定义为条件概率,是在
A事件出现的情况下,B事件出现的条件概率;⑤频繁项集:经常一起出现的项目的集合,定义为支持度大于某一阀值的集合;
⑥关联规则:置信度大于一定阀值的关系。
-
关联规则(关联分析)寻找的关系
①频繁项集:频繁项集是经常一起出现的项目的集合,具体定义为在数据集中支持度大于某一阈值的项目集合。支持度反映了该项集在整个数据集中出现的频率,是衡量项集频繁程度的重要指标。
②关联规则:关联规则表示数据项之间的一种逻辑关系,其置信度大于一定阈值。置信度定义为条件概率,用于衡量在一个项集出现的情况下,另一个项集出现的可能性大小。
算法流程
Apriori算法的两个输入参数是数据集和最小支持度(阈值)。其流程如下:
①生成单个项的所有项集,遍历所有交易事件,筛选出单个项的频繁项集。
②对于包含k个项的频繁项集,两两组合生成k+1项项集,删除非频繁项集,获得k+1频繁项集直到算法收敛。
③返回频繁项集。
实验实现
-
实验目的
掌握Apriori算法的原理。通过实际操作与编程实现,能够运用该算法对数据进行关联分析,挖掘数据集中的频繁项集和关联规则,从而提升在数据挖掘领域的实践能力与理论水平,为处理大规模数据中的关联关系提供有效的技术手段。 -
数据准备
使用一行字母代表一次交易事件;
每行内有多个大写字母代表交易元素,每个元素用空格分隔;
每行(本次交易)结束用回车与下一行(下一个交易)分隔;
最后用**'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 # 表示输入五个交易事件 -
实验流程及代码
完整代码
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)
实验结果
请输入交易事件(每行一个交易,交易内各元素用空格分隔,每个交易以回车键结束,输入'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次的频繁级。如上结果可知,已正确实现输出符合最小支持度阀值的频繁集。且经过计算和验证,以上结果符合强关联规则的要求。