2023年9月-实验三
【实验名称】
关联规则求取
【实验目的】
通过实验二的最大频繁集,求出关联规则,最小置信度为40%。
【实验内容】
1、程序清单
from itertools import combinations
from collections import defaultdict
def generate_frequent_itemsets(data, min_support, filtered=1):
# 步骤1:初始化第1阶的候选项集
itemsets = []
for transaction in data:
for item in transaction:
itemsets.append(frozenset([item]))
# 步骤2:为每个阶段生成频繁项集
frequent_itemsets = []
order = 1
while itemsets:
# 统计每个候选项集的出现次数
itemset_counts = defaultdict(int)
for transaction in data:
for itemset in itemsets:
if itemset.issubset(transaction):
itemset_counts[itemset] += 1
# 过滤满足最小支持度阈值的候选项集
frequent_itemsets_order = [itemset for itemset, count in itemset_counts.items() if count >= min_support]
# 将频繁项集添加到最终列表中
frequent_itemsets.extend(frequent_itemsets_order)
# 生成下一个阶段的候选项集
itemsets = []
for i in range(len(frequent_itemsets_order)):
for j in range(i + 1, len(frequent_itemsets_order)):
itemset1 = frequent_itemsets_order[i]
itemset2 = frequent_itemsets_order[j]
new_itemset = itemset1.union(itemset2)
if len(new_itemset) == order + 1:
itemsets.append(new_itemset)
order += 1
if filtered == 1:
frequent_itemsets_filtered = []
for i in range(len(frequent_itemsets)):
flag = 1
for j in range(i + 1, len(frequent_itemsets)):
itemset1 = frequent_itemsets[i]
itemset2 = frequent_itemsets[j]
# 在昨天生成的频繁集的列表里拿个元素往后找,
# 如果它是其后某个频繁集的子集,
# 则说明这个频繁集是冗余的,需要过滤掉
if itemset1.issubset(itemset2):
flag = 0
if flag == 1:
frequent_itemsets_filtered.append(frequent_itemsets[i])
return frequent_itemsets_filtered
else:
return frequent_itemsets
# 根据generate_frequent_itemsets里给出的平凡项集生成关联规则
def generate_association_rules(frequent_itemsets, min_confidence):
# 存储关联规则
association_rules = []
all_frequent_itemsets = generate_frequent_itemsets(data,min_support,0)
# 存储每个频繁项集的计数
itemset_counts = {}
for itemset in all_frequent_itemsets:
itemset_counts[itemset] = 0
for transaction in data:
if itemset.issubset(transaction):
itemset_counts[itemset] += 1
# 遍历每个频繁项集,如果置信度大于最小置信度,则添加到association_rules列表中
for itemset in frequent_itemsets:
# 遍历每个频繁项集的第一个元素
for i in range(1, len(itemset)):
# 遍历每个频繁项集的第一个元素的每一个子集
for antecedent in combinations(itemset, i):
# 获取antecedent的差集
consequent = itemset.difference(antecedent)
# # 计算antecedent和consequent的置信度
# print(itemset_counts[itemset])
# print(itemset_counts[antecedent])
confidence_forward = itemset_counts[itemset] / itemset_counts[frozenset(antecedent)]
# 如果置信度大于最小置信度,则添加到association_rules列表中
if confidence_forward >= min_confidence:
association_rules.append((antecedent, consequent, confidence_forward))
# 计算antecedent和consequent的反向置信度
confidence_backward = itemset_counts[itemset] / itemset_counts[frozenset(consequent)]
if confidence_backward >= min_confidence:
association_rules.append((consequent, antecedent, confidence_backward))
return association_rules
# 示例数据和最小支持度
data = [[1, 2, 5], [2, 4], [2, 3], [1, 2, 4], [1, 3], [2, 3], [1, 3], [1, 2, 3, 5], [1, 2, 3]]
min_support = 2
min_confidence = 0.4
# 生成频繁项集
frequent_itemsets = generate_frequent_itemsets(data, min_support, 1)
# 打印频繁项集
for itemset in frequent_itemsets:
print(sorted(list(itemset)))
# 打印关联规则
association_rules = generate_association_rules(frequent_itemsets, min_confidence)
for antecedent, consequent, confidence in association_rules:
print(sorted(list(antecedent)), "-->", sorted(list(consequent)), "confidence =", confidence)
2、结果截图
【实验体会】
在本次实验里我对generate_frequent_itemsets的功能做了进一步扩充,让其能生成所有频繁集的支持度与过滤后的最大频繁集的支持度。以此作为一个表供生成频繁集的方法generate_association_rules里计算置信度使用。当filtered=1时,会在实验二中生成的频繁集里的列表里拿个元素往后找,如果它是其后某个频繁集的子集,则说明这个频繁集是冗余的,需要过滤掉。