博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MapReduce实现倒排索引(类似协同过滤)
阅读量:6940 次
发布时间:2019-06-27

本文共 2898 字,大约阅读时间需要 9 分钟。

一、问题背景

  倒排索引其实就是出现次数越多,那么权重越大,不过我国有凤巢....zf为啥不管,总局回应推广是不是广告有争议...

  eclipse里ctrl+t找接口或者抽象类的实现类,看看都有啥方法,有时候hadoop的抽象类返回的接口没有需要的方法,那么我们返回他的实现类。

   吧需要的文件放入hdfs下的目录下,只要不是以下划线开头的均算。

二、理论准备

   

  搜索引擎查询的时候就是查询这个单词文档矩阵,旺旺采用倒排索引存储,后缀树也可以。

  不管理论直接看例子,这是原始的文档

  下面是简单的索引,只是表征是否在文档中出现过。

  下面就是文档及出现次数。

  擦,咋有点想协同过滤。

三、思路分析

  其实是一个全文检索的数据结构。理论上关键字出现次数越多,那么文章就越靠前。

  就是wc的加强版本。wc是统计单词在文章里出现的次数,倒排是统计关键字在各个文章出现的次数。

  有时候不能一下子写出来,可能需要多次mr,那么我们首先确定最终的结果形式,然后向上反推。

  如果多个mr,考虑使用combiner,不过要考虑combiner是不是可插拔的,也就是combiner和业务逻辑是否和reducer一样。

  怎么知道单词出现在那个文章里?从context对象里获取。既然能忘context写东西,那么也能从其中获取信息。

  最终结果是

hello	"a.txt->5 b.txt->3"tom		"a.txt->2 b.txt->1"kitty	"a.txt->1"

  那么reduce的输出

context.write("hello","a.txt->5 b.txt->3");

  那么combiner阶段是

<"hello",{"a.txt->5","b.txt->3"}>

  那么map的输出

context.write("hello","a.txt->5");context.write("hello","b.txt->3");

  不过考虑到wc,map的输出应该是,路径放在value不好处理,还要廉价呢。

context.write("hello->a.txt",1);context.write("hello->a.txt",1);context.write("hello->a.txt",1);context.write("hello->a.txt",1);context.write("hello->a.txt",1);context.write("hello->b.txt",1);context.write("hello->b.txt",1);context.write("hello->b.txt",1);

  那么combiner阶段根据就输出

<"hello->a.txt",1><"hello->a.txt",1><"hello->a.txt",1><"hello->a.txt",1><"hello->a.txt",1><"hello->b.txt",1><"hello->b.txt",1><"hello->b.txt",1>context.write("hello","a.txt->5");context.write("hello","b.txt->3");

 次是不同文件的相同key并没有合并,reducer合并输出皆可。

四、代码实现

4.1 Mapper

public class IIMapper1 extends Mapper
{ private Text k = new Text(); //下面其实是int,不过也可以在接收端Integer.parseInt转了就好 private Text v = new Text(); public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); String[] words = line.split(" "); //从context对象里找到单词属于那个文章 //context.getInputSplit();找到切片 按ctrl找 发现返回时InputSplit //不过是个抽象类 ctrl + t找他的实现类 //能把数据写入context,繁殖也能从context拿到很多信息 //从下面inputSplit调用get的时候发现没有合适的方法,那么我们找他的实现类,调用实现类的方法 //InputSplit inputSplit = context.getInputSplit(); //inputSplit.get //他的子类很多 我们处理文件就用File开头的 然后有个getPath FileSplit inputSplit = (FileSplit)context.getInputSplit(); //文件名是hdfs://hostname:port/a/1.txt //我们戒掉hdfs://hostname:port 不能戒掉a 应为这是文件夹否则不知道1.txt来自哪 其他文件家下可能也有同名文件 //也可以不接去 String path = inputSplit.getPath().toString(); for(String w:words) { k.set(w+"->"+path); v.set("1"); context.write(k, v); } }}

  

4.2 Combiner

String[] wordAndPath = key.toString().split("->");		String word = wordAndPath[0];		String path = wordAndPath[1];		// process values		int sum = 0;		for (Text val : value) {			sum += Integer.parseInt(val.toString());		}		k.set(word);		v.set(path+"->"+sum);		context.write(k, v);

  

4.3 Reducer

//不涉及多线程 用StringBuilde即可		StringBuilder sb = new StringBuilder();		// process values		for (Text val : value) {			sb.append(val.toString()).append("\t");		}		context.write(key, new Text(sb.toString()));

  

四、实验分析

转载地址:http://lebnl.baihongyu.com/

你可能感兴趣的文章
启动或重启DNS服务时,卡在Generating /etc/rndc.key:上很长时间
查看>>
视频专辑:Python系列视频教程
查看>>
Linux内核更新 linux3.10.tar.gz Redhat 6.0
查看>>
IPv6技术详解:基本概念、应用现状、技术实践(下篇)
查看>>
zabbix自定义key监控mysql重要参数的运行情况
查看>>
CISCO 多协议,多进程,路由重分布及其路由策略应用
查看>>
ios开发备忘录十
查看>>
windows下 iis配置php5.6
查看>>
谷歌火狐浏览器保存网页为htm格式
查看>>
sqlserver表和库管理
查看>>
Ceph安装QEMU报错:User requested feature rados block device configure was not able to find it
查看>>
我的友情链接
查看>>
linux中 qt5 的环境搭建
查看>>
Qt 中调用cmd不显示窗口
查看>>
HBase原理和优化
查看>>
maven配置全局的jdk和配置局部的jdk
查看>>
Integer.valueOf(int i)源码
查看>>
CentOS 6.5 minimal 装配vmware-tools
查看>>
Linux中获取命令帮助
查看>>
从零构建PHP商用MVC框架(2.1 路由-带参数请求)
查看>>