LCM:线性时间闭合项集Miner

由Takeaki Uno编码,电子邮件:uno@nii.jp,
主页:http://research.nii.ac.jp/~uno/index.html


这个程序基本上只用于学术用途。任何人都可以修改这个程序,但他/她必须在源代码的顶部写下修改的更改。无需联系或预约Takeaki Uno。如果要重新分发此代码,请不要忘记引用最新代码,并显示Takeaki Uno主页的链接,以通知用户有关代码的新闻。出于商业目的,请联系Takeaki Uno。


问题定义
用法
输入文件格式
对变量和其他格式使用通用名称
简单的批处理文件
输出格式
性能
解决其他问题
频繁项集挖掘简介
算法和实现问题
致谢
工具书类


问题定义

让我成为一组项目。项集是I的子集。设D是事务数据库,使得每个记录(称为事务)都是项集。项集的频率是包括项集的事务数。对于给定的数量t(称为支持),如果一个项集的频率不小于t,则称其为频繁项集。如果一个频繁项集不包含在其他频繁项集中,则称它为最大频繁项集;如果它不包含在同一频率的其他项集,则称之为闭合频繁项集。该程序LCM的任务是枚举(输出或计数)给定事务数据库中给定支持的所有频繁项集、所有最大频繁项集或所有频繁关闭项集。


用法

====如何编译====

将文件解压缩到任意目录,然后执行“make”。然后您可以在同一目录中看到“lcm”(或lcm.exe)。在ver.2xx和3的情况下,您可以看到fim_all、fim_closed和fim_maximal。

====版本2xx和版本3的命令行选项====

参数格式遵循FIMI实现。(http://fimi.cs.helsinki.fi/)
要枚举频繁项集,请执行fim_all。对于频繁闭合项集,执行fim_closed;对于最大频繁项集,执行fim_maximal。第一个参数是输入文件名,第二个是最小支持,第三个是输出文件名。我们可以省略第三个参数,这样就不会生成输出文件,程序会计算解决方案的数量。

示例)
%fim_closed输入文件名支持[输出文件名]

====版本4和版本5的命令行选项====

要执行LCM,只需键入LCM并按如下所示给出一些参数。

%lcm[命令][选项]输入文件名支持[输出文件名]

键入时不需要“%”。它是表示命令行的符号。要查看简单的解释,只需执行不带参数的“lcm”即可。

“input-filename”是输入事务数据库的文件名。输入文件名的第一个字母不得为“-”。否则,它将被视为一种选择。输入文件格式如下所示。“支持”是指对给定频率阈值的支持。“output-filename”是写入程序找到的项集的文件名。您可以省略输出文件,以仅查看数据库中的频繁项集数。如果输出文件名为“-”,则解决方案将输出到标准输出。

第一个参数[命令]由一些字母组成,并提供给程序以指示任务。

F:枚举频繁项集,
C:枚举关闭的频繁项集
M:枚举最大频繁项集

例如,如果要枚举最大频繁项集,请在第一个参数中键入“M”。此外,我们可以提供以下命令来指定输出样式:

q:没有输出到标准输出(包括消息w.r.t.输入数据)
i:不将项集输出到输出文件(只编写规则)
f:输出找到的每个项目集末尾的频率,
Q:输出找到的每个项目集头部的频率,
A:输出正/负频率,和(频率)/(绝对
频率);正/负频率是
分别具有正/负权重的事件。
绝对频率是
事件。
s:输出置信度和项目频率的绝对值;默认情况下,
它们是按比例写的,但通过这个命令,它们是由
#笔交易/交易权重之和
I:包括每个项目集的事务的输出ID;的ID
事务由事务所在的行数给出
已写入。ID从0开始。
R:为规则挖掘输出冗余项
通常,人们可能会认为
不影响频率,不需要信心
因此,LCM从
规则挖掘中的项集。此命令禁用此
函数,因此要输出的项集将与
通常的项目集挖掘。
V:显示计算进度
t:转换数据库,使项目i成为事务i,因此
如果项目i包含在j-th事务中,那么项目j将是
包含在i-th交易中。

输出格式解释如下。以下选项用于限制要找到的项集。我们可以在第一个参数和第二个参数之间键入它们。当然,选项可以是空的。

