跳转到内容

R 中的数据挖掘算法/频繁模式挖掘/FP-Growth 算法

来自维基教科书,开放世界中的开放书籍

在数据挖掘中,寻找大型数据库中的频繁模式的任务非常重要,并在过去几年中被大规模研究。不幸的是,这项任务计算量很大,尤其是在存在大量模式的情况下。

FP-Growth 算法由 Han 在 [1] 中提出,是一种高效且可扩展的方法,它通过模式片段增长来挖掘完整的频繁模式集,并使用扩展的前缀树结构来存储关于频繁模式的压缩和关键信息,称为频繁模式树(FP-Tree)。在他的研究中,Han 证明了他的方法优于其他流行的挖掘频繁模式的方法,例如 Apriori 算法 [2] 和 TreeProjection [3]。在一些后续作品 [4] [5] [6] 中证明,FP-Growth 具有比其他方法更好的性能,包括 Eclat [7] 和 Relim [8]。FP-Growth 算法的普及和效率促成了许多研究,这些研究提出了改进其性能的变体 [5] [6] [9] [10] [11] [12] [13] [14] [15] [16]

本章介绍了该算法和一些变体,并讨论了 R 语言的特性以及在 R 中实现该算法以供使用的策略。接下来,提出了简要的结论和未来工作。

该算法

[编辑 | 编辑源代码]

FP-Growth 算法是一种寻找频繁项集的替代方法,无需使用候选生成,从而提高性能。为此,它使用分治策略 [17]。该方法的核心是使用一种称为频繁模式树(FP-Tree)的特殊数据结构,它保留了项集关联信息。

简单来说,该算法的工作原理如下:首先,它压缩输入数据库,创建 FP-Tree 实例来表示频繁项。完成第一步后,它将压缩后的数据库划分为一组条件数据库,每个数据库都与一个频繁模式相关联。最后,分别挖掘每个这样的数据库。使用这种策略,FP-Growth 减少了递归查找短模式的搜索成本,然后将它们连接成长频繁模式,提供了良好的选择性。

在大型数据库中,不可能将 FP-Tree 保存在主内存中。解决此问题的策略是首先将数据库划分为一组较小的数据库(称为投影数据库),然后从每个较小的数据库构建 FP-Tree。

接下来的几个小节将描述 FP-Tree 结构和 FP-Growth 算法,最后将提供一个示例,以便更轻松地理解这些概念。

FP-Tree 结构

[编辑 | 编辑源代码]

频繁模式树(FP-Tree)是一种紧凑的结构,用于存储数据库中频繁模式的定量信息 [4]

Han 将 FP-Tree 定义为如下所示的树结构 [1]

  1. 一个标记为“null”的根,其子节点是一组项前缀子树;
  2. 项前缀子树中的每个节点都包含三个字段
  1. 项名称:注册节点表示的项;
  2. 计数:到达节点的路径部分所表示的事务数量;
  3. 节点链接:链接到 FP-Tree 中下一个具有相同项名称的节点,如果不存在则为 null。
  1. 频繁项表头表中的每个条目都包含两个字段
  1. 项名称:与节点相同;
  2. 节点链接头部:指向 FP-Tree 中第一个携带该项名称的节点的指针。

此外,频繁项表头表可以包含项的计数支持。下面的图 1 展示了一个 FP-Tree 的示例。

图 1:来自 [17] 的 FP-Tree 示例。


Han 在 [1] 中定义的构建 FP-Tree 的原始算法如下所示,即算法 1。

算法 1:FP-Tree 构建

输入:事务数据库 DB 和最小支持阈值 ?。
输出:FP-Tree,DB 的频繁模式树。
方法:FP-Tree 按以下步骤构建。
  1. 扫描事务数据库 DB 一次。收集 F,即频繁项集,以及每个频繁项的支持度。按支持度降序对 F 进行排序,得到 FList,即频繁项列表。
  2. 创建 FP-Tree T 的根,并将其标记为“null”。对于 DB 中的每个事务 Trans,执行以下操作
  • 选择 Trans 中的频繁项,并根据 FList 的顺序对它们进行排序。令 Trans 中排序后的频繁项列表为 [ p | P],其中 p 是第一个元素,P 是其余列表。调用 insert tree([ p | P], T )。
  • 函数 insert tree([ p | P], T ) 的执行方式如下。如果 T 存在子节点 N,使得 N.item-name = p.item-name,则将 N 的计数加 1;否则,创建一个新节点 N,其计数初始化为 1,其父链接指向 T,其节点链接通过节点链接结构指向具有相同项名称的节点。如果 P 不为空,则递归调用 insert tree(P, N )。


使用此算法,FP-Tree 在扫描数据库两次后构建完成。第一次扫描收集并排序频繁项集,第二次扫描构建 FP-Tree。

FP-Growth 算法

[编辑 | 编辑源代码]

构建完 FP-Tree 后,就可以对其进行挖掘,以找到完整的频繁模式集。为了完成这项工作,Han 在 [1] 中提出了一组引理和性质,之后描述了 FP-Growth 算法,如下所示,即算法 2。

