数学建模学习-Apriori关联规则挖掘算法教程(32)

数学建模学习-Apriori关联规则挖掘算法教程(32)

写在最前

注意本文的相关代码及例子为同学们提供参考,借鉴相关结构,在这里举一些通俗易懂的例子,方便同学们根据实际情况修改代码,很多同学私信反映能否添加一些可视化,这里每篇教程都尽可能增加一些可视化方便同学理解,但具体使用时,同学们要根据实际情况选择是否在论文中添加可视化图片。

系列教程计划持续更新,同学们可以免费订阅专栏,内容充足后专栏可能付费,提前订阅的同学可以免费阅读,同时相关代码获取可以关注博主评论或私信。

目录

  1. 算法简介
  2. 算法特点
  3. 理论基础
  4. 环境准备
  5. 算法实现
  6. 结果分析
  7. 应用场景
  8. 性能优化
  9. 总结

算法简介

Apriori算法是一种经典的关联规则挖掘算法,主要用于发现大型数据集中项目之间的关联关系。该算法最早由Agrawal和Srikant于1994年提出,是数据挖掘领域中最具影响力的算法之一。

算法的核心思想基于两个重要的概念:

  1. 支持度(Support):某个项集在所有交易中出现的频率
  2. 置信度(Confidence):条件概率,表示包含项集A的交易中同时包含项集B的概率

算法特点

1. 优点

  • 原理简单,易于理解和实现
  • 可以发现数据中的强关联规则
  • 适用于各种类型的交易数据分析
  • 结果可解释性强
  • 可以处理大规模数据集
  • 支持增量更新

2. 缺点

  • 在处理大规模数据集时可能效率较低
  • 需要多次扫描数据集
  • 可能产生大量的候选项集
  • 对于稀疏数据集效率不高
  • 内存消耗较大
  • 不适合处理高维数据

3. 关键参数

  • 最小支持度(min_support):用于筛选频繁项集
  • 最小置信度(min_confidence):用于生成关联规则
  • 提升度(lift):衡量规则的相关性强度
  • 最大项集大小:控制生成的频繁项集的最大长度
  • 最小项集大小:控制生成的频繁项集的最小长度

理论基础

1. 基本概念

1.1 项集(Itemset)
  • 定义:一个或多个项目的集合
  • 示例:{面包, 牛奶} 是一个2项集
  • k项集:包含k个项目的项集
1.2 支持度(Support)
  • 定义:项集在所有交易中出现的频率
  • 计算公式:support(X) = count(X) / N
  • 其中,count(X)是包含项集X的交易数,N是总交易数
1.3 置信度(Confidence)
  • 定义:条件概率P(Y|X),表示包含X的交易中同时包含Y的概率
  • 计算公式:confidence(X→Y) = support(X∪Y) / support(X)
1.4 提升度(Lift)
  • 定义:衡量规则的相关性强度
  • 计算公式:lift(X→Y) = confidence(X→Y) / support(Y)
  • 解释:
    • lift > 1:正相关
    • lift = 1:独立
    • lift < 1:负相关

2. 算法原理

2.1 先验知识(Apriori Property)
  • 如果一个项集是频繁的,则它的所有子集也是频繁的
  • 如果一个项集是非频繁的,则它的所有超集也是非频繁的
2.2 算法步骤
  1. 生成候选1项集
  2. 扫描数据库,计算支持度
  3. 删除不满足最小支持度的项集
  4. 连接步:合并k项频繁项集生成k+1项候选项集
  5. 剪枝步:删除包含非频繁k项子集的候选项集
  6. 重复步骤2-5直到无法生成新的频繁项集
2.3 关联规则生成
  1. 对每个频繁项集生成所有可能的非空真子集
  2. 对每个子集生成关联规则
  3. 计算规则的置信度
  4. 保留满足最小置信度的规则

环境准备

1. 依赖安装

pip install numpy pandas matplotlib seaborn mlxtend

2. 所需库说明

import numpy as np          # 数值计算
import pandas as pd         # 数据处理
import matplotlib.pyplot as plt  # 绘图
import seaborn as sns      # 统计可视化
from mlxtend.frequent_patterns import apriori  # Apriori算法实现
from mlxtend.preprocessing import TransactionEncoder  # 数据预处理

3. 数据格式要求

  • 输入数据需要是交易记录的列表
  • 每条交易记录是一个项目列表
  • 项目可以是任意可哈希的对象(如字符串、数字等)

算法实现

1. 数据准备

