接上篇,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)的更多相关文章

  1. Twenty Newsgroups Classification任务之二seq2sparse(5)

    接上篇blog,继续分析.接下来要调用代码如下: // Should document frequency features be processed if (shouldPrune || proce ...

  2. Twenty Newsgroups Classification任务之二seq2sparse

    seq2sparse对应于mahout中的org.apache.mahout.vectorizer.SparseVectorsFromSequenceFiles,从昨天跑的算法中的任务监控界面可以看到 ...

  3. Twenty Newsgroups Classification任务之二seq2sparse(3)

    接上篇,如果想对上篇的问题进行测试其实可以简单的编写下面的代码: package mahout.fansy.test.bayes.write; import java.io.IOException; ...

  4. mahout 运行Twenty Newsgroups Classification实例

    按照mahout官网https://cwiki.apache.org/confluence/display/MAHOUT/Twenty+Newsgroups的说法,我只用运行一条命令就可以完成这个算法 ...

  5. Twenty Newsgroups Classification实例任务之TrainNaiveBayesJob(一)

    接着上篇blog,继续看log里面的信息如下: + echo 'Training Naive Bayes model' Training Naive Bayes model + ./bin/mahou ...

  6. 项目笔记《DeepLung:Deep 3D Dual Path Nets for Automated Pulmonary Nodule Detection and Classification》(二)(上)模型设计

    我只讲讲检测部分的模型,后面两样性分类的试验我没有做,这篇论文采用了很多肺结节检测论文都采用的u-net结构,准确地说是具有DPN结构的3D版本的u-net,直接上图. DPN是颜水成老师团队的成果, ...

  7. 深度学习数据集Deep Learning Datasets

    Datasets These datasets can be used for benchmarking deep learning algorithms: Symbolic Music Datase ...

  8. Open Data for Deep Learning

    Open Data for Deep Learning Here you’ll find an organized list of interesting, high-quality datasets ...

  9. 深度学习课程笔记(二)Classification: Probility Generative Model

    深度学习课程笔记(二)Classification: Probility Generative Model  2017.10.05 相关材料来自:http://speech.ee.ntu.edu.tw ...

随机推荐

  1. 3DShader之投影贴图(Projective Texturing)

    相信大家都应该玩过CS或者CF吧,游戏里面有个喷图功能,就是按一个T键就能在墙上或者地板上喷出自己预先设定的图案. 而刚好这就是我们这个Shader所需实现的内容.由于没有潜伏者的贴图,我只有从这个图 ...

  2. 再造 “手机QQ” 侧滑菜单(三)——视图联动

    代码示例:https://github.com/johnlui/SwiftSideslipLikeQQ 本 文中,我们将一起使用 UINavigationController 来管理主视图,并实现点击 ...

  3. DHCP的工作原理

    什么是dhcp?它是如何实现的? DHCP称为动态主机配置协议.DHCP服务允许工作站连接到网络并且自动获取一个IP地址.配置DHCP服务的服务器可以为每一个网络客户提供一个IP地址.子网掩码.缺省网 ...

  4. 架构漫谈:UML中几种类间关系:继承、实现、依赖、关联、聚合、组合的联系与区别

    这是一堂关于UML基础知识的补习课:现在我们做项目时间都太紧了,基本上都没有做过真正的class级别的详细设计,更别提使用UML来实现规范建模了:本篇主要就以前自己一直感觉很迷糊的几种class之间的 ...

  5. 基于visual Studio2013解决C语言竞赛题之0804成绩筛选

     题目

  6. 有关oppo蝴蝶解锁的三D技术

    oppo手机的界面设计也是很漂亮的.在很多界面中使用了3D技术塑造出了大量华丽的效果.在蝴蝶解锁中使用了两个对称的三D变幻,宛如蝴蝶翅膀上美丽的花纹.在受到用户点击后,随风缓慢上下扇动,充满浪漫的动感 ...

  7. oralce 简单错误汇集。。。。。

    1.ora-12560 TNS:协议适配器错误 实例名被错误修改或者oracle 服务没有正常启动.

  8. java.lang.NoClassDefFoundError: ognl/PropertyAccessor解决的方法

    本来不想为这个专门写一篇文章的,可是发现这么简单的一个问题居然没有人好好回答过.从方便搜索的角度考虑,特意取了这么一个题目. 事实上解决方法就是将ognl的jar包增加就可以. 比方我用的是ognl3 ...

  9. API通用设计原则

    什么是好的API? ·        完备(Be Complete) 对确定重点支持的用户场景具有完备的功能支持.就是说,用户通过对一组API的调用能够完成预期的功能. ·        不冗余(Be ...

  10. BBED的安装及简单的使用方法

    记录下BBED的安装--ORACLE 11.2.0.4下 1.在ORACLE 11G下安装BBED,需要从ORACLE 10G中复制三个包 bbedus.msb               sbbdp ...