算法 2:FP-Growth

输入:一个数据库 DB,由根据算法 1 构建的 FP-Tree 表示,以及最小支持阈值 ?。
输出:完整的频繁模式集。
方法:调用 FP-growth(FP-tree, null)。
过程 FP-growth(Tree, a) {
(01) 如果 Tree 包含一条前缀路径,则 { // 挖掘单前缀路径 FP-Tree
(02) 令 P 为 Tree 的单前缀路径部分;
(03) 令 Q 为多路径部分,其中顶部分支节点被替换为 null 根;
(04) 对于路径 P 中节点的每个组合(记为 ß),执行以下操作
(05) 生成模式 ß ∪ a,其支持度 = ß 中节点的最小支持度;
(06) 令 freq pattern set(P) 为如此生成的模式集;
}
(07) 否则,令 Q 为 Tree;
(08) 对于 Q 中的每个项 ai,执行以下操作 { // 挖掘多路径 FP-Tree
(09) 生成模式 ß = ai ∪ a,其支持度 = ai .support;
(10) 构建 ß 的条件模式库,然后构建 ß 的条件 FP-Tree Tree ß;
(11) 如果 Tree ß ≠ Ø,则
(12) 调用 FP-growth(Tree ß , ß);
(13) 令 freq pattern set(Q) 为如此生成的模式集;
}
(14) 返回 (freq pattern set(P) ∪ freq pattern set(Q) ∪ (freq pattern set(P) × freq pattern set(Q)))
}


当 FP 树包含单个前缀路径时,可以将完整的频繁模式集划分为三个部分生成:单个前缀路径 P、多路径 Q 以及它们的组合(第 01 到 03 行和第 14 行)。单个前缀路径的所得模式是其具有最小支持的子路径的枚举(第 04 到 06 行)。之后,定义多路径 Q(第 03 或 07 行)并处理由此产生的模式(第 08 到 13 行)。最后,在第 14 行,将组合的结果作为找到的频繁模式返回。

一个例子

[edit | edit source]

本节提供一个简单的示例来说明先前算法的工作原理。原始示例可以在 [18] 中查看。

考虑以下交易,最小支持度为 3

i(t)
1 FBAED
2 BCE
3 ABDE
4 ABCE
5 ABCDE
6 BCD


要构建 FP 树,首先计算频繁项的支持度并按降序排列,得到以下列表:{ B(6), E(5), A(4), C(4), D(4) }。然后,使用排序后的项目列表,如 图 2 所示,为每个交易迭代地构建 FP 树。

图 2:迭代构建 FP 树。


如图 3 所示,对 FP-Growth 的初始调用使用从算法 1 获得的 FP 树(如 图 2 (f) 所示),以在对投影树进行递归调用时处理之前提供的交易中的频繁模式。

使用深度优先策略,分别确定到项目 D、C、A、E 和 B 的投影树。首先递归处理 D 的投影树,投影 DA、DE 和 DB 的树。以类似的方式处理剩余的项目。在处理结束时,频繁项集为:{ DAE, DAEB, DAB, DEB, DA, DE, DB, CE, CEB, CB, AE, AEB, AB, EB }。

图 3:FP-Growth 算法递归调用发现的投影树和频繁模式。

FP-Growth 算法变体

[edit | edit source]

如前所述,FP-Growth 算法的流行和效率促成了许多研究,这些研究提出了各种变体来提高其性能 [5] [6] [9] [12] [19] [12] [13] [14] [15] [16]。本节简要介绍其中一些。

DynFP-Growth 算法

[edit | edit source]

DynFP-Growth [13] [5],重点关注基于两个观察到的问题的 FP-Tree 算法构建的改进

  1. 对于相同的“逻辑”数据库,生成的 FP 树并不唯一;
  2. 该过程需要对数据库进行两次完整扫描。

为了解决第一个问题,Gyorödi C. 等人 [13] 提出了使用支持降序排列以及词典排序的方法,从而确保了对于不同的“逻辑上等效”数据库,生成的 FP 树的唯一性。为了解决第二个问题,他们建议设计一种动态 FP 树重排序算法,并在检测到至少一项提升到更高阶时使用此算法。

此方法的一个重要特点是,当实际数据库更新时,无需重建 FP 树。只需再次执行算法,并考虑新交易和存储的 FP 树。

由于动态重排序过程,另一个提议的适应性是在原始结构中的修改,用双向链表替换单向链表以将树节点链接到标题,并在同一标题中添加一个主表。有关更多详细信息,请参阅 [13]

FP-Bonsai 算法

[edit | edit source]

FP-Bonsai [6] 通过使用 ExAnte 数据减少技术 [14] 减少(修剪)FP 树来提高 FP-Growth 性能。修剪后的 FP 树称为 FP-Bonsai。有关更多详细信息,请参阅 [6]

AFOPT 算法

[edit | edit source]

