一、倒排索引简单介绍

倒排索引(英语:Inverted index),也常被称为反向索引、置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。

它是文档检索系统中最经常使用的数据结构。

以英文为例。以下是要被索引的文本:

T0="it is what it is"
T1="what is it"
T2="it is a banana"

我们就能得到以下的反向文件索引:

 "a":      {2}
"banana": {2}
"is": {0, 1, 2}
"it": {0, 1, 2}
"what": {0, 1}

检索的条件”what”, “is” 和 “it” 将相应这个集合:{0, 1}&{0, 1, 2}& {0, 1, 2}={0,1}

对于中文分词,能够使用开源的中文分词工具,这里使用ik-analyzer。

准备几个文本文件,写入内容做測试。

file1.txt内容例如以下:

其实我们发现,互联网裁员潮频现甚至要高于其它行业领域

file2.txt内容例如以下:

面对寒冬,互联网企业不得不调整人员结构,优化雇员的投入产出

file3.txt内容例如以下:

在互联网内部,因为内部竞争机制以及要与竞争对手拼进度

file4.txt内容例如以下:

互联网大公司职员尽管能够从复杂性和专业分工中受益
互联网企业不得不调整人员结构

二、加入依赖

出了hadoop主要的jar包意外。加入中文分词的lucene-analyzers-commonik-analyzers


<!--Lucene分词模块-->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>6.0.0</version>
</dependency> <!--IK分词 -->
<dependency>
<groupId>cn.bestwu</groupId>
<artifactId>ik-analyzers</artifactId>
<version>5.1.0</version>
</dependency>

三、MapReduce程序

关于Lucene 6.0中IK分词的配置參考http://blog.csdn.net/napoay/article/details/51911875,MapReduce程序例如以下。

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import java.io.IOException;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map; /**
* Created by bee on 4/4/17.
*/
public class InvertIndexIk { public static class InvertMapper extends Mapper<Object, Text, Text, Text> { public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
String filename = ((FileSplit) context.getInputSplit()).getPath().getName()
.toString();
Text fname = new Text(filename);
IKAnalyzer6x analyzer = new IKAnalyzer6x(true);
String line = value.toString();
StringReader reader = new StringReader(line);
TokenStream tokenStream = analyzer.tokenStream(line, reader);
tokenStream.reset();
CharTermAttribute termAttribute = tokenStream.getAttribute
(CharTermAttribute.class);
while (tokenStream.incrementToken()) {
Text word = new Text(termAttribute.toString());
context.write(word, fname);
}
} } public static class InvertReducer extends Reducer<Text, Text, Text, Text> { public void reduce(Text key, Iterable<Text> values,Reducer<Text,Text,
Text,Text>.Context context) throws IOException, InterruptedException {
Map<String, Integer> map = new HashMap<String, Integer>();
for (Text val : values) {
if (map.containsKey(val.toString())) { map.put(val.toString(),map.get(val.toString())+1); } else {
map.put(val.toString(),1);
} }
int termFreq=0;
for (String mapKey:map.keySet()){
termFreq+=map.get(mapKey);
}
context.write(key,new Text(map.toString()+" "+termFreq));
} } public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { HadoopUtil.deleteDir("output");
Configuration conf=new Configuration(); String[] otherargs=new
String[]{"input/InvertIndex",
"output"}; if (otherargs.length!=2){
System.err.println("Usage: mergesort <in> <out>");
System.exit(2);
} Job job=Job.getInstance();
job.setJarByClass(InvertIndexIk.class);
job.setMapperClass(InvertIndexIk.InvertMapper.class);
job.setReducerClass(InvertIndexIk.InvertReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job,new Path(otherargs[0]));
FileOutputFormat.setOutputPath(job,new Path(otherargs[1]));
System.exit(job.waitForCompletion(true) ? 0: 1); }
}

四、执行结果

输出例如以下:

专业分工    {file4.txt=1}  1
中 {file4.txt=1} 1
其实 {file1.txt=1} 1
互联网 {file1.txt=1, file3.txt=1, file4.txt=2, file2.txt=1} 5
人员 {file4.txt=1, file2.txt=1} 2
企业 {file4.txt=1, file2.txt=1} 2
优化 {file2.txt=1} 1
内部 {file3.txt=2} 2
发现 {file1.txt=1} 1
受益 {file4.txt=1} 1
复杂性 {file4.txt=1} 1
大公司 {file4.txt=1} 1
寒冬 {file2.txt=1} 1
投入产出 {file2.txt=1} 1
拼 {file3.txt=1} 1
潮 {file1.txt=1} 1
现 {file1.txt=1} 1
竞争对手 {file3.txt=1} 1
竞争机制 {file3.txt=1} 1
结构 {file4.txt=1, file2.txt=1} 2
职员 {file4.txt=1} 1
行业 {file1.txt=1} 1
裁员 {file1.txt=1} 1
要与 {file3.txt=1} 1
调整 {file4.txt=1, file2.txt=1} 2
进度 {file3.txt=1} 1
雇员 {file2.txt=1} 1
面对 {file2.txt=1} 1
领域 {file1.txt=1} 1
频 {file1.txt=1} 1
高于 {file1.txt=1} 1

结果有三列。依次为词项、词项在单个文件里的词频以及总的词频。

五、參考资料

1.https://zh.wikipedia.org/wiki/ 倒排索引

2. Lucene 6.0下使用IK分词器

最新文章

  1. JSTL自定义标签
  2. 【转】使用Xcode 6将你的项目本地化
  3. Secondary IP Addressing
  4. 谈谈MVC模式
  5. poj 3237 Tree
  6. [译]servlet3.0与non-blocking服务端推送技术
  7. Ubuntu下配置 keepalived+nginx+tomcat 负载均衡
  8. @Component(&quot;userService&quot;).@Resource(name=&quot;userDao&quot;)
  9. 关于在C#中实现AOP 拦截编程模式的新的探索
  10. Web 前端知识点
  11. rational rose 2003安装及破解
  12. LeetCode之“动态规划”:Maximal Square &amp;&amp; Largest Rectangle in Histogram &amp;&amp; Maximal Rectangle
  13. linux文件的基本属性
  14. c/c++ 继承与多态 文本查询的小例子(智能指针版本)
  15. .NetCore&amp;Linux&amp;Docker&amp;Portainer踩坑历险记
  16. sqlmap常用渗透方法
  17. Java环境变量配置----JDK开发环境及环境变量设置
  18. java.lang.IllegalStateException: Cannot forward after response has been committed的一个情况解决方法
  19. 10-51单片机ESP8266学习-AT指令(ESP8266连接路由器,建立TCP服务器,分别和C#TCP客户端和AndroidTCP客户端通信+花生壳远程通信)
  20. 改变Cube的Shader下的Alpha值,实现Cube若隐若现的效果。

热门文章

  1. FeignClient与RestTemplate的区别比较简单研究
  2. thinkphp去重统计数据sql
  3. nodejs调试利器:supervisor
  4. postgres--流复制
  5. postgres10配置huge_pages
  6. 关停后Bitfinex放贷初探
  7. Selenium IDE 基础使用教程
  8. 怎么设置IDEA,去除单词拼写检查,或者添加自定义的单词
  9. oracle 10g函数大全--数值型函数
  10. 解决 KendoUI TabStrip 高度 100% 问题