问题:
我有数百万笔交易的清单。每个交易都包含项目(例如“胡萝卜”,“苹果”),目标是生成在个别交易中经常出现的一对项目列表。据我所知,进行详尽的搜索是不可行的。
解决方案尝试:
到目前为止,我有两个想法。 1)随机抽样一些适当的交易部分,只检查那些或2)计算每个元素出现的频率,使用该数据计算元素偶然出现的频率,并用它来修改1的估计值。
非常感谢任何提示,替代方法,现成解决方案或一般阅读建议。
编辑:
评论中的一些其他信息
不同项目数量:1,000到100,000
记忆约束:最多几次撞击几个小时。
使用频率:或多或少一次性。
可用资源:20-100小时的新手程序员时间。
所需的结果列表格式:对于n个最常见的对,项目对和一些项目会测量它们出现的频率。
每笔交易的物品分配:截至目前未知。
答案 0 :(得分:7)
让交易次数为n
,项目数为k
,交易平均大小为d
。
天真的方法(所有记录中的检查对)将为您提供O(k^2 * n * d)
解决方案,确实不是非常优化。但我们可以将其改进为O(k*n*d)
,如果我们假设项目的均匀分布(即每个项目平均重复O(n*d/k)
次) - 我们可以将其改进为O(d^2 * n + k^2)
(其中好多了,因为很可能d << k
)。
这可以通过构建事务的 inverted index 来完成,这意味着 - 创建从项目到包含它们的事务的映射(创建索引为O(nd + k)
)
示例,如果您有交易
transaction1 = ('apple','grape')
transaction2 = ('apple','banana','mango')
transaction3 = ('grape','mango')
倒排索引将是:
'apple' -> [1,2]
'grape' -> [1,3]
'banana' -> [2]
'mango' -> [2,3]
因此,在了解了倒排索引是什么之后 - 这里是解决方案的指南:
(x,y)
构建histogram,使y
与x
共同发生。< / LI>
复杂性分析:
O(nd+k)
O(nd/k)
个事务中重复,每次迭代需要O(nd/k * d)
次,并且您在此步骤中进行k
次迭代,因此您将获得此O(nd^2 + k)
步骤。 O(k^2)
中完成。在O(nd^2 + k^2)
解决方案中总计获得top-X元素,这比天真的方法要好得多,假设为d << k
。
此外,请注意,如果需要,瓶颈(步骤2)可以有效地并行化并在线程之间分配。
答案 1 :(得分:0)
如果一次购买中订购的商品数量很少(&lt; 10),请执行以下操作:
有地图地图(词典字典):
第一张地图中的关键字是项目,
第一个地图中的值是地图,其键是第二个项目,值计算在购买第一个键时出现的次数。
因此,请仔细检查每个订单和每对更新地图。 最后浏览地图并在“第二个值”中查找“大值”
注意:根据输入数据的大小和“分布”,您可能最终没有足够的内存