# 生成示例交易数据
transactions = [
    ['面包', '牛奶', '饼干'],
    ['面包', '可乐', '饼干', '薯片'],
    ['牛奶', '饼干', '可乐', '巧克力'],
    ['面包', '牛奶', '饼干', '薯片'],
    ['面包', '牛奶', '可乐', '巧克力'],
    ['面包', '饼干', '可乐'],
    ['牛奶', '饼干', '可乐', '薯片'],
    ['面包', '牛奶', '饼干', '可乐'],
    ['面包', '饼干', '薯片'],
    ['面包', '牛奶', '饼干', '可乐'],
]

# 数据预处理
te = TransactionEncoder()
te_ary = te.fit(transactions).transform(transactions)
df = pd.DataFrame(te_ary, columns=te.columns_)

2. 频繁项集挖掘

# 使用Apriori算法找出频繁项集
frequent_itemsets = apriori(df, min_support=0.3, use_colnames=True)

3. 关联规则生成

def generate_rules(frequent_itemsets, min_confidence=0.5, min_lift=1.0):
    rules = []
    for _, row in frequent_itemsets.iterrows():
        items = list(row['itemsets'])
        if len(items) > 1:
            # 生成所有可能的前件和后件组合
            for i in range(1, len(items)):
                from itertools import combinations
                for antecedent_items in combinations(items, i):
                    antecedent = frozenset(antecedent_items)
                    consequent = frozenset(items) - antecedent
                    
                    # 计算支持度、置信度和提升度
                    rule_support = row['support']
                    ant_support = frequent_itemsets[frequent_itemsets['itemsets'] == antecedent]['support'].iloc[0]
                    con_support = frequent_itemsets[frequent_itemsets['itemsets'] == consequent]['support'].iloc[0]
                    
                    confidence = rule_support / ant_support
                    lift = confidence / con_support
                    
                    if confidence >= min_confidence and lift >= min_lift:
                        rules.append({
                            'antecedents': antecedent,
                            'consequents': consequent,
                            'support': rule_support,
                            'confidence': confidence,
                            'lift': lift
                        })
    
    return pd.DataFrame(rules)

4. 可视化分析

# 频繁项集支持度分布图
plt.figure(figsize=(12, 6))
plt.bar(range(len(frequent_itemsets)), frequent_itemsets['support'], alpha=0.8)
plt.title('频繁项集支持度分布', fontsize=14, pad=20)
plt.xlabel('频繁项集索引', fontsize=12)
plt.ylabel('支持度', fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('images/support_distribution.png', dpi=300, bbox_inches='tight')
plt.close()

# 关联规则散点图
plt.figure(figsize=(12, 6))
scatter = plt.scatter(rules['support'], rules['confidence'], 
                     c=rules['lift'], cmap='viridis', 
                     s=100, alpha=0.6)
plt.colorbar(scatter, label='提升度')
plt.title('关联规则支持度-置信度-提升度分布', fontsize=14, pad=20)
plt.xlabel('支持度', fontsize=12)
plt.ylabel('置信度', fontsize=12)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('images/support_confidence_scatter.png', dpi=300, bbox_inches='tight')
plt.close()

结果分析

1. 频繁项集分析

[外链图片转存中…(img-D5PxYj4a-1737339258606)]
从支持度分布图中可以看出:

  • 不同频繁项集的支持度分布情况
  • 支持度较高的项集数量
  • 项集大小与支持度的关系

具体分析:

  1. 单项集(1项集)

    • 饼干的支持度最高(0.9),说明是最常购买的商品
    • 面包(0.8)和牛奶、可乐(0.7)次之
    • 薯片支持度较低(0.4)
  2. 双项集(2项集)

    • {面包,饼干}支持度最高(0.7)
    • {可乐,饼干}和{牛奶,饼干}次之(0.6)
    • 其他组合支持度在0.3-0.5之间
  3. 三项集(3项集)

    • 支持度普遍低于双项集
    • 最高的是{可乐,牛奶,饼干}和{可乐,面包,饼干}(0.4)

2. 关联规则分析

images/support_confidence_scatter.png)在这里插入图片描述
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?
散点图展示了:

  • 规则的支持度和置信度分布
  • 强关联规则的分布特征
  • 规则质量的整体评估

主要发现:

  1. 强关联规则

    • 薯片→饼干 (置信度=1.0, 提升度=1.111)
    • 薯片,面包→饼干 (置信度=1.0, 提升度=1.111)
  2. 中等强度关联

    • 可乐↔牛奶 (置信度=0.714, 提升度=1.020)
    • 薯片→面包,饼干 (置信度=0.750, 提升度=1.071)

