摘要 韩家炜教授等人提出FP-growth(Frequent Pattern growth)算法是频繁模式(Frequent Pattern, FP)挖掘领域的经典算法,其高效性能的背后是强大的信息压缩树——频繁模式树(Frequent Pattern Tree, FPTree),但在构建FPTree的过程中很容易忽略一些关键的步骤,如正确的频繁模式顺序(Frequent Pattern Ordering, FPO)和排序结果的稳定性,这篇文章从原论文出发,分析当前网络上高点击量的复现文章的不当之处,给出一个较为合理的复现方法。
引言
FP-growth算法由韩家炜[1]等人于2000年提出,其中FPTree是使得这一算法相比Aprioris等算法较为高效的关键数据结构,FPTree将数据库中的所有事务(Transactions)高度压缩成树的路径,所有的频繁项(Frequent Items, FIs)都成为树的一个节点,每个节点都拥有相应的计数,代表该FI在数据库中出现的次数,其中叶子节点的计数等于前向遍历路径中的FIs出现在数据库中的次数。因此所有的挖掘工作都以最初的FPTree为中心展开,而在构建一棵FPTree时,核心步骤在于对每一条事务进行降序排序。但是,在这一过程中要保证FIs出现顺序的一致性,否则树的结构是不唯一的,那么挖掘的结果就会产生偏差。 这是大部分人在复现的时候容易忽略的一个点,而另外一种情况出现在流行机器学习畅销书《Machine Learning in Action》(译为:机器学习实践)中,该书的FP-growth的实现版本结果存在随机性。 在网络上我选取了两篇点击量较高的FP-growth的复现文章:
这两篇文章相似程度极高,且都是参考了《Machine Learning in Action》这一书。可见这一错误传播的广泛程度。本文使用的数据集与FP-growth原论文使用的数据集相同,即:
图1: 数据集取自Han J et al.[1]
正确的FPTree如下图所示:
图2: 正确的FPTree取自Han J et al.[1]
之后在所提到的复现文章提供的算法上运行图1的数据集,分析他们的不足之处。另外,本文所使用的Python语言版本为3.7.6。
注: 本文对于所提到的书籍或文章均无恶意,仅从良性学术交流的目的出发,互相学习。由于本人才疏学浅,文中难免出现不妥之处,烦请各位雅正。
他们错在哪?
从前文中,我们知道FPTree的正确性取决于正确顺序的FIs,图1左边为原始数据库中的事务,假定最小支持度(minimum support)为3,那么在第一次扫描数据库之后可以得到如下的FIs:
$$ \langle (f:4) , (c:4) , (a:3) , (b:3) , (m:3) , (p:3) \rangl