-l,-u[num]:枚举大小至少为/most[num'的项集
-U[num]:枚举频率最多为[num'的项集
-w[filename]:从文件读取事务权重(版本4和5)
itemset的频率将是事务权重的总和
其中包括项目集。
-c[文件名]:读取项之间的约束图(5.2版)
-C[文件名]:读取项之间的非约束图(5.2版)

以下选项仅适用于5.x版。

-m,-m[文件名]:读/写项从/到文件的顺序[文件名】
-K[num]:输出[num]-第个最大频率(闭合/最大)的频率
项目集(仅适用于版本5)。注意,它只输出频率,
因此不会输出任何项集
-S[num]:输出[num]solutions后停止
-,[char]:给出输出中数字的分隔符
输出文件中的数字由给定的
字符[char]。
-Q[文件名]:替换输出编号
根据文件中写入的排列表
[文件名],替换输出中的数字。中的数字
文件可以由任何非数字字符分隔,例如换行符
字符。
-f,-f[ratio]:输出频率[比率]乘以更小/更大的项集
而不是独立;设p是
项集中所有项i的(i)/(#事务的频率)。
-i[num]:查找项目[num'的关联规则;输出表单的所有规则
{1,3,5}=>[num]。输出规则的标准可以由其他
选项。
-a,-a[ratio]:找到至少[rato]的置信关联规则;一个
{1,3,5}=>2的关联规则将被输出,如果
{1,3,5,2}不小于/不大于{1,35}的频率乘以[比率]。
-r,-r[ratio]:至少查找关系可信度的关联规则
[比率];如果
{1,3,5,2}的频率不小于/不大于{1,35}的
次数({2}/(数据库中的事务数)的频率)乘以[比率]。
-p,-p[num]:仅当(频率)/(绝对)时输出模式项集
频率)不小于/不大于[num]。绝对频率是
模式项集出现次数的绝对权重之和。
-n,-n[num]:仅当其负频率为
不小于/不大于[num]。负频率是
权重为负的事件的权重
-o,-o[num]:仅当其正频率为
不小于/不大于[num]。正频率是
具有正权重的事件的权重

-l、 -u和-u指定项集/频率的上限/下限。超出上限/下限的项集将不会输出。当我们给出-S选项和数字X时,如果找到X个解,即使有更多的解,程序也会终止。

如果我们指定“-w”和文件名,那么LCM将读取该文件作为事务的权重数据库。文件的第i行被视为第i个事务的权重。使用事务权重,LCM查找项目集,使得包含项目集的事务权重之和不小于支持值。权重可以是实数。对于版本5,我们可以给出负权重。

“-c”和“-c”选项(仅适用于版本5):“-c“选项用于提供项目约束。在不能与一起包含在频繁项集中的两个项之间给出了项约束。换句话说,如果为项1和2给定了项约束,则{1,2}不能包含在任何频繁项集中。项目约束集形成一个无向图。因此,LCM通过图形输入项目约束。“-c”后面的文件名被视为图形文件。图形文件的格式如下所示。相反,“-C”选项用于提供“un-constraint”项目对。确切地说,当我们给出“-C”选项时,项1和项2之间的项约束意味着{1,2}可以包含在频繁项集中。也就是说,如果没有为项1和2给定项约束,则对{1,2}不能包含在任何频繁项集中。“-C”选项的非约束也由图形给出,其格式与“-C”选项相同。

如果我们指定“-w”和文件名,那么LCM将该文件作为事务的权重数据库读取。文件的第i行被视为第i个事务的权重。使用事务权重,LCM查找项目集,使得包含项目集的事务权重之和不小于支持值。权重可以是实数。对于版本5,我们可以给出负数。

当我们给出-K选项时,LCM计算第[num]个最大频繁(闭合/最大)项集的频率,并将其输出到标准输出(打印到命令行)。通过向LCM提供输出频率,我们可以枚举top-[num]频繁项集(闭合或最大)。

示例)

-在“test.dat”中查找支持4的所有频繁项集,大小为
不少于3,找到每个项目集的输出频率,不要
输出到文件,显示进度,如果1000000个解决方案
被发现;

%lcm FfV-l 3-S 1000000测试.dat 4

-在“test.dat”中查找频率至少为6的闭合项集,大小
从5到10,输出项集到“out.dat”;

%lcm C-l 5-u 10测试.dat 6 out.dat

-用权重文件在test.dat中查找最大频繁项集
频率至少为8的“weight.dat”,输出到“out.dat”
事务ID,标准输出无输出;
    
%lcm MqI-w重量.dat测试.dat 8 out.dat

-指定项目约束文件g.grh,用于“test.dat”,频率为

至少3个,输出out.dat;

%lcm F-c g.grh测试.dat 8 out.dat

当给出-m、-m[文件名]选项时,LCM从[文件名]/到文件读取/写入项目排列。LCM内部排列项目以进行有效计算,此选项用于将排列强制为指定的排列,或了解排列。文件格式只是一个索引列表,例如,如果0,1,2,3将为2,1,0,3,则文件为

2
1
0

[终止]

对于排列未写入文件的项目,LCM确定其内部索引。

-f和-f选项用于查找关系频率较高的项集。对于每个项目i,让我们考虑({i}的频率)/(D中的事务数)作为项目i包含在事务中的外观概率。如果每个项目的出现概率彼此独立,则项目集S的频率应为其项目出现概率乘以(D中的事务数)的乘积。我们在这里通过以下公式定义S的相关频率
(S的频率)/(S的预期频率)。当我们给出-f[num]选项时,LCM输出的频繁项集的关系频率不小于[num]。类似地,当给定-F[num]选项时,会输出关系频率不大于[num]frequentitemset。

当给定-n/-n[num]选项时,LCM仅输出频率至少/最多[num]为负的项集。项目集S的负频率是包含S且具有负权重的事务的权重之和。同样,定义了S的正权重。当给定-o/-o选项时,LCM仅输出具有正权重的项集。

-p/-p[比率]选项用于评估绝对频率比率。项目集S的绝对频率是包括S在内的事务的绝对权重之和,绝对频率比由S的频率除以S的绝对频度得出。当给定-p/-p选项时,LCM仅输出绝对频率比至少为/最大为[比率]的项目集。

上述三种选项可用于查找新兴项集。对于两个数据库D1和D2,新出现的项集是在D1和D1中具有完全不同频率的项集,即在一个数据库中具有较大频率,而在另一数据库中具有较小频率。有几种模型可以定义新兴项集,例如(a)D1和D2之间的频率差至少是给定的阈值s,(b)D1中的频率比D2中的频度至少是s,依此类推。如果我们给a的每个事务赋予正权重,给b的每个事务赋负权重,定义为(a)的新兴项目集具有较大的频率,而定义为(b)的新兴项集具有较大或较小的绝对频率比-n/-n、-o/-n选项可用于修剪D1或D2中频率太小或太大的项集。

选项-m/-m[文件名]用于控制输出项集的顺序。在计算频繁项集之前,LCM根据项目频率的降序对项目进行排序,并按词汇顺序查找频繁项集-M选项将此顺序输出到文件。文件的格式只是顺序中的一系列项。m选项不是使用频率排序,而是从文件中输入项目排序。输入文件格式与-M选项的格式相同,但它接受任何非数字分隔符。使用这些选项,您可以控制查找频繁项集的顺序,这些频繁项集可用于比较不同数据库中的频繁项集集。

其余选项用于关联规则挖掘。关联规则是一对项集S和形式为“S=>x”的项x。该规则的置信度是包含x的事务在包含S的事务集中的比率。如果置信度高,我们可以说包含S的一个事务可能包含x的概率很高。其余选项用于以较高或较低的置信度枚举所有此类关联规则

-a[比率]和-a[比率]选项用于指定置信度的阈值。当给定-a选项和[ratio]时,LCM会找到至少具有[ratio].置信度的所有关联规则。相反,当我们给出-A选项时,可以找到置信度最高的关联规则。

-r[比率]和-r[比率]选项也用于指定阈值,但阈值会根据每个项目的频率而变化。准确地说,当我们给出-R和[ratio]时,如果关联规则的置信度不大于,则输出关联规则S=>x
[比率]*({x}/#事务的频率),
因此,只有当置信度与数据库中x的频率相比很小时,它才会输出。相反,当我们给出-r和[ratio]时,如果(1-其置信度)不大于[ratio]*(1-{x}的频率),则输出关联规则S=>x。

当给定-i[num]选项时,LCM仅查找表单规则
S=>[num]([num'是一个项目)。

示例)
-查找所有关联规则“A=>b”,使A的频率不低于
小于200,置信度不小于0.9。输入文件是
“test.dat”,输出文件为“out”。

%lcm C-0.9测试.dat 200输出

-查找所有关联规则“A=>b”,使A的频率不小于
大于200,信心不大于
0.1*({x}/#事务的频率)。项目b被指定为项目5。
输入文件是“test.dat”,输出文件是“out”。

%lcm C-R 0.1-i 5测试.dat 200输出


输入文件格式

输入文件的每一行(行)都是一个事务。交易中包含的项目列在一行中。项目必须是从1开始的数字。它们不可能是负数。项目编号不必是连续的,但请注意,程序在最大项目编号中以线性方式占用内存。数字分隔符可以是任何非数字字母,例如“,”“”:“a”等。

示例)(“[EOF]”是文件的末尾)
0 1 2
1
2 3 4
4,1 2 3
2,1
[终止]

项目约束(或补充)图的文件格式如下。文件的第i行(行)对应于节点i-1。第一行对应节点0,第十行对应节点9。大于i-1且与i-1相邻的节点列在第i行中。节点由数字表示。数字的分隔符可以是“,”,但图形加载例程接受分隔符的任何字母,但不接受数字、+和-。如果边集是{(0,1),(0,2),(1,1),(1.3),(2,3)},文件将是
===========
     1,2
1 3个
     3
    
[终止]
=========
其中“[EOF]”是文件结束的符号。


对变量和其他格式使用通用名称

我们可以将一般字符串中的变量名转换为数字,以便通过一些脚本文件将数据输入到程序中。

-排序<输入文件>输出文件
按字典顺序对文件进行排序。它用于对输出文件进行排序。

-transnum.pl表格文件[分隔符]<输入文件>输出文件
从标准输入中读取文件,并为由通用字符串(如ABC、ttt)写入的每个名称指定一个唯一的数字,然后将每个字符串名称转换为一个数字,并将其输出到标准输出。从字符串名称到数字的映射输出到table-file。字符串名称分隔符的默认字符是“”(空格)。可以通过为选项[分隔符]指定一个字符来更改它。例如,A,B是一个字符串名,如果分隔符是空格,但如果我们将分隔符设置为“,”,它将被视为两个名称A和B。这由“transnum.pl table-file”、“<input-file…”执行。

-untransnum.pl表格文件<输入文件>输出文件
根据transnum.pl的table-file输出,将数字转换为字符串名称。程序的输出是由数字组成的,因此,如果我们想转换为原始字符串名称,可以使用它。它从标准输出读取文件,并输出到标准输出。

-appendnum.pl<输入文件>输出文件
当我们想区分不同列中的相同单词时,请使用此脚本。这会将列编号附加到每个单词,以便我们可以区分它们。然后,通过使用transnum.pl,我们将字符串转换为数字。

-转置.pl<输入文件>输出文件
转置文件。换句话说,将文件视为邻接矩阵,并输出转置矩阵,或交换项目和事务的位置。对于输入文件,输出其中第i行对应于项目i并且包括数字j的文件,使得i包括在输入文件的第j行中。

-01conv.pl[分隔符]<输入文件>输出文件
将以01矩阵样式编写的事务数据库转换为我们的输入样式。文件必须是由0和1组成的列表,用[分隔符]分隔。如果省略[分隔符],则使用默认分隔符“”。


简单使用的批处理文件

对于一般字符串名称,我们有几个基本用法的批处理文件脚本“exec_lcm”、“exec_lcm_”、“sep_lcm“或”sep_lecm_“。例如,当具有“通用项名称”的数据库为时,

狗、猪、猫
猫鼠
猫鼠狗猪
牛马
马鼠狗
[终止]

所有这些都用数字替换输入数据库中的字符串,执行LCM,并用原始字符串替换输出文件中的数字。脚本的用法是

%exec_lcm[commands]输入文件名支持输出文件名[options]

您必须在第一个参数中给出命令,但选项必须位于末尾。项目的分隔符为“”(空白,空格)。如果要使用其他字符作为分隔符,请使用“sep_lcm”。用法是

%sep_lcm分隔符[命令]输入文件名支持输出文件名[选项]

几乎与“exec_lcm”相同,但必须在第四个参数处指定分隔符。“exec-lcm”和“sep_lcm”都是为了区分不同列中的相同项。例如,它用于数据库,使得不同的项位于不同的列中,但一些特殊符号,例如“-表示缺少数据”,通常被使用。一个例子是;

一个真正的小
B-真-
C假中间
B--
C-中间
一个真实的-
[终止]

在输出文件中,项目后跟“.”和数字,其中数字是列编号。例如,“dog.0”表示第0列(第一列)上的项目“dog”。

它们的用法分别与“exec_lcm”和“sep_lcm“相同。所有这些脚本都使用名为“__tmp1_”、“__tmp 2_”和“__ttp3__”的文件。执行后,这些名称的文件将被删除。

示例)

%exec_lcm F test2.dat 10 out.dat-w weight.dat-l 2

%sep_lcm_“,”C test3.dat 3 out.dat-U 5


输出格式

当程序执行时,程序将打印出输入数据库的#items、#transactions和其他特性,显示为标准错误。枚举结束后,它输出找到的项集总数(频繁/闭合/最大项集)以及每个大小的项集数。例如,如果有4个大小为1的频繁项集、2个大小为3的频繁项集中和1个大小为三的频繁项集合,则标准输出的输出将为,

9<=频繁项集总数
1<=#大小为0的频繁项集(空集),总是频繁的
4<=#大小为1的频繁项集
3<=#大小为2的频繁项集
1<=#大小为3的频繁项集

如果第一个参数中给出了“q”,则这些参数不会出现在标准输出中。

如果给定了输出文件名,则找到的项集将写入输出文件。输出文件的每一行是包含在找到的项集中的项的列表,以“”分隔。通过提供“-,”选项,我们可以更改分隔符。如果第一个参数中给定了“f”,频率将跟随每个项目集,例如,

1 5 10 2 4 (22)

这意味着项目集{1,2,4,5,10}包含在22个事务中。当给出“Q”选项时,输出将为

(22) 1 5 10 2 4

输出项集未排序。如果要对其进行排序,请使用脚本“sortout.pl”。用法是,

%sortout.pl<输入文件>输出文件

“input-file”是LCM输出到的文件的名称,排序后的输出将写入名为“outputfile”的文件中。每个项目集的项目将按照项目的递增顺序进行排序,所有项目集(行)也将按照字典顺序进行排序(视为字符串)。(实际上,您可以指定类似sortout.pl“,”的分隔符)。

关联规则S=>x,例如{1,2,3}=>5以如下形式输出

[xxx yyy]5<=1 2 3

其中xxx是规则的置信度,yyy是
(y的频率)/D中的交易次数。


性能

LCM的性能在计算时间和内存使用方面都是稳定的。LCM的初始化和预处理时间与输入数据库的大小成线性关系。查找频繁项集的计算时间取决于找到的项集数量和最小支持。当最小支持度较大且找到的项集数量较少时,每个项集的计算时间相对较大。但是,每个项集合的计算时间随着找到的项集合的增加而减少,粗略地说,当输出文件的大小等于输入数据库的大小时,它将是恒定的,例如1/1000000秒(通过CPU为2GHz的PC)

LCM的内存使用非常稳定。与其他实现相比,这是一个优势。LCM的内存使用量在输入数据库的大小上总是线性的。大约LCM使用的整数最多是数据库大小的三倍,数据库大小是每个事务的项目数之和。其他实现的内存使用量随着频繁项集数量的增加而增加,但LCM的内存使用率没有增加。


解决其他问题

-二部图中最大二部团的计数-

枚举二部图中所有最大二部团相当于枚举所有闭项集。LCM可用于此任务。对于由两个顶点集a和B组成的二部图,构造数据库,使每条线都是a中某个顶点的顶点列表。然后,通过执行

%lcm CI输入文件名1输出文件名

你可以列举最大的二部集团。

-图中最大二部团的计数-

通过对图的变换,我们可以枚举图中的二部团。对于给定的G=(V,E),我们构造了一个图G'=(V+V',E'),其中V'是V的副本。如果边(V,u)在E中,那么在E'中,V的顶点V和V'中的顶点u通过边连接,V的顶点u和V'中的顶点V通过边连接。那么,G'是一个二部图,G'中的二部团是G中的二部分团,反之亦然。因此,将G’赋给LCM,我们可以枚举一般图中的所有最大二部团。

-有向图中最大有向二部团的计数-

对于有向图G=(V,a),一个有向二部团是顶点集B和C,这样对于B中的任意一对顶点B和C中的任何一对顶点,都有一条从B到C的弧。与上面类似,我们构造了一个有向图G'=(V+V',a'),其中V'是V的副本。如果一条弧(V,u)在a中,则在a'中,有一条边连接v的顶点v和A'中v'中的顶点u。那么,G'是一个二部图,G'中的二部团是G中的有向二部团,反之亦然。因此,将G’赋给LCM,我们可以枚举一般图中的所有最大二部团。

-查找具有大交集的事务对-

假设我们想查看哪一对事务具有许多公共项,即对于阈值t,我们想找到所有事务a和B对,以便在a和B中至少包含t项。为此,使用-l 2和-u 2执行lcm,例如,

lcm F-l 2-u 2测试.dat 20

然后,我们可以找到所有具有至少20个公共项的成对事务。

-挖掘“itemset”集合。
考虑一个数据库,每个数据库的记录都是一组项集(事务数据库)。当且仅当S的每个项集包含在R中的某个项集中时,记录R中包含项集S。注意,R的项集可能包含多个S的项集。这里的问题是枚举包含在给定数据库的θ记录中的所有项集。当我们对要枚举的模式S中的项集的大小进行限制时,比如说最多可以枚举一些小k,我们可以使用LCM来解决这个问题。通过列出记录中至少一个项目集中包含的所有项目集,并将列出的每个项目集视为一个项目,将数据库的每个记录转换为一个项集。

例如,一个项目集{A,B,C}被认为是一个项目“{A,B,C}.”。获得的数据库中的频繁项集对应于频繁项集集。它们一一对应。此外,通过枚举封闭项集,我们可以自动忽略不必要的模式。如果一个频繁项集包含一个项{a,B,C},对应于原始问题中的项集{a,B,C},那么在不改变频率的情况下,我们可以将任何对应于{a,C,}子集的项添加到该项集。闭项集总是包含这样的子集,因此闭项集是由一组项集给出的,因此任何两个项集都不满足包含关系。因此,我们可以自动丢弃不必要的模式。


频繁项集挖掘简介

假设D是一个数据库,这样每个记录都是事务数据。这里的交易数据是一组项目。因此,数据库是一组项目子集。这样的数据库称为“事务数据库”。

例如,让我们查看以下事务数据库:

事务A:1,2,5,6,7
事务B:2,3,4,5
事务C:1,2,7,8,9
事务D:1,7,9
事务E:2,7,9
事务E:2,7,9
事务F:2

事务A是一组项目1、2、5、6和7,其他项目依此类推。现在我们考虑一个问题,即查找包含在许多事务中的项目集,因为这些集合给出了一些有趣的数据库结构。由于“许多事务”没有定义明确,我们引入了一个称为“最小支持”或简称为“支持”的数字,并认为至少包含在“最小支持”事务中的项集包含在许多事务中。我们将此类项集称为“频繁项集”,并将包括项集的项集在内的事务数称为“频率”。对于上述事务数据库,通过将最小支持设置为3,频繁项集为

{}、{1}、}、2,7}、9}、1,7}和1,9}。
  