3. 商品关联强度分析

images/correlation_heatmap.png)在这里插入图片描述
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

热力图反映了:

  • 商品之间的关联强度
  • 最强关联的商品对
  • 关联模式的整体分布

关键发现:

  1. 强关联商品对
    2 - 薯片→饼干

    • 薯片→面包
  2. 中等关联

    • 可乐↔牛奶
    • 面包↔饼干
  3. 弱关联

    • 巧克力与其他商品

应用场景

1. 零售业

  • 商品布局优化

    • 将强关联商品放在相近位置
    • 根据关联规则设计动线
    • 优化货架空间利用
  • 促销策略制定

    • 捆绑销售方案设计
    • 交叉销售推荐
    • 折扣商品组合设计
  • 库存管理优化

    • 关联商品库存水平协调
    • 补货策略优化
    • 季节性需求预测
  • 个性化推荐

    • 购物篮分析
    • 实时推荐系统
    • 会员营销方案

2. 电子商务

  • 商品推荐系统

    • 实时个性化推荐
    • 相关商品展示
    • 购物车推荐
  • 网页布局优化

    • 商品展示顺序
    • 导航菜单设计
    • 搜索结果排序
  • 营销策略制定

    • 邮件营销内容
    • 优惠券设计
    • 活动商品组合
  • 用户行为分析

    • 购物路径分析
    • 用户兴趣挖掘
    • 流失预警

3. 医疗健康

  • 疾病共现分析

    • 疾病关联模式
    • 并发症预测
    • 健康风险评估
  • 药物相互作用研究

    • 药物配伍禁忌
    • 联合用药分析
    • 不良反应预警
  • 治疗方案优化

    • 个性化治疗方案
    • 临床路径设计
    • 治疗效果评估
  • 健康风险评估

    • 风险因素分析
    • 预防保健建议
    • 早期干预方案

4. 金融领域

  • 欺诈检测

    • 异常交易模式
    • 欺诈行为识别
    • 风险预警系统
  • 风险评估

    • 信用风险分析
    • 投资风险评估
    • 市场风险预测
  • 投资组合分析

    • 资产配置优化
    • 投资策略设计
    • 市场机会识别
  • 客户行为分析

    • 客户分群
    • 产品推荐
    • 营销策略优化

性能优化

1. 算法优化

  • 减少数据库扫描次数
  • 优化候选项集生成
  • 使用更高效的数据结构
  • 并行化处理

2. 参数调优

  • 合理设置最小支持度
  • 调整最小置信度阈值
  • 控制最大项集大小
  • 优化内存使用

3. 实现技巧

  • 使用位图表示法
  • 采用散列技术
  • 数据预处理优化
  • 增量式更新

4. 硬件优化

  • 使用分布式计算
  • GPU加速
  • 内存优化
  • IO优化

全部代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mlxtend.frequent_patterns import apriori
from mlxtend.preprocessing import TransactionEncoder
import seaborn as sns
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 生成示例交易数据
transactions = [
    ['面包', '牛奶', '饼干'],
    ['面包', '可乐', '饼干', '薯片'],
     ['牛奶', '饼干', '可乐', '巧克力'],
    ['面包', '牛奶', '饼干', '薯片'],
    ['面包', '牛奶', '可乐', '巧克力'],
    ['面包', '饼干', '可乐'],
    ['牛奶', '饼干', '可乐', '薯片'],
    ['面包', '牛奶', '饼干', '可乐'],
    ['面包', '饼干', '薯片'],
    ['面包', '牛奶', '饼干', '可乐'],
]

# 数据预处理
te = TransactionEncoder()
te_ary = te.fit(transactions).transform(transactions)
df = pd.DataFrame(te_ary, columns=te.columns_)

# 使用Apriori算法找出频繁项集
frequent_itemsets = apriori(df, min_support=0.3, use_colnames=True)

# 生成关联规则
def generate_rules(frequent_itemsets, min_confidence=0.5, min_lift=1.0):
    rules = []
    for _, row in frequent_itemsets.iterrows():
        items = list(row['itemsets'])
        if len(items) > 1:
            # 生成所有可能的前件和后件组合
            for i in range(1, len(items)):
                from itertools import combinations
                for antecedent_items in combinations(items, i):
                    antecedent = frozenset(antecedent_items)
                    consequent = frozenset(items) - antecedent
                    
                    # 计算支持度、置信度和提升度
                    rule_support = row['support']
                    ant_support = frequent_itemsets[frequent_itemsets['itemsets'] == antecedent]['support'].iloc[0]
                    con_support = frequent_itemsets[frequent_itemsets['itemsets'] == consequent]['support'].iloc[0]
                    
                    confidence = rule_support / ant_support
                    lift = confidence / con_support
                    
                    if confidence >= min_confidence and lift >= min_lift:
                        rules.append({
                            'antecedents': antecedent,
                            'consequents': consequent,
                            'support': rule_support,
                            'confidence': confidence,
                            'lift': lift
                        })
    
    return pd.DataFrame(rules)

