MapReduce实现倒排索引(类似协同过滤)

一、问题背景

  倒排索引其实就是出现次数越多,那么权重越大,不过我国有凤巢....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<LongWritable, Text, Text, Text> {

	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()));

  

四、实验分析

优秀的个人博客,低调大师

微信关注我们

原文链接:https://yq.aliyun.com/articles/288400

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
优质分享Android(本站安卓app)

优质分享Android(本站安卓app)

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的、适应高吞吐量的数据库方案。

Sublime Text 一个代码编辑器

Sublime Text 一个代码编辑器

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。