Java Apriori算法在Hadoop上的实现
我正在尝试使用Hadoop实现Apriori算法。我已经实现了Apriori算法的非分布式版本,但我对Hadoop和MapReduce的不熟悉导致了一些问题 我想要实现算法的方式分为两个阶段: 1) 在第一阶段,map reduce作业将在原始事务数据集上操作。此阶段的输出是一个包含所有1-itemset及其对1的支持的文件 2) 在第二阶段,我想读入前一阶段的输出,然后构造新的项目集。重要的是,我想在mapper中确定数据集中是否仍然存在任何新的项集。我设想,如果我将原始数据集作为输入发送给映射器,它将对原始文件进行分区,以便每个映射器只扫描部分数据集。然而,候选列表需要根据前一阶段的所有输出构建。这将在循环中迭代固定次数的过程 我的问题是如何明确地确保我可以访问每个映射器中的完整项集,以及能够访问原始数据集以计算每个阶段的新支持 感谢您的建议、评论、建议或回答Java Apriori算法在Hadoop上的实现,java,hadoop,mapreduce,apriori,Java,Hadoop,Mapreduce,Apriori,我正在尝试使用Hadoop实现Apriori算法。我已经实现了Apriori算法的非分布式版本,但我对Hadoop和MapReduce的不熟悉导致了一些问题 我想要实现算法的方式分为两个阶段: 1) 在第一阶段,map reduce作业将在原始事务数据集上操作。此阶段的输出是一个包含所有1-itemset及其对1的支持的文件 2) 在第二阶段,我想读入前一阶段的输出,然后构造新的项目集。重要的是,我想在mapper中确定数据集中是否仍然存在任何新的项集。我设想,如果我将原始数据集作为输入发送给映
编辑:根据反馈,我只想更具体地说明我在这里要问的问题。在开始之前,我建议您阅读 步骤1: 将数据文件加载到HDFS。让我们假设您的数据是txt文件,每个集合是一行
a b c
a c d e
a e f
a f z
...
步骤2:
按照MapReduce教程构建您自己的Apriori类
public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
// Seprate the line into tokens by space
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
// Add the token into a writable set
... put the element into a writable set ...
}
context.write(word, one);
}
步骤3:
运行mapreduce jar文件。输出将在HDFS中的一个文件中。
您将有类似于:
a b 3 (number of occurrence)
a b c 5
a d 2
...
根据输出文件,可以计算关系
我使用Hadoop流在Apache Spark和Hadoop MapReduce中实现了AES算法。 我知道这与Apriori不同,但你可以尝试使用我的方法 使用Hadoop Streming MapReduce实现AES的简单示例 1n_reducer.py/1n_combiner是相同的代码,但没有约束
import sys
CONSTRAINT = 1000
def do_reduce(word, _values):
return word, sum(_values)
prev_key = None
values = []
for line in sys.stdin:
key, value = line.split("\t")
if key != prev_key and prev_key is not None:
result_key, result_value = do_reduce(prev_key, values)
if result_value > CONSTRAINT:
print(result_key + "\t" + str(result_value))
values = []
prev_key = key
values.append(int(value))
if prev_key is not None:
result_key, result_value = do_reduce(prev_key, values)
if result_value > CONSTRAINT:
print(result_key + "\t" + str(result_value))
base_mapper.py:
import sys
def count_usage():
for line in sys.stdin:
elements = line.rstrip("\n").rsplit(",")
for item in elements:
print("{item}\t{count}".format(item=item, count=1))
if __name__ == "__main__":
count_usage()
2n_mapper.py使用上一次迭代的结果。
在回答您的问题时,您可以通过这种方式读取上一次迭代的输出以形成项集
import itertools
import sys
sys.path.append('.')
N_DIM = 2
def get_2n_items():
items = set()
with open("part-00000") as inf:
for line in inf:
parts = line.split('\t')
if len(parts) > 1:
items.add(parts[0])
return items
def count_usage_of_2n_items():
all_items_set = get_2n_items()
for line in sys.stdin:
items = line.rstrip("\n").rsplit(",") # 74743 43355 53554
exist_in_items = set()
for item in items:
if item in all_items_set:
exist_in_items.add(item)
for combination in itertools.combinations(exist_in_items, N_DIM):
combination = sorted(combination)
print("{el1},{el2}\t{count}".format(el1=combination[0], el2=combination[1], count=1))
if __name__ == "__main__":
count_usage_of_2n_items()
根据我的经验,如果唯一组合(项目集)的数量太大(100K+),Apriori算法不适合Hadoop。
如果您发现使用Hadoop MapReduce(流媒体或Java MapReduce实现)实现Apriori算法的优雅解决方案,请与社区分享
注:如果您需要更多的代码片段,请询问。谢谢您的评论。不幸的是,作业要求我使用MapReduce。我知道你的问题是关于apriori算法的。但是,我强烈建议使用更好的
FP-Growth算法
,因为apriori算法在这个过程中需要重复多次。对于长而高的数据处理管道,不建议使用这种算法。