如何加速基于 Apriori 框架以仅生成关联规则,其结果(右手边)是数据集的一个元素?
Posted
技术标签:
【中文标题】如何加速基于 Apriori 框架以仅生成关联规则,其结果(右手边)是数据集的一个元素?【英文标题】:How to Speed Up the Apriori Framework Based On to Generate Only Association Rules Which Consequents (Right Hand Side) Are One Element of the Data Set? 【发布时间】:2018-03-01 11:26:03 【问题描述】:我有一个包含 600 000 行和 15 列的 csv 文件 "Col1, Col2 ... COl15"
。我想生成关联规则,其中只有右侧只有 col15 的值。我正在使用来自here的先验实现@
它以这种方式计算每个项目集的 minSupport :
oneCSet = returnItemsWithMinSupport(itemSet,
transactionList,
minSupport,
freqSet)
print "reached line 80"
currentLSet = oneCSet
k = 2
while(currentLSet != set([])):
print k
largeSet[k-1] = currentLSet
currentLSet = joinSet(currentLSet, k)
currentCSet = returnItemsWithMinSupport(currentLSet,
transactionList,
minSupport,
freqSet)
currentLSet = currentCSet
k = k + 1
def returnItemsWithMinSupport(itemSet, transactionList, minSupport, freqSet):
"""calculates the support for items in the itemSet and returns a subset
of the itemSet each of whose elements satisfies the minimum support"""
_itemSet = set()
localSet = defaultdict(int)
#print itemSet
for item in itemSet:
#print "I am here", list(item)
for transaction in transactionList:
if item.issubset(transaction):
freqSet[item] += 1
localSet[item] += 1
print "Done half"
for item, count in localSet.items():
support = float(count)/len(transactionList)
if support >= minSupport:
_itemSet.add(item)
return _itemSet
但是对于我拥有的许多行,这将花费很多时间,因为我希望 RHS 被限制为仅具有来自特定列 (Col15) 的值,我是否可以通过以某种方式减少频繁项集?另一种方法是在最后过滤规则,但它具有相同的时间复杂度。还是有其他一些实现/库可以帮助我加快速度?
【问题讨论】:
那是不是 Apriori 的正确实现。它错过了关键的优化,并且会非常缓慢。 @Anony-Mousse - 是的,我现在开始使用您回答中的想法来实施它。谢谢:) @n01dea - 感谢编辑标题。这更有意义 @Anony-Mousse,你知道先验算法的任何高效python实现吗?我尝试了 mlxtend,但它引发了 50 000 个事务的内存不足错误,5 000 个项目根本不被视为大型事务数据库 【参考方案1】:根据第 15 列中的值(即右侧 RHS)拆分数据集。因此,如果您在该列中有 5 个不同的值,您现在将获得 5 个数据集。删除最后一列,现在是不变的。
仅在其他列上计算频繁项集(非关联规则),通过 Apriori 对每个 子集(更快!)。但是你仍然需要一个比你链接的随机 github 版本更好的实现。它只需要 FIM,不需要规则!
将带有分区键的频繁项集组合成关联规则 (FIS -> RHS),并像关联规则一样使用您的首选指标进行评估。
这要快得多,因为它不会生成跨越多个 col15 键的频繁项集。在每个分区中,所有剩余数据都与您的目标相关。此外,它还适用于未修改 Apriori FIM 生成。
【讨论】:
我不明白。你能举个例子吗?我认为,使用这种方法,结果中缺少关联规则,其中包含省略列的先行频繁项集。 他不想要那些。他希望 col15 仅是 RHS。 是的,只有第 15 列的频繁项集作为关联规则的后件(右手边)。但是使用这种方法,频繁项的提取结果会出现缺陷。例如三笔交易(a, b), (a, c), (b)。支持率为 50%。频繁项集是(a), (b)。现在将省略第三个事务:(a, b), (a, c)。没有(b)。再次支持50%。频繁项集是 (a)。频繁项集 (b) 现在在频繁项集的提取结果中丢失。因此在关联规则的生成中缺少频繁项集(b)。 我从不建议省略最后一笔交易。您的示例中的第 15 列是什么? 好的。现在我明白了。 op 喜欢只有关联规则,其结果是一个特定元素别名列 15。不是一个特定事务的频繁项集的结果。但后来我认为有一种更流畅的方法可以加快频繁项集的提取。不是事先而是在先验框架内。请查看我的答案以获取更新。【参考方案2】:没有。没有办法加速先验框架的复杂性,以生成仅将数据集的一个特定元素作为结果的关联规则。但是你可以稍微加快计算时间。
先验框架由两个步骤组成。第一步是生成频繁项集。第二步是生成这些频繁项集的关联规则。为了加快框架,研究关联规则的生成几乎没有用处。先验算法的大部分复杂性在于频繁项集的提取。
先验算法通过以下方式提取频繁项集:
-
使所有项目唯一化
获取所有 1 个长度的频繁项集的唯一项
将这 1 个长度的频繁项集组合成 2 个长度的项集
获取这 2 个长度项集的所有 2 个长度频繁项集
将n个长度的频繁项集组合成n+1个长度的项集
得到那些 n+1 个项集的所有 n+1 个频繁项集
重复 5. 和 6. 直到 n+1 个组合项集中没有频繁项集可以退出
在生成的n+1 个长度频繁项集中,生成关联规则。关联规则的生成相当简单:
-
将频繁项集组合到关联规则中
根据置信度检查生成的关联规则
如果关联规则位于置信水平之上,则它是强关联规则,因此是有效关联规则
应该是所有生成的关联规则的结果的数据集元素在下面称为x。
为了加快计算的第一步是对第一步频繁项集的提取进行裁剪。在步骤 1.2 中是要从 1 长度频繁项集的结果集中删除的 1 长度频繁项集 (x)。如果在步骤 1.2 中元素没有被提取为频繁项集,则算法应该停止。因为这样就不会有与元素作为结果的关联规则。一条关联规则由n个长度的频繁项集组成。
因此步骤1的频繁项集提取的结果只包含那些n个长度的频繁项集,这些频繁项集适合作为一个关联规则的前件,其后件只能是(x)。这些是那些不包含 (x) 的频繁项集。这节省了计算时间,因为存在一个长度为 1 的频繁项集,如果该项集是频繁项集,则将组合其中的 n 个长度项集并根据支持度进行检查。
为了加快计算速度,第二步是对第二步关联规则的生成进行裁剪。在步骤 2.1 中仅生成关联规则,其结果为 (x)。关联可以形成为将频繁项集提取的结果,并将每个频繁项集作为前件,将(x)作为关联规则的后件。因此,关联规则应该是 ((n 长度频繁项集) -> (x))。
但要真正加快计算速度,请使用另一种算法来提取频繁项集。 fp-growth 算法已经快了很多。提取频繁项集的最快算法是最新的 prepost+ 算法。
one 是一个简洁的 Python 库,其中包含用于提取频繁项集的算法。
tl;dr:复杂性保持不变。计算时间可以得到改善。总体而言,应该使用另一种更快的算法,而不是像 fp-growth 这样的先验算法。
【讨论】:
实际上,有一种方法可以更快地做到这一点,因为“目标”列始终只有一个值。看我的回答。 如果答案的方法可行,我看不出这个方法会更快吗?请参阅我对您的回答的评论。据我了解您的回答,建议是在创建频繁项集时省略提到的一个特定库。除此之外,我认为这种方法会在结果中遗漏关联规则,复杂性时间是相同的。正如我所说,他应该使用另一种算法来提取频繁项集是毫无疑问的。 由于有分区,它会更快,因为它不再会在最后一列中找到没有值的频繁项集。 省略一列只会加快一点速度。复杂性保持不变。并且只提取不包括省略列的元素的频繁项集将导致错误结果。请查看我对您的回答的评论。 那个“小”位可能相当大。因为他有很长的交易(总是 15 列!)。它将事务的平均长度减少了 1,通常候选者的数量减少了 2 倍。并且分区进一步提供了帮助。以上是关于如何加速基于 Apriori 框架以仅生成关联规则,其结果(右手边)是数据集的一个元素?的主要内容,如果未能解决你的问题,请参考以下文章
第九章 数据关联规则分析算法——基于Apriori算法的关联项分析
R语言apriori算法进行关联规则挖掘(限制规则的左侧或者右侧的内容进行具体规则挖掘)使用subset函数进一步筛选生成的规则去除左侧规则中的冗余信息获取更独特的有新意的关联规则