1. Eclat算法简介
数据格式
- Apriori算法和FpGrowth都是从项集格式{TID: itemset}的事物集中挖掘频繁模式,其中TID是事物标识符,而itemset是事物TID中购买的商品。这种数据格式成为水平数据格式。
- 数据也可以用项-TID集格式{item:TID_set}表示,其中item是项的名称,而TID_set是包含item的事物标识符的集合。这种数据格式称为垂直数据格式。
等价变换类算法(Eclat算法)
- Eclat算法加入了倒排的思想,具体就是将事务数据中的项作为key,每个项对应的事务ID作为value。
- 只需对数据进行一次扫描,算法的运行效率会很高。
Ecalt算法的过程
- 通过扫描一次数据集,把水平格式的数据转换成垂直格式;
- 项集的支持度计数简单地等于项集的TID集的长度;
- 从k=1开始,可以根据先验性质,使用频繁k项集来构造候选(k+1)项集;
- 通过取频繁k项集的TID集的交,计算对应的(k+1)项集的TID集。
- 重复该过程,每次k增加1,直到不能再找到频繁项集或候选项集
Eclat算法原理
-
与fp-growth和apriori算法不同,Eclat算法加入了倒排的思想,具体就是将事务数据中的项作为key,每个项对应的事务ID作为value
-
水平格式转换成垂直格式
通过转换后的倒排表可以加快频繁集生成速度。
-
计算频繁1项集,结果为
-
由频繁1项集生成频繁2项集
-
由频繁2项集生成频繁3项集
频繁k项集生成频繁k+1项集的过程与由1项集生成2项集的过程完全一致。
Eclat算法实例
2 算法实现过程
2.1 输出结果
3完整代码
# -*- coding: utf-8 -*-
import numpy as np
from itertools import combinations
# 读取数据集
def read_data():
dataset = [['Milk', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Dill', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Milk', 'Apple', 'Kidney Beans', 'Eggs'],
['Milk', 'Unicorn', 'Corn', 'Kidney Beans', 'Yogurt'],
['Corn', 'Onion', 'Onion', 'Kidney Beans', 'Ice cream', 'Eggs']]
return dataset
# eclat算法
def eclat(transactions, min_support=0.35):
combos_to_counts = {}
for transaction in transactions: # 变量交易记录
goods = list(np.unique(transaction)) # 获取商品列表
length = len(goods)
for k in range(2, length + 1):
k_combos = list(combinations(goods, k))
for combo in k_combos:
if set(combo).issubset(transaction):
try:
combos_to_counts[combo] += 1
except KeyError:
combos_to_counts[combo] = 1
# Calculate supports for combinations of goods
#
combo_support_vec = []
for combo in combos_to_counts.keys():
# 计算支持度
support = float(combos_to_counts[combo]) / len(transactions)
combo_support_vec.append((combo, support))
# 按照支持度排序
combo_support_vec.sort(key=lambda x: float(x[1]), reverse=True)
# 第一列货物的列表,第二列为支持度
with open("./eclat_out.tsv", "w") as fo:
for combo, support in combo_support_vec:
if support < min_support:
continue
else:
print(combo, support)
fo.write(", ".join(combo) + "\t" + str(support) + "\n")
fo.close()
def main():
transactions = read_data()
eclat(transactions, min_support=0.6)
if __name__ == '__main__':
main()