【问题标题】:Generate candidate itemsets based on Apriori algorithm基于Apriori算法生成候选项集
【发布时间】:2021-05-24 20:12:36
【问题描述】:

我正在尝试实现 Apriori 算法。为此,我需要从长度为 k 的项集(作为字典 L 给出)生成长度为 k+1 的项集。在生成组合时必须遵循 Apriori 原则。原理说明:只有当其所有子集都存在于输入 L 中时,才能生成长度为 k+1 的集合。

我有一本字典,需要从中生成项集。

我目前的尝试是这样的:

import itertools as it
def generateItemsets(Lk,k):

    comb = sum(Lk.keys(), tuple())
    Ck = set(it.combinations(comb, k))
    return Ck

但是该函数需要永远并且在错误时被中断:IOPub data rate exceeded.

示例 1:

Input (dictionary): {(150,): 2, (160,): 3, (170,): 3, (180,): 3}

Output (set): {(150, 160), (150, 170), (150, 180), (160, 170), (160, 180), (170, 180)}

Update-1

数据集包含近 16000 笔交易。它看起来像这样:

[![数据集][1]][1]

唯一项的范围为 0-999

如你所见,这个函数将被赋予一个输入 L_k,它应该输出 C_k+1。 输入 L_k 是一个类似于 ({(301,350): 46, (966,970): 612, (310,350): 216, (548, 550): 457}) 的字典,而输出 C_k+1 应该是一个集合(例如:{ (250,350),(360,370),(380,390),...}

【问题讨论】:

  • 你检查过this库吗?
  • @Ashar 我只是将您在赏金评论中提供的解释添加到问题本身中。否则,问题可能会因为缺乏细节和清晰度而被关闭。
  • @KacperFloriański 添加了我当前的尝试并使其更加清晰
  • 对于 Apriori 算法,您需要一个包含项目的数据库和一个包含事务的数据库。你没有提供任何这些。您的代码尝试也相当不完整。要获得可靠的答案,您应该提供更多信息。
  • 我假设,您的函数的输入 k 是当前正在进行的事务,看起来类似于 Lk 的键之一,例如 (301,350)

标签: python apriori market-basket-analysis


【解决方案1】:

我不确定您究竟想要什么输入,因为您发布的列表如何符合 Apriori 算法的输入定义尚不清楚。
输入应该是交易列表、这些交易中的一个项目和一个数字,该数字表示与同一交易中的指定项目一起出现的某些项目的计数。
输出是已售出的商品列表以及指定商品的所需次数。
有几个库可以解决这类问题。用户 null 已经指出了一个好消息:https://github.com/tommyod/Efficient-Apriori。还有Apyori:https://github.com/ymoch/apyori.
这是求解 Apriori 算法的简单尝试。它可以复制到一个文件并用 Python 执行:

# list of transactions
sales = [
  ('eggs', 'bacon', 'soup'),
  ('eggs', 'bacon', 'apple'),
  ('soup', 'bacon', 'banana'),
]

# generate match dictionary of type {item: {count: {item, ...}, ...}, ...}
matches = {
  i: { 
    sum((i in z and j in z) for z in sales): set(
      k for t in sales for k in t
      if i!=k and
      sum((i in z and j in z) for z in sales) == sum((i in z and k in z) for z in sales)
    )
    for t in sales for j in t if i in t and j!=i
  }
  for t in sales for i in t
}

#print ( "match counts: %s\n" % (matches) )

print ( "best match(es) for eggs:", matches['eggs'][len(matches['eggs'])] )
# output: {'bacon'}
print ( "best match(es) for bacon:", matches['bacon'][len(matches['bacon'])] )
# output: {'eggs', 'soup'}

basket = ('soup', 'apple', 'banana') # consumer basket

# calculate a list of best matches for new sales
best = set(sum([ list(matches[i][len(matches[i])]) for i in basket ], [])) - set(basket)

print ( "basket: %s, best matches: %s" % ( basket, best ) )
# output: {'bacon', 'eggs'}

上面的代码生成一个项目字典,其中包含包含两个项目的事务中某些项目的某些计数列表。对于庞大的事务列表,此字典的生成可能会很慢。但是您不必为每笔新交易计算这一点。相反,我会不时地每天重新计算匹配计数。
项目名称可以替换为项目索引来处理项目数据集。在这个例子中,字符串比数字更清晰。
一般来说,将慢速函数转换为数据集的嵌套字典是加快代码速度的好主意。类型的慢函数:

result = function ( parameter, parameter, ... )

可以转成嵌套字典和一个在较长时间后重新计算字典的函数:

if time < refresh:
  dictionary = precalc ( )
  refresh = time + rate
...
result = dictionary [ parameter ] [ parameter ] [ ... ]

此解决方案当然需要更多内存。

为了获得可靠的答案,您不应该对帖子投反对票,而应提供更大的代码块,这些代码可以复制到文件中并执行。您还应该提供明确的函数输入值。什么是 Lk 和什么是 k ? 根据您的问题,我假设以下程序不会输出您发布的错误:

import itertools as it
def generateItemsets(Lk,k):

    comb = sum(Lk.keys(), tuple())
    Ck = set(it.combinations(comb, k))
    return Ck

# input of apriori algorithm should be a list of transactions, wtf is this ?!
Lk = {(150,): 2, (160,): 3, (170,): 3, (180,): 3}
missing_input_value = 1234567890

print ( generateItemsets ( Lk, missing_input_value ) )
# output: set()

for i in range(0,999999):
  generateItemsets ( Lk, i )   # does not error out

所以你要么搞砸了你的 Python 版本,要么我误解了你的问题,或者你提供的输入没有涵盖你的程序的错误情况。
我建议您使用更大的代码来更新您的问题,而不仅仅是三行没有任何工作输入的函数。
当您使用 Jupyter 笔记本时,您得到的错误可能与您的输出数据速率有关。尝试执行jupyter notebook --NotebookApp.iopub_data_rate_limit=1.0e10 在控制台中,来自这篇文章:How to solve "IOPub data rate exceeded." in Jupyter Notebook
或者这个视频:https://www.youtube.com/watch?v=B_YlLf6fa5A

【讨论】:

    猜你喜欢
    • 2020-02-09
    • 2017-08-10
    • 2016-09-18
    • 2016-09-19
    • 1970-01-01
    • 2019-05-15
    • 1970-01-01
    • 2020-02-14
    • 2011-11-08
    相关资源
    最近更新 更多