Liu 在 [12] 中提出了 AFOPT 算法,该算法旨在从四个方面提高 FP-Growth 算法的性能

  • 项目搜索顺序:当搜索空间被划分时,所有项目都按某种顺序排序。使用不同的项目搜索顺序,构造的条件数据库的数量可能会有很大差异;
  • 条件数据库表示:条件数据库的遍历和构造成本在很大程度上取决于其表示;
  • 条件数据库构建策略:物理地构建每个条件数据库可能很昂贵,会影响每个单独条件数据库的挖掘成本;
  • 树遍历策略:使用自上而下的遍历策略,树的遍历成本最小。

有关更多详细信息,请参阅 [12]

NONORDFP 算法

[edit | edit source]

Nonordfp 算法 [15] [5] 的灵感来自 FP-Growth 算法的运行时间和空间需求。理论上的区别是主要数据结构(FP 树),它更紧凑,并且不需要在每个条件步骤中重建它。引入了使用 Trie 数据结构 的 FP 树的紧凑、内存高效表示,其内存布局允许更快的遍历、更快的分配以及可选的投影。有关更多详细信息,请参阅 [15]

FP-Growth* 算法

[edit | edit source]

该算法由 Grahne 等人提出。[16][19],并基于他对使用 FP-Growth 计算频繁项集的 CPU 时间的结论。他们观察到 80% 的 CPU 时间用于遍历 FP-Tree。[9] 因此,他们使用基于数组的数据结构结合 FP-Tree 数据结构来减少遍历时间,并结合了几种优化技术。有关详细信息,请参见[16][19]

PPV、PrePost 和 FIN 算法

[edit | edit source]

这三种算法由 Deng 等人提出。[20][21][22],并基于三种新颖的数据结构,即节点列表[20]、N-列表[21] 和节点集[22],分别用于促进频繁项集的挖掘过程。它们基于 FP-Tree,每个节点都用前序遍历和后序遍历进行编码。与节点列表相比,N-列表和节点集更高效。这使得 PrePost [21] 和 FIN [22] 的效率高于 PPV [20]。有关详细信息,请参见[20][21][22]

R 中的数据可视化

[edit | edit source]

通常,用于挖掘频繁项集的数据存储在文本文件中。可视化数据的第一步是将其加载到数据帧中(一个表示 R 中数据的对象)。

函数 read.table 可以以以下方式使用

var <- read.table(fileName, fileEncoding=value, header = value, sep = value)

Where:
  • var: the R variable to receive the loaded data.
  • fileName: is a string value with the name of the file to be loaded.
  • fileEncoding: to be used when the file has no-ASCII characters.
  • header: indicates that the file has headers (T or TRUE) or not (F or FALSE).
  • sep: defines the field separator character (“,”, “;” or “\t” for example)
  • Only the filename is a mandatory parameter.


R 中另一个用于加载数据的函数称为 scan。有关详细信息,请参见 R 数据导入/导出手册

数据的可视化可以通过两种方式完成

  • 使用变量名 (var) 以表格形式列出数据。
  • 以及 summary(var) 以列出数据的摘要。


示例

> data <- read.table("boolean.data", sep=",", header=T)

> data
      A    B     C     D     E
1  TRUE TRUE FALSE  TRUE  TRUE
2 FALSE TRUE  TRUE FALSE  TRUE
3  TRUE TRUE FALSE  TRUE  TRUE
4  TRUE TRUE  TRUE FALSE  TRUE
5  TRUE TRUE  TRUE  TRUE  TRUE
6 FALSE TRUE  TRUE  TRUE FALSE

> summary(data)
     A              B               C               D               E
 Mode :logical   Mode:logical   Mode :logical   Mode :logical   Mode :logical
 FALSE:2         TRUE:6         FALSE:2         FALSE:2         FALSE:1
 TRUE :4         NA's:0         TRUE :4         TRUE :4         TRUE :5
 NA's :0                        NA's :0         NA's :0         NA's :0


在上面的示例中,使用简单的二进制数据库“boolean.data”中的数据加载到数据帧变量 data 中。在命令行中键入变量名,将打印其内容,键入 summary 命令将打印每个项目的频率出现情况。summary 函数的工作方式不同。它取决于变量中数据的类型,有关详细信息,请参见[23][24][25]

之前介绍的函数可能很有用,但对于频繁项集数据集,使用一个名为 arules [26] 的特定包可以更好地可视化数据。

使用 arules,提供了一些函数

  • read.transactions:用于将数据库文件加载到变量中。
  • inspect:用于列出事务。
  • length:返回事务数量。
  • image:绘制包含所有事务的矩阵格式的图像。
  • itemFrequencyPlot:计算每个项目的频率并将其绘制在条形图中。


示例

> data <- read.transactions("basket.data", format="basket", sep = ",")

> data
transactions in sparse format with
 6 transactions (rows) and
 5 items (columns)

> inspect(data)
  items
1 {A,
   B,
   D,
   E}
2 {B,
   C,
   E}
3 {A,
   B,
   D,
   E}
4 {A,
   B,
   C,
   E}
