本文代码及数据集来自《Python大数据分析与机器学习商业案例实战》
- 步骤1:设定最小支持度和最小置信度
首先设定最小支持度为2/5,即40%;最小置信度为4/5,即80%。 - 步骤2:根据最小支持度找出所有的频繁项集
这一步骤是关联分析中较为重要的一个环节,我们需要找到所有的频繁项集,因为强关联规则都是从频繁项集中产生的。
举例来说,项集{A,B,C,D}只出现了1次,支持度为1/5,小于最小支持度2/5,该项集就不是频繁项集,这就意味着很难从该项集中挖掘出类似{A,B,C}→{D}的强关联规则,即类似“购买了商品A、B、C的用户也会购买商品D”这样的规则。而项集{B,C}出现了4次,支持度为4/5,大于最小支持度2/5,该项集就属于频繁项集,即商品B和商品C经常同时出现,因此很有可能挖掘出{B}→{C}这样的强关联规则(当然还需要经过步骤3的最小置信度检验),即购买了商品B的用户也会购买商品C,这样就可以向购买了商品B的用户推荐商品C。
那么该如何快速找到所有的频繁项集呢?最简单的方法就是列出所有项集,然后计算它们的支持度,如果大于等于最小支持度则认定为频繁项集。但是列出所有项集意味着要列出所有的排列组合,如果数据量较大,则会造成巨大的计算量。
Apriori算法采用了一个精巧的思路来加快运算速度:先计算长度为1的项集,然后挖掘其中的频繁项集;再将长度为1的频繁项集进行排列组合,从中挖掘长度为2的频繁项集,依此类推。其核心逻辑是一个迭代判断的思想:如果连长度为n-1的项集都不是频繁项集,那么就不用考虑长度为n的项集了,也就是说,如果在迭代的过程中发现{A,B,C}不是频繁项集,那么{A,B,C,D}必然不是频繁项集,也就不用去考虑它了。
- 步骤3:根据最小置信度发现强关联规则
找到所有长度大于1的频繁项集后,强关联规则就很有可能就从这些频繁项集中产生,此时最后一个步骤就是从各个频繁项集中推导出所有可能的关联规则,再利用最小置信度来检验这些关联规则是否为强关联规则。
举例来说,频繁项集{A,B,C}的非空子集有{A}、{B}、{C}、{A,B}、{A,C}、{B,C},由此可以推导出6条关联规则。
从上表可知,只有规则2满足最小置信度要求,所以得到一条强关联规则{A,C}→{B}。对每个长度大于1的频繁项集进行类似操作,可推导出所有强关联规则,见下表。
至此,我们便得到了9条强关联规则。以第1条强关联规则{A,C}→{B}为例,我们便可以向购买了商品A和商品C的用户推荐商品B,其余依此类推。
# 数据读取与预处理
import pandas as pd
df = pd.read_excel('中医辨证.xlsx')
print(df.head())
symptoms = []
for i in df['病人症状'].tolist(): # 转换为双重列表结构
symptoms.append(i.split(','))
print(symptoms)
运行结果:
# 法一:apyori库
from apyori import apriori
rules = apriori(symptoms, min_support=0.1, min_confidence=0.7)
results = list(rules)
for i in results: # 遍历每一个频繁项集
for j in i.ordered_statistics: # 获取频繁项集的关联规则
X = j.items_base # 关联规则的前件
Y = j.items_add # 关联规则的后件
x = ', '.join([item for item in X]) # 连接前件中的元素
y = ', '.join([item for item in Y]) # 连接后件中的元素
if x != '': # 防止关联规则前件为空
print(x + ' → ' + y)
运行结果:
# 法二:mlxtend库
from mlxtend.preprocessing import TransactionEncoder
TE = TransactionEncoder()
data = TE.fit_transform(symptoms) # 将原始数据转换为布尔值
import pandas as pd
df = pd.DataFrame(data, columns=TE.columns_)
print(df.head())
运行结果:
from mlxtend.frequent_patterns import apriori
items = apriori(df, min_support=0.1, use_colnames=True)
print(items)
# 查看长度大于等于2的频繁项集
print(items[items['itemsets'].apply(lambda x: len(x)) >= 2])
运行结果:
# 根据最小置信度在频繁项集中挖掘强关联规则
from mlxtend.frequent_patterns import association_rules
rules = association_rules(items, min_threshold=0.7)
print(rules)
运行结果:
for i, j in rules.iterrows():
X = j['antecedents']
Y = j['consequents']
x = ', '.join([item for item in X])
y = ', '.join([item for item in Y])
print(x + ' → ' + y)
运行结果: