实验3: Apriori算法
一、实验目的及要求:
(1) 掌握 Apriori 算法模型的实现过程及基本方法
(2) 掌握 Apriori 算法的实现
二、实验内容
(1) 选择合理的数据集。
(2) 数据预处理。
三、算法描述
Apriori算法是常用的用于挖掘出数据关联规则的算法,它用来找出数据值中频繁出现的数据集合,找出这些集合的模式有助于我们做一些决策。比如在常见的超市购物数据集,或者电商的网购数据集中,如果我们找到了频繁出现的数据集,那么对于超市,我们可以优化产品的位置摆放,对于电商,我们可以优化商品所在的仓库位置,达到节约成本,增加经济效益的目的
Apriori算法的流程如下:
输入:数据集合D,支持度阈值α
输出:最大的频繁k项集
1)扫描整个数据集,得到所有出现过的数据,作为候选频繁1项集。k=1,频繁0项集为空集
2)挖掘频繁k项集
a) 扫描数据计算候选频繁k项集的支持度
b) 去除候选频繁k项集中支持度低于阈值的数据集,得到频繁k项集。如果得到的频繁k项集为空,则直接返回频繁k-1项集的集合作为算法结果,算法结束。如果得到的频繁k项集只有一项,则直接返回频繁k项集的集合作为算法结果,算法结束
c) 基于频繁k项集,连接生成候选频繁k+1项集
3) 令k=k+1,转入步骤2
四、实验结果分析
数据集由我自己使用随机数生成, 如下:
df = pd.DataFrame()
n_data = 1000
data_dict = {}
data = np.random.randint(2, size=(n_data, 5))
for i in range(5):
data_dict[chr(ord('A') + i)] = data[:, i]
df = df.from_dict(data_dict)
df = df.replace(0, 'not_exist')
df = df.replace(1, 'exist')
df.to_csv('./data.csv', index=False)
df = pd.read_csv('./data.csv')
print("数据集生成成功!")
该算法只有一个可以调节的参数, 即支持度阈值alpha, 当alpha为0.1时, 结果如下:
为0.5时, 如下:
以下是我的实现:
def aprior(D: pd.DataFrame, alpha: float) -> set:
"""
aprior算法的正确实现
Args:
D (pd.DataFrame): 使用aprior寻找频繁项集的数据集
alpha (float): 支持度阈值
"""
# 频繁项集, 初始是1项集
fre_set = set()
# 1. 扫描整个数据集, 得到所有出现过的数据, 作为候选频繁1项集
for col in D.columns:
if D[col].sum() != 0:
fre_set.add(col)
if len(fre_set) <= 1:
return fre_set
# 2. 挖掘频繁k项集, k初始为1
n = len(fre_set)
last_true_set = set()
for k in range(1, n + 1, 1):
# 打印一些日志debug用
import copy
tmp = list(copy.deepcopy(fre_set))
tmp.sort()
print("候选频繁{}项集: {}".format(k, tmp))
# 真正的频繁k项集true_set
true_set = set()
# 扫描数据集计算某项集的支持度
for items in fre_set:
cnt = 0
item_list = str(items).split(',')
for i in range(D.shape[0]):
exist = True
for item in item_list:
if D.loc[i, item] == False:
exist = False
break
if exist == True:
cnt += 1
if cnt / D.shape[0] >= alpha:
true_set.add(items)
# 此时得到了真正的频繁k项集
t = list(copy.deepcopy(true_set))
t.sort()
print("真正的频繁{0}项集为: {1}".format(k, t))
# 长度为1则直接返回自身, 为0时要返回频繁k-1项集
if len(true_set) == 1:
return true_set
if len(true_set) == 0:
return last_true_set
last_true_set = true_set
# 否则连接各种项集以生成新的候选k + 1项集fre_set
fre_set.clear()
items_list = list(true_set)
for i in range(len(items_list)):
for j in range(i + 1, len(items_list)):
all_ems = set()
for t in items_list[i].split(','):
all_ems.add(t)
for t in items_list[j].split(','):
all_ems.add(t)
if len(all_ems) != k + 1:
continue
t = list(all_ems)
t.sort()
fre_set.add(",".join(t[i] for i in range(len(t))))
五、实验总结
本次实验我使用Python掌握并实现了Apriori关联关系挖掘算法, 这是一种非常简单且符合直觉的数据挖掘算法, 能够非常客观准确的找出数据中项目之间关系紧密的那部分数据, 对其的实现难度并不高但需要细心, 在生成K + 1项集时要注意特判生产出来的项集大小不等于K + 1的特殊情况, 并将其continue掉,。