5 {A,
   B,
   C,
   D,
   E}
6 {B,
   C,
   D}

> length(data)
[1] 6

> image(data)

> itemFrequencyPlot(data, support=0.1)


在这个例子中,我们可以看到在命令行中使用变量名的区别。从事务中,只打印了行数(事务)和列数(项目)。image(data) 和 itemFrequencyPlot(data, support = 0.1) 的结果分别在下面的图 4 和图 5 中给出。

图 4:image(data) 调用的结果。


图 5:itemFrequencyPlot(data, support = 0.1) 调用的结果。

R 中的实现

[edit | edit source]

R [23][24][25][27][28] 提供了用于数据操作、计算和图形显示的几种工具,非常适用于数据分析和挖掘。它既可以用作统计库,也可以用作编程语言。

作为统计库,它提供了一组用于汇总数据、矩阵工具、概率分布、统计模型和图形过程的函数。

作为编程语言,它提供了一组函数、命令和方法来实例化和管理不同类型对象的的值(包括列表、向量和矩阵)、用户交互(从控制台输入和输出)、控制语句(条件语句和循环语句)、函数的创建、对外部资源的调用以及创建包。

本章并没有完成对 R 资源的详细介绍,而是重点关注使用 R 实现算法或在 R 中使用的挑战。但是,为了更好地理解 R 的功能,在附录 A 中提供了一些基于[28] 的基本示例。

使用 R 实现算法通常需要创建复杂的对象来表示要处理的数据结构。此外,可能需要实现复杂函数来处理这些数据结构。考虑到使用 R 实现 FP-Growth 算法的具体情况,仅使用 R 资源可能很难表示和处理 FPTree。此外,出于性能原因,使用其他语言实现算法并将其与 R 集成可能很有趣。使用其他语言的其他原因是获得更好的内存管理以及使用现有的包[29]

有两种方法可以将 R 与其他语言集成,下面将简要介绍:创建包和使用接口函数进行外部调用。[24] 接下来介绍了在这项工作中使用的 FP-Growth 实现以及将其与 R 集成的努力。对于两者,都需要安装 RTools

创建包

[edit | edit source]

包是将用其他语言实现的可选代码加载到 R 中的一种机制。[24] R 发行版本身包含大约 25 个包,本 WikiBook 中使用的一些额外包可以列出


要创建包,需要遵循一些规范。R 包的来源包含在下面描述的目录结构中

  • 根目录:包含 DESCRIPTION 文件和一些可选文件(INDEX、NAMESPACE、configure、cleanup、LICENCE、COPYING 和 NEWS)的根目录。
  • R:仅包含 R 代码文件,这些文件可以通过 R 命令 source(filename) 执行以创建用户使用的 R 对象。或者,此目录可以包含一个文件 sysdata.rda。此文件包含在 R 控制台执行中创建的 R 对象的保存图像。
  • data:旨在包含数据文件,这些文件可以通过延迟加载提供或使用函数 data() 加载。这些数据文件可以来自三种不同类型:纯 R 代码(.r 或 .R)、表格(.tab、.txt 或 .csv)或来自 R 控制台的保存数据(.RData 或 .rda)。一些额外的压缩文件可用于表格文件。
  • demo:包含纯 R 代码中的脚本(用于使用函数 demo() 运行),这些脚本演示了包中的一些功能。
  • exec:可能包含包需要的其他可执行文件,通常是用于 shell、Perl 或 Tcl 等解释器的脚本。
  • inst:其内容将在构建后复制到安装目录,其 Makefile 可以创建要安装的文件。可能包含所有旨在供最终用户查看的信息文件。
  • man:应仅包含包中对象的文档文件(使用特定的 R 文档格式)。空 man 目录会导致安装错误。
  • po:用于与国际化相关的文件,换句话说,用于翻译错误和警告消息。
  • src:包含源代码、头文件、makevars 和 makefile。支持的语言有:C、C++、FORTRAN 77、Fortran 9x、Objective C 和 Objective C++。在一个包中混合所有这些语言是不可能的,但混合 C 和 FORTRAN 77 或 C 和 C++ 似乎很成功。但是,有一些方法可以从其他包中进行使用。
  • tests:用于其他特定于包的测试代码。


创建源代码包后,必须在操作系统控制台的命令行中安装它。

R CMD INSTALL <parameters>


或者,可以使用 R 控制台中的命令行从 R 中下载并安装包。

> install.packages(<parameters>)


请参阅 安装和管理手册 [27],了解详细信息。

安装后,需要使用 R 控制台中的命令行加载包才能使用它。

> library(packageName)

使用接口函数进行外部调用

[edit | edit source]

使用接口函数进行外部调用是一种简单的方法,可以无需遵守之前描述的所有规则来创建 R 包,即可使用外部实现。

首先,代码需要包含 R.h 头文件,该文件随 R 安装一起提供。

要编译源代码,需要在操作系统命令行中使用 R 编译器。

> R CMD SHLIB <parameters>