请注意,第一个项集是空集,它被视为频繁项集。如果支持较大,则#frequency项集较小。频繁项集的数量随着支持的减少而增加。

频繁项集挖掘的一个常见用法是从数据库中查找有趣的知识。从这个意义上说,大的支持通常会提供琐碎的频繁项集,这并不有趣。另一方面。当我们将最小支持设置为一个较小的数字时,频繁项集的数量将非常巨大。处理庞大的项目集本身就是一项艰巨的任务。因此,接下来我们考虑如何减少要找到的项集的数量,而不丢失有趣的知识。

这个任务的一种方法是只找到最大频繁项集,而不包括在其他频繁项集中。例如,上述数据库中的最大频繁项集为

{1,7}、{1,9}和{2,7,9}。

其思想是,任何频繁项集都包含在至少一个最大频繁项集中,至少我们可以从最大频繁项集中得到该项集。然而,我们不知道他们有多频繁。例如,{2,7}可以从{2,7,9}中获得,但我们不知道{2,7{是否比{2,7,19}更频繁。从这个意义上说,我们错过了每个频繁项集的有趣程度。

使用封闭项集,我们可以避免这个问题。如果某个项集不包含在相同频率的其他项集中,则该项集将被关闭。例如,在上述数据库中,关闭的项集为

   {}, {2}, {2,5}, {7,9}, {1,7,9}, {2,7,9}, {1,2,7,9}, {2,3,4,5},
{1,2,7,8,9}和{1,2,5,6,7,9}。
  
如果支持度等于其频率,则闭项集是最大频繁项集。因此,封闭项集集合是所有可能支持的最大频繁项集的集合。任何非封闭项集都由一个封闭项集支配,因此我们不会损失频率。


算法和实现问题

该算法的基本思想是深度优先搜索。设D是事务数据库,t是最小支持,1,。。。,n为项目,T1,。。。,Tm是D.D(I)中的事务表示包含I的事务集。我们用尾部(I)表示项集I中最大的项。LCM首先计算由一个项目组成的每个项目集的频率。如果一个项集{i}是频繁的,那么枚举通过向{i}添加一个项而获得的频繁项集。通过这种方式,LCM递归地枚举所有频繁项集。为了避免重复,LCM仅当j>i时才将项目j添加到{i}。此算法如下所示:

频繁项集挖掘(D:数据库,I:项集)
输出I
对于每个项目j>尾部(I),
如果(I\cup j)是频繁的,那么FrequentItemsetMining(D,I\cup{j})

通过调用FrequentItemsetMining(D,emptyset),我们可以枚举所有频繁项集。

然而,该算法的直接实现非常缓慢,因为计算(I\cup{j})的频率需要很长时间。为了更快,我们使用条件数据库和事件交付,如下所示。

====项集I的条件数据库===
项目集I的条件数据库,用D(I)表示,由以下公式获得的数据库给出

     1. D(I):=包括I在内的所有交易
     2. 从D(I)的每笔交易中删除所有不必要的项目
     3. 将相同的事务合并为一个。
(对所有此类相同的交易执行此操作)

这里不必要的项目是令人满意的项目
(a)包含在D(I)的少于t笔交易中,
(b)包含在D(I)中的所有交易中,或
(c)少于I中最大的项目。
然后,在D和D(I)中,项集I加上J的频率是相同的,因此LCM在关于I的递归调用中使用D(I。

当递归很深时,构造D(I)可能会占用大量内存。因此,LCM进行了轻微修改。

     1. D(I):=包括I在内的所有事务的ID
     2. 如果存在事务T1,。。。,删除后Tk变为相同
不必要的项目,使新事务与之相等,并替换
T1的ID,。。。,按新交易的ID进行交易

在终止对I的递归调用后,我们删除了进程中生成的事务。这样,我们可以将事务的内存使用量绑定为数据库大小的两倍。由此,LCM在初始化时分配内存,在主例程中不再这样做。因此,内存使用非常稳定,并且非常快,因为在频繁项集挖掘实现中,内存分配的计算时间不小。

===发生交付===
设T是事务数据库(子集族),E={1,…,n}的子集集合,T(S)是T中包含子集S的事务(子集)集合。
我们假设每个事务都已排序。发生交付计算给定j的所有i>j的T(i),在时间上与大小之和呈线性关系。首先,对于我们计算T(i)的每个i,我们给出一个空桶。然后,对于t中的每个事务t,我们按项目的降序进行扫描,直到满足小于j的项目,对于每个项目i>j,将t插入i的桶中。扫描完所有事务后,i的桶为t(i)。当我们有T(S)并且想要计算所有i>tail(S)的T(S\cup{i})时,我们可以通过设置T:=T(S。为了检查当前项集是否为not的最大频繁项集,我们还使用了发生传递。如果没有项i使得S\cup{i}是频繁的,那么频繁项集S是最大频繁项集。

===闭项集挖掘===
为了枚举封闭项集,我们使用ppc扩展(保留前缀的闭包扩展)。对于项目集P,我们通过P中小于i的项目来定义P(i),闭项集P'称为P的ppc扩张当且仅当

(i) 对于某些i>core_i(P),P'=C(P\cup{i})。(ii)P(i)=P'(i)。

注意P’的频率小于P。证明了任何闭项集都是另一个唯一闭项集的ppc扩张。因此,二元关系ppc扩展产生一个根为C(空集)的根树。因此,从最小的封闭项集(通常是空集)开始,递归地找到所有i的ppc扩展,我们可以对根树执行深度优先搜索。P的闭包计算可以通过取包含P的事务的交集来完成,因此可以通过在T(P)的线性时间内发生交付来完成。

====扫描指针方法====
实际上,我们不必完全计算交点。我们在其中选择一个事务T,并检查T中是否存在包含在所有其他事务中的项目减去P。我们以项目递增的顺序跟踪T,当我们在T中遇到项目i减去P时,我们从头部跟踪其他事务,无论它们是否包含i。请注意,要检查T\set-nus P中的下一个项目j,我们可以从终止跟踪以进行检查i的位置开始其他事务的份额。这不会增加太多的计算时间,因为时间复杂性是相同的,通常我们只检查几个项目,并得出结论,该项目集不是子项。因此,我们可以很快地进行ppc检查。

=====位掩码方法======
此外,当项集的频率很小时,我们可以使用位操作,这样我们可以同时操作32或64位。假设项集I的频率frq(I)小于32。我们给出ID为0,1,2,4,。。。,2^{frq(I)}到Occ(I),这是I的出现集。让Occ的子集S的位掩码b(S)是S中出现次数的ID之和。对于包含在I的至少一次出现中的每个项目j,我们计算b(Occ,I\cup{j})。当我们计算I\cup{j}的闭包C(I\cup{j})时,不在I\cup{j}中的项e被包括在C(I\cup{j})中,当且仅当b(Occ(I\cup{e}))\cap b(Occ(I\cup{j}))=b(Occ(I\cup{j}))。这里\cap表示位字符串的和操作,两个数字被视为位字符串。这个操作可以在很少的步骤中完成,因此我们可以加快闭包计算。如果I\cup{j}是一个封闭项集,我们可以将位掩码用于I\cup{j}的ppc扩展。因此,我们不必在递归调用中重新计算位掩码。在实践中,当数据集稀疏且最小支持度较小(例如10)时,位掩码方法将算法的速度提高了2到3倍。

====封闭项集的递归修剪===
为了有效地计算封闭项集,我们还有一种技术。假设对于封闭项集I和项j,C(I\cup{j})不是I的ppc扩展,因为C(I\ cup{j})包含项e<j,而不是I。然后,我们可以看到任何ppc扩展I\cup{j'},j'<j,C。这意味着我们永远无法通过在递归中添加j来获得ppc扩展。这减少了ppc扩展的候选数量,因此减少了计算时间。
在实际应用中,当频繁闭项集的数量与频繁项集的数目相差较大时,该算法的速度大约提高2到3倍。

该算法的细节描述如下。

1.加载输入文件并初始化内存
-扫描文件,并针对每个项目i,统计交易数量,交易大小总和,frq(i),其中frq(i)=包括i的交易数量
-为T[][]分配指针数组(事务的2d数组),Occ[][](2d整数数组)
-为w[]分配内存(事务权重),为T[][]分配“buf”,为occ[][】分配occ_buf(buf的大小为||D||*2,occ_fuf的大小=||D| |,其中D是删除不经常出现的项目(项目i,frq(i)<th已删除))。Occ[i]的大小等于frq(i)
-将文件加载到缓冲区。如果既没有给出间隙也没有给出窗口约束,则跳过frq(i)<th的项目i,
将T[T]设置为指向“buf”中T[i]开头的指针,将“end mark”(大整数)放在每个T[]的最后一个
-按递增顺序对每个事务进行排序
-加载权重文件,或将事务权重设置为1
-通过基数排序查找相同的事务(使用Occ[][])
-将相同的事务统一为一个事务,并添加事务权重
-将occ设置为{0,1,…,#transactions-1}的数组
-分配大小#items的int数组“jump”
-调用LCM_seq(occ,#transactions,current end of buffer)

2.LCM(occ,ii,t_new,buf)
-呼叫交付(occ,ii),计算每个项目i<ii,occ中交易的交易权重总和(occ_w[i])和正交易权重(occ_pw[i]]),包括i。
(交付将“跳转”设置为occ_pw[i]或occ_w[i]=0的项目)
-在闭合/最大项集挖掘的情况下,而不是调用Delivery(occ,ii),调用Delivery[occ,“endmark”)

-在封闭/最大项集挖掘的情况下,如果存在项j>ii,则返回,j不在当前项集中,这样occ_w[j]=occ中的事务权重之和,occ_pw[j]=occ的正事务权重之总和
(这是对“保留前缀的闭包扩展”的检查)

-对于带有occ_pw[i]<th的跳转中的每个i,将occ_w[i]和occ_pw[i]设置为0,并从跳转中删除i
-如果occ中的事务权重之和>=th,(如果没有j>ii,在最大项集挖掘的情况下,j不在occ_w[j]>=th的当前项集中)输出项集,或规则
    
-如果jump_t=0,清除occ_w、occ_pw和jump,然后返回
    
-通过基数排序查找相同的事务,忽略不包含在“跳转”中的项目和大于ii的项目
-将上面检测到的相同事务创建一个新事务,并添加事务权重。
(创建的事务的缓冲区和ID从buf和t_new开始
将buf/t_new更新到缓冲区/ID末尾)
---在闭合项集挖掘的情况下,取要合并的事务后缀的交集
---在最大项集挖掘的情况下,计算要合并的事务后缀的并集,并计算每个项的权重(项i的项权重是包括i在内的要合并事务的权重之和)。
-替换occ中的“合并”事务,并将新创建的事务插入occ。

-调用Delivery(occ,ii)以计算occ_pw[i]>=th的每个项目i的occ[i]

-对于以递增顺序跳转的每个项目i,
调用LCM(Occ[i],t_new,buf)(注意t_new和buf已更新)
清除Occ[i],Occ_w[i]到0,Occ_pw[i]到0
结束
LCM结束

===交货如下

交付(occ,ii)
-对于每个交易t(以occ为单位)
-对于i<ii中的每个项目
(用于计算occpw和occw)
如果occpw[i]=0且occw[i]=0,则将i插入“jump”
将t的权重加到occw[i]上,如果权重为正,则加到occpw[i'上
(用于计算Occ[i])
如果occ_pw[i]>=th,则将t插入occ[i]
结束
结束
交货结束

===内存分配和加载事务如下所述。
这种数据存储方法在图形数据结构中被称为“前向星”。

   1. 为“buf”分配大小为#transactions的int数组+(frq(i)和frq(i)>=th的总和)
   2. 为T[][]分配大小为#transactions的指针(到int)数组
   3. buf’:=指向buf起始位置的指针,t=0
  
   4. while(不是文件末尾)
4.1将T[T]设置为指向buf'的指针
4.2从buf'开始,直到换行,将整数读取到内存
4.3在整数的尾部加上“结束标记”
4.4 buf’=“结束标记”旁边的位置,t=t+1
结束时


致谢

我们感谢日本国家信息学研究所的Ken Satoh、北海道大学的Hiroki Arimura对研究的贡献,感谢Asai Tatsuya Asai、Uchida Yuzo、Masashi Kiyomi对计算实验和编码的贡献。我们还要衷心感谢FIMI(频繁项集挖掘实施)的组织者之一Bart Goethal组织研讨会,此次研讨会提交了LCM的第一个版本,也是我们研究的开始。

LCM的部分研究得到了日本国家信息学研究所的联合研究基金以及日本教育、科学、体育和文化部的赠款(Monbu-Kagaku-Sho)的支持。

我们还要感谢赫尔辛基大学的伊尔波·莱蒂宁、桑乔、R.阿伦·库马尔、Sethu理工学院、普洛尔、泰米尔纳都、日本先进工业科学技术的筑田浩二、日本宽西高津大学的Yukinobu Hamuro、日本大阪府大学的Hiroyuki Morita、,三菱研究所的Yasuyuki Shirai、Sophia-Antipolis大学的Nicolas Pasquier、Giuseppe Rizzo和Payas Gupta为他们提供了错误报告。


工具书类

Bart Goethal,“FIMI存储库”,http://fimi.cs.helsinki.fi/(各种频繁项集实现、基准数据库、比较所有实现的计算实验,以及解释实现的论文,非常有用的站点)

Takeaki Uno、Masashi Kiyomi、Hiroki Arimura,LCM第3版:数组、位图和前缀树的协作用于频繁项集挖掘,关于频繁模式挖掘实施的开源数据挖掘研讨会,2005年8月/2005

Takeaki Uno,Masashi Kiyomi,Hiroaki Arimura,“LCM第2版:频繁/闭合/最大项目集的高效挖掘算法”,《IEEE ICDM’04研讨会论文集》,2004年11月1日,http://sunsite.informatik.rwth-aachen.de/Publications/CEUR-WS//Vol-126/

Takeaki Uno和Tatsuya Asai,Hiroaki Arimura和Yuzo Uchida,“LCM:枚举频繁封闭项目集的有效算法”,频繁项目集挖掘实现研讨会(FIMI'03),http://sunsite.informatik.rwth-aachen.de/Publications/CEUR-WS//Vol-90/

Takaki Uno、Tatsuya Asai、Yuzo Uchida、Hiroki Arimura,“枚举事务数据库中闭合模式的有效算法”,人工智能3245课堂讲稿(2004年《发现科学学报》),2004年10月4日