Apriori关联规则算法是一种经典的数据挖掘方法,用于发现数据集中项之间的关联规则。其主要作用在于发现数据中频繁出现的项集以及它们之间的关联关系,从而揭示数据中的隐藏模式和规律, 具体来说Apriori算法可以帮助:
- 发现频繁项集: Apriori算法能够识别数据集中频繁出现的项集,即经常一起出现的物品组合。这有助于商家了解哪些商品常常一起被购买,为交叉销售和推荐系统提供支持
- 生成关联规则: 通过识别频繁项集,Apriori算法可以生成关联规则,例如:“如果顾客购买了商品 A 和商品 B,则他们也可能会购买商品 C”。这些规则可以指导商家设计促销活动和优化产品布局
- 提供决策支持:
基于Apriori算法生成的关联规则,商家可以做出更加明智的决策,如调整产品定价、改进促销策略、优化库存管理等
1. Apriori算法原理
Apriori算法的数学推导涉及到频繁项集、支持度、置信度等概念,以及算法的核心步骤:生成候选项集和筛选频繁项集。下面将简要介绍Apriori算法的数学推导过程:
频繁项集: 在一个数据集中,如果一个项集的支持度大于或等于预先设定的最小支持度阈值,则称该项集为频繁项集。支持度可以用以下公式表示:
其中, 是一个项集, 表示包含项集 的交易数量,总交易数是指数据集中总的交易数量
关联规则: 关联规则是指在频繁项集的基础上,生成的条件格式为 的规则,其中 和 都是项集,关联规则的置信度表示在购买项集 的情况下,也购买 项集的概率,可以用以下公式表示:
Lift值: 用于衡量关联规则中的两个项集之间的相关性,它的计算公式为:
其中, 和 分别表示关联规则的前项和后项
Lift值的含义如下:
- 如果 Lift 值等于 1,表示前项和后项之间没有关联,购买一个项不影响购买另一个项
- 如果 Lift 值大于 1,表示前项和后项之间有正相关性,这意味着在观察到前项的情况下,购买后项的概率比在整个数据集中的平均水平要高
- 如果 Lift 值小于 1,表示前项和后项之间有负相关性,这意味着在观察到前项的情况下,购买后项的概率比在整个数据集中的平均水平要低
因此,Lift 值可用于衡量关联规则的有用性和意义
Apriori算法的核心思想是利用Apriori原理来减少搜索空间,即如果一个项集是频繁的,则它的所有子集也必须是频繁的。这意味着如果一个项集 不频繁,那么它的超集 也不会是频繁的
2. Apriori算法步骤
- 初始化: 生成频繁1项集(单个物品)
- 生成候选项集: 根据频繁 项集生成候选 项集
- 筛选频繁项集: 计算候选项集的支持度,保留支持度大于等于最小支持度的项集作为频繁项集
- 生成关联规则: 根据频繁项集生成关联规则,并计算置信度
- 输出结果: 输出频繁项集和关联规则
3. 代码实现
3.1 数据解读
import numpy as np
import pandas as pd
import numpy as np
data = pd.read_csv(open('GoodsOrder.csv'))
data
数据集包含两列:id和Goods,每一行表示一个交易,id是交易的标识符,Goods列则是交易中所购买的商品
3.2 数据转换
data['Goods'] = data['Goods'].apply(lambda x: ','+x)
data = data.groupby('id').sum().reset_index() # 根据id列对Goods列合并,并使用','将商品名称隔开
data['Goods'] = data['Goods'].apply(lambda x:[x[1:]])
data_list = list(data['Goods'])
data_translation = []
for i in data_list:
p = i[0].split(',')
data_translation.append(p)
data_translation # 分割商品名为每个元素
对原始数据进行预处理,以便将其转换为适合用于Apriori算法的数据格式,每一个列表为一个订单所购买的商品合集
3.3 Apriori算法实现
def createC1(dataSet):
# 构建初始候选项集列表
C1 = []
for transaction in dataSet:
for item in transaction:
if not [item] in C1:
C1.append([item])
# 对候选项集列表进行排序
C1.sort()
return list(map(frozenset, C1))
def scanD(D, Ck, minSupport):
# 创建一个空字典,用于存储每个候选项集的支持度计数
ssCnt = {}
# 遍历数据集中的每条交易记录
for tid in D:
# 遍历候选项集列表
for can in Ck:
# 如果候选项集是交易记录的子集,则增加它的计数
if can.issubset(tid):
if not can in ssCnt:
ssCnt[can] = 1
else:
ssCnt[can] += 1
numItems = float(len(D))
retList = []
supportData = {}
# 计算支持度并筛选满足最小支持度要求的候选项集
for key in ssCnt:
support = ssCnt[key]/numItems
if support >= minSupport:
retList.insert(0, key)
supportData[key] = support
return retList, supportData
def aprioriGen(Lk, k):
# 生成候选项集
retList = []
lenLk = len(Lk)
for i in range(lenLk):
for j in range(i+1, lenLk):
L1 = list(Lk[i])[:k-2]
L2 = list(Lk[j])[:k-2]
L1.sort()
L2.sort()
if L1 == L2:
retList.append(Lk[i] | Lk[j])
return retList
def apriori(dataSet, minSupport=0.02):
# Apriori算法主函数
C1 = createC1(dataSet)
D = list(map(set, dataSet))
L1, supportData = scanD(D, C1, minSupport)
L = [L1]
k = 2
while (len(L[k-2]) > 0):
Ck = aprioriGen(L[k-2], k)
Lk, supK = scanD(D, Ck, minSupport)
supportData.update(supK)
L.append(Lk)
k += 1
del L[-1]
return L, supportData
def getSubset(fromList, toList):
# 递归地寻找fromList的所有子集并添加到toList中
for i in range(len(fromList)):
t = [fromList[i]]
tt = frozenset(set(fromList)-set(t))
if not tt in toList:
toList.append(tt)
tt = list(tt)
if len(tt) > 1:
getSubset(tt, toList)
return toList
def calcConf(freqSet, H, supportData, ruleList, minConf=0.7):
# 计算关联规则的置信度
prunedH = []
for conseq in H:
conf = supportData[freqSet]/supportData[freqSet-conseq]
lift = supportData[freqSet]/(supportData[conseq]*supportData[freqSet-conseq])
if conf >= minConf and lift > 1:
print(freqSet - conseq, '-->', conseq, '支持度:', round(supportData[freqSet], 6), '置信度:', round(conf, 6), 'lift值:', round(lift, 6))
ruleList.append((freqSet-conseq, conseq, conf))
prunedH.append(conseq)
return prunedH
def rulesFromConseq(freqSet, H, supportData, ruleList, minConf=0.7):
m = len(H[0])
if len(freqSet) > (m + 1):
Hmp1 = aprioriGen(H, m+1)
Hmp1 = calcConf(freqSet, Hmp1, supportData, ruleList, minConf)
if len(Hmp1) > 1:
rulesFromConseq(freqSet, Hmp1, supportData, ruleList, minConf)
def generateRules(L, supportData, minConf=0.7):
# 生成关联规则
bigRuleList = []
for i in range(1, len(L)):
for freqSet in L[i]:
H1 = [frozenset([item]) for item in freqSet]
if i > 1:
rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)
else:
calcConf(freqSet, H1, supportData, bigRuleList, minConf)
return bigRuleList
if __name__ == '__main__':
dataSet = data_translation
# 使用Apriori算法得到频繁项集和支持度数据
L, supportData = apriori(dataSet, minSupport=0.02)
# 生成关联规则
rules = generateRules(L, supportData, minConf=0.35)
在这里, minSupport 和 minConf 两个参数,它们分别代表着最小支持度和最小置信度阈值
minSupport : 指在 Apriori 算法中用来确定频繁项集的阈值,支持度衡量的是某个项集在所有事务中出现的频率,最小支持度就是设定的一个阈值,只有当项集的支持度不低于这个阈值时,才会被认为是频繁项集。在代码中,minSupport=0.02 表示最小支持度为 0.02,即项集在所有事务中至少出现的频率为 2%
minConf : 用来确定关联规则的阈值,它代表着最小置信度,置信度是指关联规则的可靠程度,即在条件出现的情况下,结论出现的概率,最小置信度就是设定的一个阈值,只有当关联规则的置信度不低于这个阈值时,才会被认为是强关联规则。在代码中,minConf=0.35 表示最小置信度为 0.35,即关联规则的置信度至少为 35%
这两个参数的作用是控制算法的输出,通过调整它们可以获得不同阈值下的频繁项集和关联规则,以满足具体的分析需求
3.4 Apriori输出解读
以下面输出为列:frozenset({'仁果类水果'}) --> frozenset({'全脂牛奶'}) 支持度: 0.030097 置信度: 0.397849 lift值: 1.557043
在所有交易中,有约3.01%的交易同时购买了"仁果类水果"和"全脂牛奶",而在购买了"仁果类水果"的交易中,约有39.79%的顾客也购买了"全脂牛奶",且购买了"仁果类水果"对购买"全脂牛奶"的提升效果约为1.56倍
4. 往期推荐
基于VMD分解的VMD-LSTM时间序列预测模型实现,大力提升预测精度!
可解释性机器学习库Shapash——鸢尾花XGBoost分类解释实现
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