要用于 R 的编译代码需要在类 Unix 操作系统中作为共享对象加载,或在 Windows 操作系统中作为 DLL 加载。要加载或卸载它,可以使用 R 控制台中的命令。

> dyn.load(fileName)
> dyn.unload(fileName)


加载后,可以使用以下函数之一调用外部代码。

  • .C
  • .Call
  • .Fortran
  • .External


下面展示了两个简单的示例,使用 .C 函数。

示例 1:Hello World

## C code in file example1.c

#include <R.h>

Void do_stuff ()
{
   printf("\nHello, I'm in a C code!\n");
}


## R code in file example.R

dyn.load("example1.dll")

doStuff <-
function (){
    tmp <- .C("do_stuff")
	rm(tmp)
	return(0)
}

doStuff()


## Compiling code in OS command line

C:\R\examples>R CMD SHLIB example1.c
gcc -I"C:/PROGRA~1/R/R-212~1.0/include" -O3 -Wall -std=gnu99 -c example1.c -o example1.o
gcc -shared -s -static-libgcc -o example1.dll tmp.def example1.o -LC:/PROGRA~1/R/R-212~1.0/bin/i386 -lR


## Output in R console

> source("example1.R")

Hello, I'm in a C code!
>


示例 2:使用整数向量调用 C [29]

##C code in file example2.c

#include <R.h>

void doStuff(int *i) {
    i[0] = 11;
}


## Output in R console

> dyn.load("example2.dll")
> a <- 1:10
> a
 [1]  1  2  3  4  5  6  7  8  9 10
> out <- .C("doStuff", b = as.integer(a))
> a
 [1]  1  2  3  4  5  6  7  8  9 10
> out$b
 [1] 11  2  3  4  5  6  7  8  9 10

FP-Growth 实现

[edit | edit source]

此工作中使用的 FP-Growth 实现由 Christian Borgelt [30] 实现,他是欧洲软计算中心的首席研究员。他还实现了 arules 包 [26] 中用于 Eclat 和 Apriori 算法的代码。源代码可以从他的个人网站下载。

正如 Borgelt [30] 所描述的那样,核心操作的实现变体(计算 FP 树的投影)有两种。此外,投影的 FP 树可以选择通过删除变得不再频繁的项来进行修剪(使用 FP-Bonsai [6] 方法)。

源代码分为三个主要文件夹(包)。

  • fpgrowth:包含实现算法并管理 FP 树的主要文件;
  • tract:管理项集、事务及其报告;
  • util:用于 fpgrowth 和 tract 的工具。


从操作系统命令行调用此实现的语法为

> fpgrowth [options] infile [outfile [selfile]]
-t#      target type                              (default: s)
         (s: frequent, c: closed, m: maximal item sets,
          g: generators, r: association rules)
-m#      minimum number of items per set/rule     (default: 1)
-n#      maximum number of items per set/rule     (default: no limit)
-s#      minimum support of an item set/rule      (default: 10%)
-S#      maximum support of an item set/rule      (default: 100%)
         (positive: percentage, negative: absolute number)
-o       use original rule support definition     (body & head)
-c#      minimum confidence of an assoc. rule     (default: 80%)
-e#      additional evaluation measure            (default: none)
-a#      aggregation mode for evaluation measure  (default: none)
-d#      threshold for add. evaluation measure    (default: 10%)
-i       invalidate eval. below expected support  (default: evaluate all)
-p#      (min. size for) pruning with evaluation  (default: no pruning)
         (< 0: weak forward, > 0 strong forward, = 0: backward pruning)
-q#      sort items w.r.t. their frequency        (default: 2)
         (1: ascending, -1: descending, 0: do not sort,
          2: ascending, -2: descending w.r.t. transaction size sum)
-A#      variant of the fpgrowth algorithm to use (default: c)
-x       do not prune with perfect extensions     (default: prune)
-l#      number of items for k-items machine      (default: 16)
         (only for variants s and d, options -As or -Ad)
-j       do not sort items w.r.t. cond. support   (default: sort)
         (only for algorithm variant c, option -Ac)
-u       do not use head union tail (hut) pruning (default: use hut)
         (only for maximal item sets, option -tm)
