用FP - Growth 算法怎么实现对于两个蔬菜品类销量的相互关系的判断
时间: 2025-08-16 13:57:52 浏览: 3
<think>我们使用FP-Growth算法分析两个蔬菜品类销量之间的关联关系,实际上是要挖掘频繁项集,进而发现哪些品类经常同时出现在同一个销售记录中(即同时被购买)。但是,注意题目中要求的是“两个蔬菜品类销量之间的关联关系”,我们可以通过挖掘频繁2项集来直接得到两个品类之间的关联,然后进一步可以计算关联规则(如支持度、置信度、提升度等)来量化它们的关系。
步骤:
1. 数据准备:将销售数据转化为事务数据集。每个事务代表一次销售记录(或一个订单),包含该次销售中售出的蔬菜品类(注意:这里我们关注的是品类,而不是具体单品)。例如,如果一次销售中包含了“茄类”和“辣椒类”,那么这次销售就是一个事务,包含这两个品类。
2. 运行FP-Growth算法:挖掘频繁项集,特别关注频繁2项集(即两个品类同时出现的频繁程度)。
3. 从频繁项集中生成关联规则:对于每个频繁2项集{品类A, 品类B},我们可以计算:
- 支持度 = 同时包含A和B的事务数 / 总事务数
- 置信度(A->B) = 同时包含A和B的事务数 / 包含A的事务数
- 提升度(A->B) = 置信度(A->B) / (包含B的事务数/总事务数) [提升度>1表示正相关]
注意:由于我们只关心两个品类之间的关联,因此我们主要关注频繁2项集。
但是,在引用[2]中提到,茄类和辣椒类的需求价格弹性相关系数特征与其他品类不同,因此我们可能特别关注这两个品类与其他品类的关系。
具体实现步骤:
1. 数据转换:
假设我们有一组销售记录,每条记录是一个订单,订单中包含多个蔬菜品类(注意:同一个订单中同一个品类只出现一次,即使有多个单品,我们只关心品类是否出现)。
例如:
订单1: [花叶类, 茄类]
订单2: [茄类, 辣椒类]
订单3: [花叶类, 茄类, 辣椒类]
2. 使用FP-Growth算法挖掘频繁项集(设置最小支持度阈值)。
例如,我们可能得到频繁2项集:{茄类, 辣椒类},支持度为2(出现2次),总事务数为3,则支持度为2/3。
3. 生成关联规则并计算置信度和提升度。
对于{茄类, 辣椒类}:
- 置信度(茄类->辣椒类) = 支持度(茄类,辣椒类) / 支持度(茄类) = (2/3) / (3/3) = 2/3
- 提升度 = (置信度) / (辣椒类的支持度) = (2/3) / (2/3) = 1 [这里辣椒类出现2次,支持度2/3]
4. 分析:提升度等于1,说明两者独立;大于1则正相关;小于1则负相关。
但是,注意:我们这里的数据是事务数据,每个事务代表一个订单,每个订单中的品类是同时购买的。因此,我们可以通过关联规则分析不同品类同时被购买的关联程度。
代码实现:
我们将使用上面已经实现的FP-Growth算法代码,然后进行以下步骤:
a. 准备事务数据集(注意:上面的代码示例中,数据集是字典形式,键是事务(frozenset),值是出现次数。但在实际中,我们可能每条事务独立出现一次,那么每个事务的计数为1。或者,如果有重复的事务,可以合并计数。
b. 设置最小支持度(根据数据量来定,比如最小支持度为0.1,表示出现频率至少为10%的项集)
c. 运行FP-Growth算法得到频繁项集。
d. 从频繁项集中提取所有频繁2项集,并计算关联规则指标。
由于我们之前实现的FP-Growth算法只返回频繁项集(没有返回支持度计数),所以我们需要修改一下,或者后续再计算支持度计数。不过,我们可以通过原始数据集计算每个项集的支持度。
另一种做法:在挖掘频繁项集时,算法内部已经计算了支持度(通过计数),我们可以将每个频繁项集的支持度记录下来。
修改`mine_tree`函数,使其返回频繁项集及其支持度计数(或支持度)。但是,为了简单起见,我们可以在得到频繁项集后,再遍历原始数据集计算每个项集的支持度。
但是,为了效率,我们可以在FP-Growth算法中直接记录支持度计数。修改如下:
在`mine_tree`函数中,我们不仅记录项集,还记录其支持度计数。但是,在递归构建条件树时,条件模式基的计数就是该条件树中项集的支持度计数。所以,在构建条件模式基时,我们已经有了该条件树中项集(即当前项+前缀)的计数。
然而,我们之前的实现中,`freq_items`只存储项集,没有存储支持度。我们可以修改为存储元组(项集,支持度计数)。
但是,为了快速实现,我们这里不修改算法,而是使用另一种方法:在得到频繁项集后,用原始数据集计算每个项集的支持度计数(注意:由于原始数据集是压缩的,即每个事务有计数,所以需要遍历事务并检查项集是否是其子集,然后乘以事务计数)。
但是,这样计算量较大。因此,我们修改挖掘过程,在`mine_tree`函数中记录每个频繁项集的支持度计数。
修改方案:
在`mine_tree`函数中,当我们添加一个频繁项集时,这个项集(即当前前缀+base)的支持度计数就是当前条件模式基中所有事务计数之和?实际上,这个计数就是当前base在条件模式基中的计数(即条件模式基中所有事务计数之和,因为条件模式基就是包含base的所有事务的前缀路径,并且每个事务的计数就是base在原始数据中出现的次数?)——实际上,在条件模式基中,每个事务(即前缀路径)的计数就是该事务在原始数据中出现的次数(即base在该事务中出现的次数)。所以,当前base在条件模式基中的计数之和就是base在原始数据中的总计数。但是,我们想要的是整个项集(前缀+base)的计数,这个计数等于条件模式基中每个事务的计数?不对。
实际上,条件模式基是包含base的所有事务的前缀路径(不包含base),所以当我们构建条件FP树时,条件FP树中每个事务的计数就是该事务与base同时出现的次数。因此,条件FP树中所有事务的计数之和就是base在原始数据中的总计数。但是,我们构建的条件FP树是用于挖掘更长的频繁项集,而当前项集(base+前缀)的支持度计数应该是base的条件模式基中每个事务的计数?实际上,这个计数就是base在原始数据中出现的次数(因为每个事务都包含base)。但是,我们想要的是整个项集(即base和前缀中的项同时出现)的次数,这个次数等于条件模式基中每个事务的计数(因为条件模式基中的每个事务都包含base,而事务本身是前缀路径,所以整个项集就是前缀路径+base,而前缀路径+base的出现次数就是该事务的计数)。
然而,在条件模式基中,每个事务(前缀路径)的计数就是原始数据中该事务与base同时出现的次数。所以,整个项集(前缀路径+base)的支持度计数就是该事务的计数。但是,在条件模式基中,每个事务对应一个计数,而整个项集(前缀路径+base)实际上对应多个事务(不同的前缀路径)。所以,当前项集(base+前缀)的支持度计数应该是条件模式基中所有事务计数的和?不对,因为每个事务代表不同的前缀路径,而整个项集(base+某个特定前缀路径)的支持度计数就是该事务的计数。但是,我们当前挖掘的项集是base+条件模式基中某个事务的所有项?实际上,在递归过程中,我们构建的条件模式基是针对base的,然后我们在这个条件模式基上挖掘频繁项集,这些频繁项集都是base的前缀(即与base同时出现的项集),所以最后得到的频繁项集是base与这些项的组合。因此,整个项集(base+前缀)的支持度计数等于在条件FP树中该前缀的计数?但是,我们在条件FP树中构建时,每个节点的计数是条件模式基中相同路径的计数之和。
这个逻辑比较复杂,因此我们采用一个简单的方法:在原始数据集中计算每个频繁项集的支持度计数。由于频繁项集不会太多,我们可以接受。
步骤:
1. 使用FP-Growth算法得到频繁项集列表(只有项集,没有计数)。
2. 编写一个函数计算每个项集在原始数据集中的支持度计数。
注意:原始数据集是字典,键是事务(frozenset),值是事务出现的次数(计数)。
计算一个项集的支持度计数:
遍历原始数据集的每个事务(frozenset)及其计数count
如果项集是事务的子集,则该项集的支持度计数加上count
然后,我们只保留频繁项集(因为已经通过FP-Growth得到,所以都是满足最小支持度的)。
接下来,我们只关注频繁2项集,并计算关联规则。
代码步骤:
1. 准备数据集(按照蔬菜品类整理事务)
2. 运行FP-Growth得到频繁项集(无计数)
3. 计算每个频繁项集的支持度计数
4. 过滤出频繁2项集
5. 对于每个频繁2项集{A, B},计算:
support_AB = 项集{A,B}的支持度计数
support_A = 项集{A}的支持度计数
support_B = 项集{B}的支持度计数
total_transactions = 总事务数(即原始数据集所有事务计数之和)
support = support_AB / total_transactions
confidence_A_B = support_AB / support_A # A->B
confidence_B_A = support_AB / support_B # B->A
lift_A_B = confidence_A_B / (support_B / total_transactions)
lift_B_A = confidence_B_A / (support_A / total_transactions)
6. 输出结果,并分析。
注意:由于我们只关心两个品类之间的关联,所以只考虑2项集。
示例代码:
假设我们已经从FP-Growth算法得到了频繁项集列表`freq_items`(每个元素是一个集合),然后我们计算支持度计数。
由于原始数据集`dataset`是字典,其中键是事务(frozenset),值是该事务出现的次数。
总事务数:`total = sum(dataset.values())`
计算每个项集的支持度计数:
item_support = {}
for itemset in freq_items:
count = 0
for trans, cnt in dataset.items():
if itemset.issubset(trans): # 注意:itemset是集合,trans是frozenset
count += cnt
item_support[frozenset(itemset)] = count # 用frozenset作为键,因为集合不可哈希
然后,我们找出所有大小为2的项集:
freq_2_itemsets = [itemset for itemset in freq_items if len(itemset)==2]
然后对每个2项集计算关联规则指标。
下面我们结合具体代码实现:
注意:由于我们之前实现的FP-Growth算法中,`mine_tree`函数将频繁项集存储在`freq_items`列表中(该列表是传入的,并在递归中追加)。我们直接使用这个列表。
完整代码示例:
步骤:
1. 定义数据集(根据蔬菜品类整理)
2. 设置最小支持度(例如,最小支持度计数为2,或者最小支持度比例,这里我们使用比例,需要先计算总事务数)
3. 调用FP-Growth算法
4. 计算每个频繁项集的支持度计数
5. 分析频繁2项集
注意:由于原始数据集中事务是品类集合,同一个事务中同一个品类只出现一次(因为一个订单中同一个品类可能有多个单品,但我们只关心品类是否出现,所以每个品类在事务中只出现一次)。
假设我们有以下数据集(根据引用[2]中提到的品类:花叶类、花菜类、水生根茎类、食用菌类、茄类、辣椒类)构造示例:
示例数据集(每个事务是一个订单购买的蔬菜品类):
dataset = {
frozenset(['花叶类', '茄类']): 1,
frozenset(['茄类', '辣椒类']): 1,
frozenset(['花叶类', '茄类', '辣椒类']): 1,
frozenset(['花叶类', '水生根茎类']): 1,
frozenset(['花菜类', '食用菌类']): 1,
frozenset(['辣椒类', '食用菌类']): 1,
frozenset(['茄类', '辣椒类', '食用菌类']): 1
}
总事务数:7(每个事务计数为1,所以总事务数为7)
最小支持度设为2(即出现2次)?或者设为0.2(即20%),那么最小支持度计数=0.2*7=1.4,所以最小支持度计数为2(向上取整)?注意:在FP-Growth中,我们传递的是最小支持度计数(整数),所以这里我们传递min_sup=2。
然后运行算法。
注意:由于我们的数据集较小,可能有些2项集不会出现2次,比如{花叶类,水生根茎类}只出现1次。
我们运行代码,然后分析频繁2项集。
下面我们写一个完整的示例代码(包括计算关联规则指标):</think>### 如何使用FP-Growth算法分析蔬菜品类销量关联关系
#### 1. 问题分析与数据准备
根据引用[1]的分析目标,我们需要将蔬菜销售数据转换为适合FP-Growth算法的事务数据集:
- **事务**:每个订单/交易记录
- **项集**:订单中包含的蔬菜品类(如花叶类、茄类等)
- **数据转换示例**:
```python
# 原始销售数据(简化示例)
sales_data = [
{'order_id': 1, 'items': ['花叶类', '茄类']},
{'order_id': 2, 'items': ['茄类', '辣椒类']},
{'order_id': 3, 'items': ['花叶类', '茄类', '辣椒类']},
# ...更多数据
]
# 转换为FP-Growth所需格式
dataset = {
frozenset(['花叶类', '茄类']): 1,
frozenset(['茄类', '辣椒类']): 1,
frozenset(['花叶类', '茄类', '辣椒类']): 1,
# ...更多事务
}
```
#### 2. 核心分析步骤
1. **执行FP-Growth算法**:
```python
# 设置最小支持度阈值(根据业务需求调整)
min_support = 0.1 # 出现频率>10%的组合
# 运行算法
fp_tree, header_table = create_tree(dataset, min_support)
freq_items = []
mine_tree(header_table, min_support, set(), freq_items)
```
2. **提取品类关联规则**:
```python
def generate_association_rules(freq_items, dataset, min_confidence=0.5):
rules = []
total_trans = sum(dataset.values())
for itemset in freq_items:
if len(itemset) < 2: continue
# 计算支持度
supp_count = sum(cnt for trans, cnt in dataset.items() if itemset.issubset(trans))
support = supp_count / total_trans
# 生成关联规则
for item in itemset:
antecedent = itemset - {item}
ante_count = sum(cnt for trans, cnt in dataset.items() if antecedent.issubset(trans))
if ante_count > 0:
confidence = supp_count / ante_count
if confidence >= min_confidence:
rules.append({
'antecedent': antecedent,
'consequent': item,
'support': support,
'confidence': confidence
})
return rules
# 生成关联规则(置信度>50%)
association_rules = generate_association_rules(freq_items, dataset, 0.5)
```
3. **结合价格弹性分析**(引用[2]):
```python
# 价格弹性系数(示例数据)
price_elasticity = {
'花叶类': -1.2,
'茄类': -0.8,
'辣椒类': -0.6,
# ...其他品类
}
# 增强关联规则分析
for rule in association_rules:
# 计算组合价格弹性
combo_elasticity = sum(price_elasticity[item] for item in rule['antecedent'])
+ price_elasticity[rule['consequent']]
# 添加业务洞察
if combo_elasticity > -1.0:
rule['insight'] = "价格不敏感组合:可考虑溢价策略"
else:
rule['insight'] = "价格敏感组合:需保持竞争力定价"
```
#### 3. 结果解读与应用
1. **典型分析结果示例**:
```
关联规则:{茄类} → {辣椒类}
- 支持度:23.5% (同时购买比例)
- 置信度:67.3% (购买茄类后购买辣椒类的概率)
- 价格弹性:-1.4 → 价格敏感组合
```
2. **业务应用方向**:
- **补货优化**:关联性强的品类(如茄类与辣椒类)应邻近摆放或捆绑补货[^1]
- **定价策略**:价格弹性低的组合(如茄类+辣椒类)可考虑小幅提价[^2]
- **促销设计**:对高置信度组合(如花叶类→茄类)设计交叉促销
- **空间优化**:根据支持度数据分配货架空间,高频组合优先展示
#### 4. 关键业务洞察
1. **品类关联与价格弹性关系**:
- 如引用[2]所述,茄类与辣椒类呈现弱价格弹性特征
- FP-Growth可验证:$$ \text{Support}(\text{茄类} \cup \text{辣椒类}) > \text{阈值} $$
- 业务意义:此类组合可承受更高价格波动
2. **需求预测优化**:
```python
# 基于关联规则的销量预测
def predict_demand(base_item, rules, historical_sales):
related_items = [r['consequent'] for r in rules if base_item in r['antecedent']]
# 加权预测模型(考虑置信度)
return sum(historical_sales[item] * r['confidence']
for r in rules for item in related_items)
```
#### 5. 实施建议
1. **数据预处理要点**:
- 按时间段(周/月)分割事务数据
- 排除促销期异常数据
- 处理零销量品类(如季节性蔬菜)
2. **参数调优指南**:
| 参数 | 推荐值 | 业务意义 |
|------|--------|----------|
| min_support | 0.05-0.2 | 排除低频随机组合 |
| min_confidence | 0.4-0.7 | 确保规则可靠性 |
| 时间窗口 | 4-8周 | 捕捉消费周期 |
3. **结果验证方法**:
```python
# A/B测试验证规则有效性
def test_rule_impact(rule, test_group):
# 实施规则建议(如捆绑销售)
# 对比控制组销量变化
return sales_lift # 销量提升百分比
```
> 通过FP-Growth分析发现的品类关联规则,结合价格弹性特征,可显著优化蔬菜类商品的组合策略和定价模型。例如,对{茄类, 辣椒类}等高支持度、低价格弹性组合,可实施协同补货和适度溢价策略,提升整体销售效益[^1][^2]。
阅读全文
相关推荐

















