Apriori
简介
Apriori是挖掘关联规则的频繁项集算法。
- 频繁项集(frequent item set):经常出现在一起的物品集合。
关联规则(association rule):暗示两种物品之间可能存在很强的关系。
支持度(support): 交易包含X∪Y总交易量
- 置信度\可信度(confindence): 交易包含X∪Y交易量包含X=X→Y
Apriori原理
如果某个项集是频繁的,那么它的所有子集也是频繁的,反过来,如果一个项集是非频繁的,那么它的所有超集也是非频繁的,按此原理可以减少时间复杂度。
关联挖掘
step1
算法先生成单个物品的项集列表,扫描交易记录是否满足最小支持度,不满足则删除。然后组合剩下的元素生成包含两个元素的频繁项集,再次扫描交易记录,去除不满足支持度的项集。重复以上过程,生成所有的频繁项集。
step2
从上一步生成的频繁项集中挖掘关联规则,同样组合产生所有可能的规则列表,判断每条规则是否满足置信度,不满足则删除,满足则保留。最后将生成的所有的规则按照其置信度进行排序,得到排序后的规则。
实现
实现部分参考了网上的代码。
算法主流程
def apriori_gen_rules(data_set, min_support, min_confd):
'''
利用apriori算法生成关联规则分为两步:
Step1:生成频繁项集
Step2:生成关联规则
Parameters:
-----------
data_set: item list
min_support: 项集需要满足的最小支持度,|X U Y| / |All|
min_confd: 项集之间关系需要满足的最小置信度,|X U Y| / |X|
Returns:
--------
rules: 通过apriori算法挖掘出的关联规则
'''
freq_item_set, item_set_support = gen_frequecy_set(data_set, min_support) # 利用Apriori算法生成频繁项集和对应的支持度
support_data = support_map(freq_item_set, item_set_support) # 将频繁项集和支持度联系起来
rules = gen_association_rules(freq_item_set, support_data, min_confd) # 利用频繁项集、对应的支持度和置信度生成关联规则
return rules
利用Apriori生成频繁项集
def gen_frequecy_set(data_set, min_support):
'''
生成频繁项集
Returns:
--------
freq_item_set: [[set(item1), set(item2)..]...] 存储频繁项集
item_set_support: [[support_score1, s_score2..]] 每个项集对应的支持度分值
'''
freq_item_set = []
item_set_support = []
discard_item_set = None
cur_dis_item_set_1, cur_dis_item_set_2 = [], []
cur_item_set_size = 0
while True:
# 循环产生项集大小为1, 2...的项集
cur_item_set_size += 1
if cur_item_set_size == 1:
# 产生初始的候选集
cur_candiate_set = gen_cand_set(data_set, [], cur_item_set_size)
# 将候选集分成要满足支持度的集合和不满足支持度的集合,同时记录满足支持度集合对应的支持度分值
saved_item_set, cur_dis_item_set_1, support_data = scan_data_set(data_set, cur_candiate_set, min_support)
else:
# 生成该轮候选集
cur_candiate_set = gen_cand_set(data_set, freq_item_set[-1], cur_item_set_size)
# 去除候选集中不符合非频繁项集的那些元素
cur_candiate_set, cur_dis_item_set_1 = subtract_item_set(discard_item_set, cur_candiate_set)
# 对剩下的候选集,进行遍历数据集,得到保存、丢弃、支持度集合
saved_item_set, cur_dis_item_set_2, support_data = scan_data_set(data_set, cur_candiate_set, min_support)
if saved_item_set == []: # 如果该轮没有产生任何频繁项集,则下一轮也不会产生新的频繁项集了,退出
break
freq_item_set.append(saved_item_set) # freq_item_set存储每一轮产生的频繁项集
discard_item_set = cur_dis_item_set_1 # discard_item_set存储每一轮产生的要丢弃的项集
discard_item_set.extend(cur_dis_item_set_2)
item_set_support.append(support_data) # item_set_support存储每一轮产生的频繁项集对应的支持度值
return freq_item_set, item_set_support
生成关联规则
def gen_association_rules(freq_item_set, support_data, min_confd):
'''
生成关联规则
Returns:
--------
association_rules: [(set(item1, item2, ...), itemx, confidence_score), ..]
存储关联规则,list存储,每个元素都是一个3元组,分别表示item1 和 item2.. 推出 itemx,置信度为confidence_score
'''
association_rules = []
for i in range(1, len(freq_item_set)):
for freq_item in freq_item_set[i]: # 对频繁项集的每一项尝试生成关联规则
gen_rules(freq_item, support_data, min_confd, association_rules)
return association_rules
def gen_rules(freq_item, support_data, min_confd, association_rules):
'''
生成关联规则,然后存储到association_rules中
'''
if len(freq_item) >= 2: # 遍历二阶及以上的频繁项集
for i in range(1, len(freq_item)): # 生成多种关联规则
for item in combinations(freq_item, i): # 遍历长度为1的item的组合
conf = support_data[frozenset(freq_item)] / float(support_data[frozenset(freq_item) - frozenset(item)])
if conf >= min_confd:
association_rules.append((freq_item - set(item), item, conf))
gen_rules(freq_item - set(item), support_data, min_confd, association_rules)
其他代码
效果
我这里用的一电商平台的数据,使用Apriori算法后,可以找出以下几个关联规则:
Previous_Item | Result_item | 置信度 |
---|---|---|
冻干榴莲脆、冻干黄桃脆 | 冻干芒果脆 | 0.684 |
茶香酥 | 绿茶蛋黄酥 | 0.590 |
婴儿彩棉帽子 | 婴儿彩棉袜子 | 0.535 |
蓝莓曲奇 | 蔓越莓曲奇 | 0.526 |
蔬菜脆 | 果蔬脆 | 0.523 |
… | … | … |
不过该电商平台目前商品数目不是很多,而且我只用了其中一天的数据,找到的关联规则基本都是同二级类目或者同一级类目下的商品之间的关系,反而成了挖掘物品之间相似度的工具了-_-。