Mahout基于item的协同过滤之asMatrix

来源:互联网 发布:密室逃脱窃取数据攻略 编辑:程序博客网 时间:2024/06/08 11:12
/** * Job asMatrix * 输出:itemA, <itemO, similarity> 格式的向量 * 完成的功能: * 1.对每个item求topN相似的wupin * 2.计算下三角矩阵(由已经计算完成的上三角矩阵完成) */if (shouldRunNextPhase(parsedArgs, currentPhase)) {Job asMatrix = prepareJob(pairwiseSimilarityPath, // 输入文件getOutputPath(),// 输出文件UnsymmetrifyMapper.class,// IntWritable.class,// mapper output keyVectorWritable.class, // mapper output valueMergeToTopKSimilaritiesReducer.class,// IntWritable.class,// reducer output keyVectorWritable.class);// reducer output valueasMatrix.setCombinerClass(MergeToTopKSimilaritiesReducer.class);asMatrix.getConfiguration().setInt(MAX_SIMILARITIES_PER_ROW, maxSimilaritiesPerRow);boolean succeeded = asMatrix.waitForCompletion(true);if (!succeeded) {return -1;}}

(1)UnsymmetrifyMapper

public static class UnsymmetrifyMapper extends Mapper<IntWritable, VectorWritable, IntWritable, VectorWritable> {private int maxSimilaritiesPerRow; // item相似个数@Overrideprotected void setup(Context ctx) throws IOException, InterruptedException {maxSimilaritiesPerRow = ctx.getConfiguration().getInt( MAX_SIMILARITIES_PER_ROW, 0);Preconditions.checkArgument(maxSimilaritiesPerRow > 0, "Maximum number of similarities per row must be greater then 0!");}@Overrideprotected void map(IntWritable row, VectorWritable similaritiesWritable, Context ctx) throws IOException, InterruptedException {Vector similarities = similaritiesWritable.get();// 相似度输入格式:itemX, <itemY, similarity>Vector transposedPartial = similarities.like(); // 转置后的向量TopElementsQueue topKQueue = new TopElementsQueue(maxSimilaritiesPerRow); // 每个item最多maxSimilaritiesPerRow最相似的itemfor (Element nonZeroElement : similarities.nonZeroes()) { // 计算topKMutableElement top = topKQueue.top();double candidateValue = nonZeroElement.get();if (candidateValue > top.get()) {top.setIndex(nonZeroElement.index());top.set(candidateValue);topKQueue.updateTop();}// 求转置向量transposedPartial.setQuick(row.get(), candidateValue);// 转置向量 <itemX, similarity> ctx.write(new IntWritable(nonZeroElement.index()), new VectorWritable(transposedPartial));// 以 itemY, <itemX, similarity> 格式写入到输出 transposedPartial.setQuick(row.get(), 0.0);}// 将与当前物品TopN相似的物品以 itemX, <itemY, similarity> 格式写入到输出 Vector topKSimilarities = new RandomAccessSparseVector(similarities.size(), maxSimilaritiesPerRow);for (Vector.Element topKSimilarity : topKQueue.getTopElements()) {topKSimilarities.setQuick(topKSimilarity.index(), topKSimilarity.get());}ctx.write(row, new VectorWritable(topKSimilarities)); // 将itemX最相似的topK写到输出文件中}}


(2)MergeToTopKSimilaritiesReducer

public static class MergeToTopKSimilaritiesReducer extends Reducer<IntWritable, VectorWritable, IntWritable, VectorWritable> {private int maxSimilaritiesPerRow;// item相似个数@Overrideprotected void setup(Context ctx) throws IOException, InterruptedException {maxSimilaritiesPerRow = ctx.getConfiguration().getInt(MAX_SIMILARITIES_PER_ROW, 0);Preconditions.checkArgument(maxSimilaritiesPerRow > 0,"Maximum number of similarities per row must be greater then 0!");}@Overrideprotected void reduce(IntWritable row, Iterable<VectorWritable> partials, Context ctx) throws IOException, InterruptedException {// 将mapper过程中得到的两种向量 itemO, <itemA, similarity> 与 itemA, <itemO, similarity> 按相同物品进行合并Vector allSimilarities = Vectors.merge(partials);// 再次求TopNVector topKSimilarities = Vectors.topKElements(maxSimilaritiesPerRow, allSimilarities);// 最后输出 itemA, <itemO, similarity> 格式的向量ctx.write(row, new VectorWritable(topKSimilarities));}}



0 0
原创粉丝点击