前言
网上的对于该算法的讲解已经很好了,因此此处只给出流程和代码完事儿。不懂得原理的读者请去其他博文康康。
流程
①扫描数据集,将数据由水平格式进行垂直翻转。
②计算项集的支持度(等于TID,也就是标号的数量)
③从k=1开始,保留支持度大于最小支持度的项集。
④通过取频繁k项集的两两相交,得到k+1项集。再计算出频繁项集,
⑤重复第④步,直到频繁项集<=1。
代码实现
def Vertical_data(x):
'''
作用:构造垂直数据
:param x: 数据
:return: 返回字典
'''
Vertical_dict={} #生成用于储存 垂直数据 的字典
for index,items in enumerate(x): #循环每一行数据
for item in items: #循环一行中的每一个数据。
Vertical_dict[item]=Vertical_dict.get(item,[])+[index] #构造数据
return Vertical_dict #返回字典
def main(data,support_per):
'''
:param data: 数据
:param support_per: 最小支持度
'''
Vertical_dict=Vertical_data(data) #构造垂直字典
Vertical_dict={ k:v for k,v in Vertical_dict.items() if len(v)>support_per} #计算频繁1项集
a=Vertical_dict #将频繁项集赋给a。因为Vertical_dict在本文将用于储存所有的频繁项集
while True: #作死循环
a_len=len(a) #求k项集的字典的长度
a_list=list(a) #将字典的键作为列表
a={} #将a重新洗白,因为要更新a的项集了
for i in range(a_len-1): #循环从1到n-1项(索引)
for j in range(i+1,a_len): #每次都选取i以后的项与i组合(索引)
key_i=a_list[i] #取出对应的i的键
key_j=a_list[j] #取出对应的j的键
inter=sorted(set(Vertical_dict[key_i]) & set(Vertical_dict[key_j]))#计算交集
if len(inter)>support_per: #保留支持度大于最小支持度的项
key_list=sorted(set(key_i.split()+key_j.split())) #对两组数据以空格切开形成列表并去重然后排序得到组合项
key_str=" ".join(key_list) #对该组合项变成字符串,两两数据之间用空格隔开。因为字典不能将可变列表作为键保存。
a[key_str]=inter #生成组合项和对应的交集
Vertical_dict={**Vertical_dict,**a}#将得到的频繁k项集和原始频繁(1,k-1)项集合并.
if len(a)<=1: #打破循环并输出
print(Vertical_dict)
break
if __name__ == '__main__':
data=[["l1","l2","l5"],
["l2","l4"],
["l2","l3"],
["l1","l2","l4"],
["l1", "l3"],
["l2","l3"],
["l1","l3"],
["l1","l2","l3","l5"],
["l1","l2","l3"]]
main(data,support_per=1)
结束语
如有错误,还望指出。阿里嘎多。