Twenty Newsgroups Classification任务之二seq2sparse(2)
接上篇,SequenceFileTokenizerMapper的输出文件在/home/mahout/mahout-work-mahout0/20news-vectors/tokenized-documents/part-m-00000文件即可查看,同时可以编写下面的代码来读取该文件(该代码是根据前面读出聚类中心点文件改编的),如下:
package mahout.fansy.test.bayes.read; import java.util.ArrayList;
import java.util.List; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Writable;
import org.apache.mahout.common.StringTuple;
import org.apache.mahout.common.iterator.sequencefile.PathFilters;
import org.apache.mahout.common.iterator.sequencefile.PathType;
import org.apache.mahout.common.iterator.sequencefile.SequenceFileDirValueIterable; public class ReadFromTokenizedDocuments { /**
* @param args
*/
private static Configuration conf; public static void main(String[] args) {
conf=new Configuration();
conf.set("mapred.job.tracker", "ubuntu:9001");
String path="hdfs://ubuntu:9000/home/mahout/mahout-work-mahout0/20news-vectors/tokenized-documents/part-m-00000"; getValue(path,conf);
} /**
* 把序列文件读入到一个变量中;
* @param path 序列文件
* @param conf Configuration
* @return 序列文件读取的变量
*/
public static List<StringTuple> getValue(String path,Configuration conf){
Path hdfsPath=new Path(path);
List<StringTuple> list = new ArrayList<StringTuple>();
for (Writable value : new SequenceFileDirValueIterable<Writable>(hdfsPath, PathType.LIST,
PathFilters.partFilter(), conf)) {
Class<? extends Writable> valueClass = value.getClass();
if (valueClass.equals(StringTuple.class)) {
StringTuple st = (StringTuple) value;
list.add(st);
} else {
throw new IllegalStateException("Bad value class: " + valueClass);
}
}
return list;
} }
通过上面的文件可以读取到第一个StringTuple的单词个数有1320个(去掉stop words的单词数);
然后就又是一堆参数的设置,一直到267行,判断processIdf是否为非true,因为前面设置的是tfdif,所以这里进入else代码块,如下:
if (!processIdf) {
DictionaryVectorizer.createTermFrequencyVectors(tokenizedPath, outputDir, tfDirName, conf, minSupport, maxNGramSize,
minLLRValue, norm, logNormalize, reduceTasks, chunkSize, sequentialAccessOutput, namedVectors);
} else {
DictionaryVectorizer.createTermFrequencyVectors(tokenizedPath, outputDir, tfDirName, conf, minSupport, maxNGramSize,
minLLRValue, -1.0f, false, reduceTasks, chunkSize, sequentialAccessOutput, namedVectors);
}
这里直接调用DictionaryVectorizer的createTermFrequencyVectors方法,进入该方法(DictionaryVectorizer的145行),可以看到首先也是一些参数的设置,然后就到了startWordCounting方法了,进入这个方法可以看到这个是一个Job的基本设置,其Mapper、Combiner、Reducer分别为:TermCountMapper、TermCountCombiner、TermCountReducer,下面分别来看各个部分的作用(其实和最基本的wordcount很相似):
TermCountMapper,首先贴代码:
protected void map(Text key, StringTuple value, final Context context) throws IOException, InterruptedException {
OpenObjectLongHashMap<String> wordCount = new OpenObjectLongHashMap<String>();
for (String word : value.getEntries()) {
if (wordCount.containsKey(word)) {
wordCount.put(word, wordCount.get(word) + 1);
} else {
wordCount.put(word, 1);
}
}
wordCount.forEachPair(new ObjectLongProcedure<String>() {
@Override
public boolean apply(String first, long second) {
try {
context.write(new Text(first), new LongWritable(second));
} catch (IOException e) {
context.getCounter("Exception", "Output IO Exception").increment(1);
} catch (InterruptedException e) {
context.getCounter("Exception", "Interrupted Exception").increment(1);
}
return true;
}
});
该部分代码首先定义了一个Mahout开发人员定义的Map类,然后遍历value中的各个单词(比如第一个value中有1320个单词);当遇到map中没有的单词就把其加入map中,否则把map中该单词的数量加1更新原来的单词的数量,即for循环里面做的事情;然后就是forEachPair方法了,这里应该是复写了该方法?好像是直接新建了一个类然后把这个新建的类作为forEachPair的参数;直接看context.write吧,应该是把wordCount(这个变量含有每个单词和它的计数)中的各个单词和单词计数分别作为key和value输出;
然后是TermCountCombiner和TermCountReducer,这两个代码一样的和当初学习Hadoop入门的第一个例子是一样的,这里就不多说了。查看log信息,可以看到reduce一共输出93563个单词。
然后就到了createDictionaryChunks函数了,进入到DictionaryVectorizer的215行中的该方法:
List<Path> chunkPaths = Lists.newArrayList();
Configuration conf = new Configuration(baseConf);
FileSystem fs = FileSystem.get(wordCountPath.toUri(), conf);
long chunkSizeLimit = chunkSizeInMegabytes * 1024L * 1024L;
int chunkIndex = 0;
Path chunkPath = new Path(dictionaryPathBase, DICTIONARY_FILE + chunkIndex);
chunkPaths.add(chunkPath);
SequenceFile.Writer dictWriter = new SequenceFile.Writer(fs, conf, chunkPath, Text.class, IntWritable.class);
try {
long currentChunkSize = 0;
Path filesPattern = new Path(wordCountPath, OUTPUT_FILES_PATTERN);
int i = 0;
for (Pair<Writable,Writable> record
: new SequenceFileDirIterable<Writable,Writable>(filesPattern, PathType.GLOB, null, null, true, conf)) {
if (currentChunkSize > chunkSizeLimit) {
Closeables.closeQuietly(dictWriter);
chunkIndex++;
chunkPath = new Path(dictionaryPathBase, DICTIONARY_FILE + chunkIndex);
chunkPaths.add(chunkPath);
dictWriter = new SequenceFile.Writer(fs, conf, chunkPath, Text.class, IntWritable.class);
currentChunkSize = 0;
}
Writable key = record.getFirst();
int fieldSize = DICTIONARY_BYTE_OVERHEAD + key.toString().length() * 2 + Integer.SIZE / 8;
currentChunkSize += fieldSize;
dictWriter.append(key, new IntWritable(i++));
}
maxTermDimension[0] = i;
} finally {
Closeables.closeQuietly(dictWriter);
}
这里看到新建了一个Writer,然后遍历该文件的key和value,但是只读取key值,即单词,然后把这些单词进行编码,即第一个单词用0和它对应,第二个单词用1和它对应。
上面代码使用的dictWriter查看变量并没有看到哪个属性是存储单词和对应id的,所以这里的写入文件的机制是append就写入?还是我没有找到正确的属性?待查。。。
分享,快乐,成长
转载请注明出处:http://blog.csdn.net/fansy1990
Twenty Newsgroups Classification任务之二seq2sparse(2)的更多相关文章
- Twenty Newsgroups Classification任务之二seq2sparse(5)
接上篇blog,继续分析.接下来要调用代码如下: // Should document frequency features be processed if (shouldPrune || proce ...
- Twenty Newsgroups Classification任务之二seq2sparse
seq2sparse对应于mahout中的org.apache.mahout.vectorizer.SparseVectorsFromSequenceFiles,从昨天跑的算法中的任务监控界面可以看到 ...
- Twenty Newsgroups Classification任务之二seq2sparse(3)
接上篇,如果想对上篇的问题进行测试其实可以简单的编写下面的代码: package mahout.fansy.test.bayes.write; import java.io.IOException; ...
- mahout 运行Twenty Newsgroups Classification实例
按照mahout官网https://cwiki.apache.org/confluence/display/MAHOUT/Twenty+Newsgroups的说法,我只用运行一条命令就可以完成这个算法 ...
- Twenty Newsgroups Classification实例任务之TrainNaiveBayesJob(一)
接着上篇blog,继续看log里面的信息如下: + echo 'Training Naive Bayes model' Training Naive Bayes model + ./bin/mahou ...
- 项目笔记《DeepLung:Deep 3D Dual Path Nets for Automated Pulmonary Nodule Detection and Classification》(二)(上)模型设计
我只讲讲检测部分的模型,后面两样性分类的试验我没有做,这篇论文采用了很多肺结节检测论文都采用的u-net结构,准确地说是具有DPN结构的3D版本的u-net,直接上图. DPN是颜水成老师团队的成果, ...
- 深度学习数据集Deep Learning Datasets
Datasets These datasets can be used for benchmarking deep learning algorithms: Symbolic Music Datase ...
- Open Data for Deep Learning
Open Data for Deep Learning Here you’ll find an organized list of interesting, high-quality datasets ...
- 深度学习课程笔记(二)Classification: Probility Generative Model
深度学习课程笔记(二)Classification: Probility Generative Model 2017.10.05 相关材料来自:http://speech.ee.ntu.edu.tw ...
随机推荐
- MFC逆向-消息响应函数的定位
MFC == Microsoft Foundation Class,微软基础类库,他封装了Windows API以便用户更快速的开发界面功能程序然而该库及其庞大而复杂,需要有C++的功底否则很难 ...
- 同步机制Lock初学(转)
前段时间review同事的代码,发现可以简化成如下的模型: Thread 1 Thread 2 lock.lock(); condition.await(); lock.unlock() lock.l ...
- 基于visual Studio2013解决算法导论之029二叉搜索树
题目 二叉搜索树 解决代码及点评 #include <stdio.h> #include <malloc.h> #include <stdlib.h> ty ...
- yii框架网址解析问题
转载请注明来自souldak,微博:@evagle 首先如果你在config/main.php里面没有配置urlManager的话,那么流程如下(摘自yii官网) 用户发出了访问 URL http:/ ...
- [置顶] 63行代码完美实现html5 贪吃蛇游戏
以前也很少关注html5,感觉选择html已经慢慢成为趋势,想了解下.就找了个游戏学习了,写完这个游戏感觉html5和js结合很紧密,如果js不是特别好.估计需要先补习下js,这个只是个人的建议,不一 ...
- C++11 thread::detach(2)
原文地址:http://www.cplusplus.com/reference/thread/thread/detach/ public member function <thread> ...
- Technology_Roadmap
2016年1月23日 前端技术: - HTML CSS JavaScript JQuery 操作系统: - Linux (CentOS) 数据库: - SQLServer MySQL 开源前端框架: ...
- Windows Store Javascript项目使用高德地图、谷歌地图、百度地图API
原文 Windows Store Javascript项目使用高德地图.谷歌地图.百度地图API 在Win8 Store 项目中可以使用的地图主要有微软的Bing Map,目前高德地图sdk也支持Wi ...
- 解决基于BAE python+bottle开发上的一系列问题 - artwebs - 博客频道 - CSDN.NET
解决基于BAE python+bottle开发上的一系列问题 - artwebs - 博客频道 - CSDN.NET 解决基于BAE python+bottle开发上的一系列问题 分类: python ...
- 基于visual Studio2013解决C语言竞赛题之1032平方和
题目 解决代码及点评 /* 编程序将一个正整数写成其它两个正整数的平方和,若不能成立时输出"NO".例如 5 = 1^2 + 2^2 , 25 ...