# 生成关联规则
rules = generate_rules(frequent_itemsets, min_confidence=0.6, min_lift=1.0)

# 可视化1:频繁项集支持度分布
plt.figure(figsize=(12, 6))
plt.bar(range(len(frequent_itemsets)), frequent_itemsets['support'], alpha=0.8)
plt.title('频繁项集支持度分布', fontsize=14, pad=20)
plt.xlabel('频繁项集索引', fontsize=12)
plt.ylabel('支持度', fontsize=12)
plt.grid(True, alpha=0.3)
 plt.tight_layout()
plt.savefig('32_apriori_algorithm/images/support_distribution.png', dpi=300, bbox_inches='tight')
plt.close()

if len(rules) > 0:
    # 可视化2:关联规则散点图
    plt.figure(figsize=(12, 6))
    scatter = plt.scatter(rules['support'], rules['confidence'], 
                         c=rules['lift'], cmap='viridis', 
                         s=100, alpha=0.6)
    plt.colorbar(scatter, label='提升度')
    plt.title('关联规则支持度-置信度-提升度分布', fontsize=14, pad=20)
    plt.xlabel('支持度', fontsize=12)
    plt.ylabel('置信度', fontsize=12)
    plt.grid(True, alpha=0.3)
    plt.tight_layout()
    plt.savefig('32_apriori_algorithm/images/support_confidence_scatter.png', dpi=300, bbox_inches='tight')
    plt.close()

    # 可视化3:热力图展示项目间的关联强度
    correlation_matrix = pd.DataFrame(0, index=te.columns_, columns=te.columns_)
    for _, rule in rules.iterrows():
        for ant in rule['antecedents']:
            for con in rule['consequents']:
                correlation_matrix.loc[ant, con] = rule['lift']

    plt.figure(figsize=(12, 10))
    sns.heatmap(correlation_matrix, annot=True, cmap='YlOrRd', fmt='.2f')
    plt.title('商品关联强度热力图', fontsize=14, pad=20)
    plt.tight_layout()
    plt.savefig('32_apriori_algorithm/images/correlation_heatmap.png', dpi=300, bbox_inches='tight')
    plt.close()

# 打印结果
print("\n频繁项集:")
print(frequent_itemsets)
print("\n关联规则:")
if len(rules) > 0:
    # 格式化输出规则
    for idx, rule in rules.iterrows():
        ant = ', '.join(sorted(rule['antecedents']))
        con = ', '.join(sorted(rule['consequents']))
        print(f"规则 {idx+1}: {ant} -> {con}")
         print(f"支持度: {rule['support']:.3f}")
        print(f"置信度: {rule['confidence']:.3f}")
        print(f"提升度: {rule['lift']:.3f}")
        print("-" * 50)
else:
    print("未找到满足条件的关联规则") 

总结

Apriori算法是一种强大的关联规则挖掘工具,通过分析大量交易数据,可以发现隐藏在数据中的有价值的关联关系。本教程通过简单的商品交易数据示例,展示了算法的实现过程和结果分析方法。在实际应用中,可以根据具体场景调整参数,以获得更有价值的挖掘结果。

关键要点

  1. 合理设置最小支持度和置信度阈值
  2. 注意数据预处理的质量
  3. 结合业务场景解释挖掘结果
  4. 考虑算法的效率和可扩展性
  5. 注意数据质量和规模
  6. 重视结果的实际应用价值

进阶建议

  1. 尝试其他关联规则挖掘算法(如FP-Growth)
  2. 结合其他数据挖掘技术
  3. 优化算法性能
  4. 开发可视化分析工具
  5. 探索增量式更新方法
  6. 研究并行化实现

实践建议

  1. 从小数据集开始测试
  2. 逐步调整参数以获得最佳结果
  3. 重视结果的业务解释
  4. 持续监控和优化系统性能
  5. 注意数据隐私和安全
  6. 保持与业务需求的紧密结合

同学们如果有疑问可以私信答疑,如果有讲的不好的地方或可以改善的地方可以一起交流,谢谢大家。
*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值