-F#:#..  support border for filtering item sets   (default: none)
         (list of minimum support values, one per item set size,
         starting at the minimum size, as given with option -m#)
-R#      read item selection/appearance indicators
-P#      write a pattern spectrum to a file
-Z       print item set statistics (number of item sets per size)
-N       do not pre-format some integer numbers   (default: do)
-g       write item names in scanable form (quote certain characters)
-h#      record header  for output                (default: "")
-k#      item separator for output                (default: " ")
-I#      implication sign for association rules   (default: " <- ")
-v#      output format for set/rule information   (default: " (%S)")
-w       integer transaction weight in last field (default: only items)
-r#      record/transaction separators            (default: "\n")
-f#      field /item        separators            (default: " \t,")
-b#      blank   characters                       (default: " \t\r")
-C#      comment characters                       (default: "#")
-!       print additional option information
infile   file to read transactions from           [required]
outfile  file to write item sets/assoc. rules to  [optional]


可以选择每个集合的项数限制、最小支持度、评估度量、配置输入和输出格式等等。

使用 test1.tab 示例文件(随源代码提供)作为输入文件、test1.out 和最小支持度为 30% 对 FP-Growth 进行简单调用,其结果如下所示。

C:\R\exec\fpgrowth\src>fpgrowth -s30 test1.tab test1.out
fpgrowth - find frequent item sets with the fpgrowth algorithm
version 4.10 (2010.10.27)        (c) 2004-2010   Christian Borgelt
reading test1.tab ... [5 item(s), 10 transaction(s)] done [0.00s].
filtering, sorting and recoding items ... [5 item(s)] done [0.00s].
reducing transactions ... [8/10 transaction(s)] done [0.00s].
writing test1.out ... [15 set(s)] done [0.00s].


结果显示了一些关于版权的信息和一些执行数据,例如项数、事务数和频繁集数(本例中为 21 个)。输入和输出文件的内容如下所示。

输入文件内容

a b c
a d e
b c d
a b c d
b c
a b d
d e
a b c d
c d e
a b c


输出文件内容

e d  (30.0)
e  (30.0)
a c b  (40.0)
a c  (40.0)
a d b  (30.0)
a d  (40.0)
a b  (50.0)
a  (60.0)
d b c  (30.0)
d b  (40.0)
d c  (40.0)
d  (70.0)
c b  (60.0)
c  (70.0)
b  (70.0)

从 R 调用 FP-Growth

[edit | edit source]

如前所述,要创建一个包,需要遵守几个规则,创建标准目录结构和内容,以使外部源代码可用。前面介绍了另一种方法,即创建共享对象或 DLL,并使用特定的 R 函数(.C、.CALL 等等)调用它。

从头开始做将现有代码改编成一个包的工作可能是一项艰巨的任务,需要花费大量时间。一个有趣的方法是迭代地创建和改编共享对象或 DLL,并进行测试以验证它,并在一些迭代后改进改编,当获得满意的结果后,开始进行包版本的工作。

使 C 实现可用于 R 的迭代意图如下所示。

1. 创建一个简单的命令行调用,不带参数,只对原始源代码(fpgrowth.c 文件)进行两个更改。
  • 将主函数重命名为 FP-Growth,并使用相同的签名;
  • 创建一个要从 R 中调用的函数,从配置文件创建参数(仅包含一个与命令行语法相同的字符串,将其分解成一个数组,以用作 FP-Growth 函数的参数数组);
2. 使用 R 编译命令编译代码项目,包括 R.h 读取器文件,并使用 R 调用它;
3. 实施来自 R 调用的输入参数,消除配置文件的使用,包括更改以定义输入文件名以用于 R 中的数据帧;
4. 将输出准备成一个 R 数据帧,以返回到 R;
5. 创建 R 包。


第一次迭代可以轻松完成,没有任何意外。

不幸的是,第二次迭代看起来也很容易完成,但在实践中却证明非常困难。R 编译命令不能与 makefile 一起使用,因此无法使用它来编译原始代码。经过一些实验后,策略改为使用改编后的代码构建一个库,没有创建要从 R 中调用的函数,然后创建一个包含此函数并使用编译后的库的新代码。接下来,从 R 调用新编译的 DLL 会引发执行错误。在调试执行过程中,浪费了大量时间,发现创建库的一些编译配置是错误的。为了解决这个问题,进行了一些测试,创建了一个可执行版本,使用操作系统命令行运行它,直到所有执行错误都得到解决。然而,解决了这些错误后,又发现了另一个意外的行为。从 R 控制台调用使用 R 命令编译的版本,在加载 DLL 函数时,出现了 cygwin 版本不兼容的错误。尝试了很多实验,更改编译参数、cygwin 的不同版本等等,但都没有成功(这些测试只在 Windows 操作系统下进行)。因此,在第二次迭代中没有取得成功,后面的步骤就变得很困难。

第三和第四次迭代中预期的主要挑战是将 R 数据类型和结构与其在 C 语言中的对应物进行接口,无论是用于数据集输入和要转换为内部使用的其他输入参数,还是用于创建要返回到 R 的输出数据集。另一种方法是改编所有代码以使用接收到的数据。但是,这似乎更复杂。

第五次迭代看起来像是一项官僚工作。一旦代码完全改编并验证,创建额外的目录和所需内容应该是一件容易的事。

结论和未来工作

[edit | edit source]

本章介绍了一种用于挖掘数据库中频繁模式的有效且可扩展的算法:FP-Growth。该算法使用了一种有用的数据结构 FP 树来存储关于频繁模式的信息。还介绍了该算法的实现。此外,还介绍了 R 语言的一些特性以及将算法源代码改编以在 R 中使用的实验。我们可以观察到,进行这种改编是一项艰巨的任务,无法在短时间内完成。不幸的是,还没有时间来完成这种改编。

作为一项未来工作,将对更好地理解 R 中外部资源的实现以及完成本工作中提出的任务,并在随后将结果与 R 中可用的其他频繁项集挖掘算法进行比较,会很有趣。

附录 A:R 语句示例

[edit | edit source]

一些基于 [28] 的基本示例。

获取有关函数的帮助

> help(summary)
> ?summary


创建对象

> perceptual <- 1.2


数字表达式

> z <- 5
> w <- z^2
> y <- (34 + 90) / 12.5


打印对象值

> w
[1] 25


创建向量

> v <- c(4, 7, 23.5, 76.2, 80)


向量运算

> x <- sqrt(v)
> v1<- c(4, 6, 87)
> v2 <- c(34, 32.4, 12)
> v1 + v2
[1] 38.0 38.4 99.0


分类数据

> s <- c("f", "m", "m", "f")
> s
[1] "f" "m" "m" "f"
> s <- factor(s)
> s
[1] f m m f
Levels: f m
> table(s)
s
f m
2 2


序列

> x <- 1:1000
> y <- 5:0
> z <- seq(-4, 1, 0.5) # create a sequence starting in -4, stopping in 1 
                       # with an increment of 0.5
> w <- rnorm(10) # create a random sequence of 10 numeric values
> w <- rnorm(10, mean = 10, sd = 3) # create a normal distribution of 
                                    # 10 numeric values with mean of 10
                                    # and standard deviation of 3


矩阵

> m1 <- matrix(c(45,  23,  66,  77,  33,  44),  2,  3)
> m1
        [,1]   [,2]   [,3]
[1,]     45     66     33
[2,]     23     77     44
> m2 <- matrix(c(12,  65,  32,  7,  4,  78),  2,  3)
> m2
        [,1]   [,2]   [,3]
[1,]     12     32      4
[2,]     65      7     78
> m1 + m2
        [,1]   [,2]   [,3]
[1,]     57     98     37
[2,]     88     84    122


列表

> student <- list(nro = 34453, name = "Marie", scores = c(9.8, 5.7, 8.3))
> student[[1]]
[1] 34353
> student$nro
[1] 34353


数据框(表示数据库表格)

> scores.inform <- data.frame(nro = c(2355, 3456, 2334, 5456),
+ team = c("tp1", "tp1", "tp2", "tp3"), 
+ score = c(10.3, 9.3, 14.2, 15))
> scores.inform
    nro    team   score
1  2355     tp1    10.3
2  3456     tp1     9.3
3  2334     tp2    14.2
4  5456     tp3    15.0
> scores.inform[score > 14,]
    nro    team   score
3  2334     tp2    14.2
4  5456     tp3    15.0
> team
[1]  tp1  tp1  tp2  tp3
Levels:  tp1  tp2  tp3


条件语句

> if (x > 0) y <- z / x else y <- z
> if (x > 0) {
+    cat('x is positive.\n')
+    y <- z / x
+} else {
+    cat('x isn't positive!\n')
+    y <- z
+}


case 语句

> sem <- "green"
> switch(sem, green = "continue", yellow = "attention", red = "stop")
[1] "continue"


循环语句

> x <- rnorm(1)
> while (x < -0.3) {
+    cat("x=", x, "\t")
+    x <- rnorm(1)
+  }

> text  <-  c()
> repeat  {
+   cat('Type a phrase?  (empty to quit) ')
+   fr  <-  readLines(n=1)
+   if  (fr  ==  '')  break  else  texto  <-  c(texto,fr)
+}

> x <- rnorm(10)
> k <- 0
> for(v in x)  {
+   if(v > 0)
+     y <- v
+   else y <- 0
+     k <- k + y
+  }


创建和调用函数

> cel2far <- function(cel) {
+   res  <-  9/5  *  cel  +  32
+   res
+ }
> cel2far(27.4)
[1]  81.32
> cel2far(c(0,  -34.2,  35.6,  43.2))
[1]  32.00  -29.56    96.08  109.76

参考文献

[编辑 | 编辑源代码]
  1. a b c d J. Han, H. Pei 和 Y. Yin. 无候选生成挖掘频繁模式。在:Proc. Conf. on the Management of Data (SIGMOD’00, Dallas, TX)。ACM Press, New York, NY, USA 2000.
  2. Agrawal, R. 和 Srikant, R. 1994. 挖掘关联规则的快速算法。在 Proc. 1994 Int. Conf. Very Large Data Bases (VLDB’94), Santiago, Chile, pp. 487–499.
  3. Agarwal, R., Aggarwal, C. 和 Prasad, V.V.V. 2001. 一种用于生成频繁项集的树投影算法。Journal of Parallel and Distributed Computing, 61:350–371.
  4. a b B.Santhosh Kumar 和 K.V.Rukmani. 使用 APRIORI 和 FP Growth 算法实现 Web 使用挖掘。Int. J. of Advanced Networking and Applications, Volume: 01, Issue:06, Pages: 400-404 (2010).
  5. a b c d e Cornelia Gyorödi 和 Robert Gyorödi. 关联规则挖掘算法的比较研究。
  6. a b c d e f F. Bonchi 和 B. Goethals. FP-Bonsai: 小型 FP-树的生长和修剪艺术。Proc. 8th Pacific-Asia Conference on Knowledge Discovery and Data Mining (PAKDD’04, Sydney, Australia), 155–160. Springer-Verlag, Heidelberg, Germany 2004.
  7. M. Zaki, S. Parthasarathy, M. Ogihara 和 W. Li. 快速发现关联规则的新算法。Proc. 3rd Int. Conf. on Knowledge Discovery and Data Mining (KDD’97), 283–296. AAAI Press, Menlo Park, CA, USA 1997.
  8. Christian Borgelt. 保持简单:通过递归消除寻找频繁项集。Workshop Open Source Data Mining Software (OSDM'05, Chicago, IL), 66-70. ACM Press, New York, NY, USA 2005
  9. a b c Aiman Moyaid, Said 和 P.D.D., Dominic 和 Azween, Abdullah。FP-growth 变体的比较研究。international journal of computer science and network security, 9 (5). pp. 266-272.
  10. Liu,G. , Lu ,H. , Yu ,J. X., Wang, W. 和 Xiao, X.. AFOPT:模式增长方法的有效实现,在 Proc. IEEE ICDM'03 Workshop FIMI'03, 2003.
  11. Grahne, G. 和 Zhu, J. 使用 FP-树进行频繁项集挖掘的快速算法。IEEE Transactions on Knowledge and Data Engineer,Vol.17,NO.10, 2005.
  12. a b c d e Gao, J. 新关联规则挖掘算法的实现。Int. Conf. on Computational Intelligence and Security ,IEEE, 2007.
  13. a b c d e Cornelia Gyorödi, Robert Gyorödi, T. Cofeey 和 S. Holban. 使用动态 FP-树挖掘关联规则。在 The Irish Signal and Systems Conference 的论文集,利默里克大学,利默里克,爱尔兰,2003 年 6 月 30 日至 7 月 2 日,ISBN 0-9542973-1-8,第 76-82 页。
  14. a b c F. Bonchi, F. Giannotti, A. Mazzanti 和 D. Pedreschi. Exante:约束模式挖掘中的预期数据减少。在 Proc. of PKDD03。
  15. a b c d Balázes Rácz. Nonordfp:一种无需重建 FP-树的 FP-Growth 变体。第二届国际频繁项集挖掘实现研讨会 FIMI2004。
  16. a b c d Grahne O. 和 Zhu J. 在频繁项集挖掘中有效地使用前缀树,在 Proc. of the IEEE ICDM Workshop on Frequent Itemset Mining,2004。
  17. a b Jiawei Han 和 Micheline Kamber,数据挖掘:概念与技术。第二版,Morgan Kaufmann,2006。
  18. M. Zaki 和 W. Meira Jr. 数据挖掘算法基础,剑桥,2010(待出版)
  19. a b c Grahne, G. 和 Zhu, J. 使用 FP-树进行频繁项集挖掘的快速算法。IEEE Transactions on Knowledge and Data Engineer,Vol.17,NO.10, 2005.
  20. a b c d Z. H. Deng 和 Z. Wang. 一种用于挖掘频繁模式的新型快速垂直方法 [1]。International Journal of Computational Intelligence Systems, 3(6): 733 - 744, 2010.
  21. a b c d Z. H. Deng, Z. Wang 和 J. Jiang. 一种使用 N-List 快速挖掘频繁项集的新算法 [2]。SCIENCE CHINA Information Sciences, 55 (9): 2008 - 2030, 2012.
  22. a b c d Z. H. Deng 和 S. L. Lv. 使用 Nodesets 快速挖掘频繁项集 [3]。Expert Systems with Applications, 41(10): 4505–4512, 2014.
  23. a b W. N. Venables, D. M. Smith 和 R Development Core Team. R 简介:R 笔记:用于数据分析和图形的编程环境。版本 2.11.1 (2010-05-31)。
  24. a b c d R Development Core Team. R 语言定义。版本 2.12.0 (2010-10-15) 草案。
  25. a b R Development Core Team. 编写 R 扩展。版本 2.12.0 (2010-10-15)。
  26. a b Michael Hahsler 和 Bettina G 和 Kurt Hornik 和 Christian Buchta. arules 简介 – 用于挖掘关联规则和频繁项集的计算环境。2010 年 3 月。
  27. a b R Development Core Team. R 安装和管理。版本 2.12.0 (2010-10-15)。
  28. a b c Luís Torgo. R 编程入门。经济学院,波尔图大学,2006 年 10 月。
  29. a b Sigal Blay. 从 R 调用 C 代码入门。统计学和精算科学系 西蒙弗雷泽大学,2004 年 10 月。
  30. a b Christian Borgelt. FP-growth 算法实现. 开源数据挖掘软件研讨会 (OSDM'05,芝加哥,伊利诺伊州),1-5. ACM 出版社,纽约,纽约,美国 2005 年。
华夏公益教科书