别再只懂Apriori了!手把手教你用Python基础库实现亲和性分析(附完整代码与数据集)
从零实现商品亲和性分析:深入理解支持度与置信度的计算本质
在电商推荐系统中,我们经常看到"买了这个商品的人还买了..."的提示。这背后是经典的亲和性分析技术,而大多数人只停留在调用现成库的阶段。本文将带您用Python基础库一步步实现核心算法,彻底掌握关联规则挖掘的精髓。
1. 亲和性分析基础与数据准备
关联规则挖掘的核心目标是发现数据中项集之间的有趣关系。与直接调用mlxtend等库不同,我们这次选择用NumPy和defaultdict从头构建算法,这能帮助您真正理解Apriori算法背后的计算逻辑。
首先准备一个模拟的购物篮数据集,保存为market_data.txt:
1,1,0,0,0 1,0,1,0,0 0,1,1,0,0 1,1,1,0,1 0,0,1,1,1 1,0,1,1,0每行代表一个交易记录,各列分别表示牛奶、面包、苹果、香蕉和火腿的购买情况(1为购买,0为未购买)。我们用NumPy加载这些数据:
import numpy as np def load_data(file_path): """加载并返回交易数据矩阵""" data = np.loadtxt(file_path, delimiter=",") print(f"成功加载{len(data)}条交易记录") return data2. 核心指标:支持度与置信度的数学本质
2.1 支持度的计算原理
支持度衡量的是规则在所有交易中出现的频率。数学表达式为:
$$ \text{支持度}(X \Rightarrow Y) = \frac{\sigma(X \cup Y)}{N} $$
其中$\sigma$表示计数,$N$是总交易数。例如牛奶和面包一起购买的支持度计算如下:
def calculate_support(data, item_a, item_b): """计算两个商品同时出现的支持度""" co_occurrence = np.sum((data[:, item_a] == 1) & (data[:, item_b] == 1)) return co_occurrence / len(data)2.2 置信度的深层含义
置信度表示在X出现的情况下Y也出现的条件概率:
$$ \text{置信度}(X \Rightarrow Y) = \frac{\sigma(X \cup Y)}{\sigma(X)} $$
实现代码反映了这个定义:
def calculate_confidence(data, premise, conclusion): """计算前提商品到结论商品的置信度""" premise_count = np.sum(data[:, premise] == 1) if premise_count == 0: return 0.0 co_occurrence = np.sum((data[:, premise] == 1) & (data[:, conclusion] == 1)) return co_occurrence / premise_count3. 高效实现:使用defaultdict构建规则空间
为了系统性地计算所有可能的规则,我们采用defaultdict来存储中间结果:
from collections import defaultdict def generate_rules(data, feature_names): """生成所有可能的关联规则并计算支持度和置信度""" num_features = len(feature_names) valid_rules = defaultdict(int) # 规则应验次数 num_occurrences = defaultdict(int) # 前提出现次数 for sample in data: for premise in range(num_features): if sample[premise] == 0: continue num_occurrences[premise] += 1 for conclusion in range(num_features): if premise == conclusion: continue if sample[conclusion] == 1: valid_rules[(premise, conclusion)] += 1 support = {rule: count/len(data) for rule, count in valid_rules.items()} confidence = { rule: valid_rules[rule]/num_occurrences[rule[0]] for rule in valid_rules } return support, confidence4. 规则评估与结果排序策略
得到所有规则的支持度和置信度后,我们需要找出最有价值的规则。常见的排序方式有三种:
- 按支持度降序:找出最频繁的共现模式
- 按置信度降序:找出最强的关联规则
- 按提升度排序:衡量规则的实际价值
实现排序功能的代码示例:
from operator import itemgetter def get_top_rules(support, confidence, feature_names, n=5, sort_by='support'): """获取前N条最佳规则""" if sort_by == 'support': sorted_rules = sorted(support.items(), key=itemgetter(1), reverse=True) else: sorted_rules = sorted(confidence.items(), key=itemgetter(1), reverse=True) top_rules = [] for i in range(min(n, len(sorted_rules))): (premise, conclusion), metric = sorted_rules[i] premise_name = feature_names[premise] conclusion_name = feature_names[conclusion] top_rules.append({ 'rule': f"If {premise_name} then {conclusion_name}", 'support': support.get((premise, conclusion), 0), 'confidence': confidence.get((premise, conclusion), 0) }) return top_rules5. 完整实现与商业应用实例
将上述组件整合成完整的解决方案:
def affinity_analysis(file_path, feature_names): """完整的亲和性分析流程""" data = load_data(file_path) support, confidence = generate_rules(data, feature_names) print("\n=== 支持度最高的5条规则 ===") top_support = get_top_rules(support, confidence, feature_names, sort_by='support') for i, rule in enumerate(top_support, 1): print(f"{i}. {rule['rule']}") print(f" 支持度: {rule['support']:.3f}, 置信度: {rule['confidence']:.3f}") print("\n=== 置信度最高的5条规则 ===") top_confidence = get_top_rules(support, confidence, feature_names, sort_by='confidence') for i, rule in enumerate(top_confidence, 1): print(f"{i}. {rule['rule']}") print(f" 支持度: {rule['support']:.3f}, 置信度: {rule['confidence']:.3f}") # 实际使用示例 features = ["牛奶", "面包", "苹果", "香蕉", "火腿"] affinity_analysis("market_data.txt", features)在实际电商场景中,这些规则可以用于:
- 商品捆绑销售策略
- 购物车推荐优化
- 货架摆放规划
- 促销活动设计
6. 性能优化与工程实践
当处理大规模数据时,基础实现可能遇到性能瓶颈。以下是几个关键优化点:
内存优化技巧:
- 使用稀疏矩阵存储大型交易数据
- 分批处理数据而非一次性加载
- 对商品ID进行哈希编码减少内存占用
计算加速策略:
# 使用NumPy向量化计算替代循环 def vectorized_support(data, item_pairs): """向量化计算多个商品对的支持度""" item_a, item_b = zip(*item_pairs) co_occurrence = np.sum((data[:, list(item_a)] == 1) & (data[:, list(item_b)] == 1), axis=0) return co_occurrence / len(data)并行计算实现:
from multiprocessing import Pool def parallel_rule_generation(data_chunk): """并行处理数据分片""" # 实现类似generate_rules的逻辑 pass # 在主程序中分配任务 with Pool(processes=4) as pool: results = pool.map(parallel_rule_generation, data_chunks)7. 进阶思考:超越基础指标
除了支持度和置信度,实际业务中还会考虑:
提升度(Lift): $$ \text{提升度} = \frac{\text{置信度}(X \Rightarrow Y)}{\text{支持度}(Y)} $$
确信度(Conviction): $$ \text{确信度} = \frac{1 - \text{支持度}(Y)}{1 - \text{置信度}(X \Rightarrow Y)} $$
实现这些扩展指标的代码:
def calculate_lift(support, confidence, item_b, total_items): """计算规则的提升度""" consequent_support = support.get(item_b, 0) / total_items if consequent_support == 0: return float('inf') return confidence / consequent_support def calculate_conviction(support, confidence, item_b, total_items): """计算规则的确信度""" consequent_support = support.get(item_b, 0) / total_items if confidence == 1: return float('inf') return (1 - consequent_support) / (1 - confidence)在零售项目中,我们发现当提升度>3时,规则通常具有实际商业价值。例如,某超市通过分析发现"啤酒和尿布"的组合在周末晚上特别受欢迎,于是调整了货架位置,使这个品类的销售额提升了18%。
