From e6c270ddf155a90d2b2d81c6ff200b0f616bc3c2 Mon Sep 17 00:00:00 2001
From: lintool
Date: Wed, 25 Jan 2012 23:27:28 -0500
Subject: [PATCH 1/7] Refactoring to get building weighted doc vectors from
Wikipedia to work for me.
---
.classpath | 6 +-
ivy/ivy.xml | 3 +-
.../VerifyWikipediaProcessingMonolingual.java | 51 +++++++
.../data/document/WeightedIntDocVector.java | 4 +
.../core/driver/PreprocessWikipedia.java | 13 +-
.../BuildWeightedIntDocVectors.java | 142 +++++++++---------
.../BuildWeightedTermDocVectors.java | 126 +++++++++-------
.../ivory/core/util/ReadSequenceFile.java | 111 ++++++++++++++
8 files changed, 325 insertions(+), 131 deletions(-)
create mode 100644 src/java/integration/ivory/integration/wikipedia/VerifyWikipediaProcessingMonolingual.java
create mode 100644 src/java/main/ivory/core/util/ReadSequenceFile.java
diff --git a/.classpath b/.classpath
index 51380052..41691201 100644
--- a/.classpath
+++ b/.classpath
@@ -6,9 +6,6 @@
-
-
-
@@ -65,5 +62,8 @@
+
+
+
diff --git a/ivy/ivy.xml b/ivy/ivy.xml
index f73a5f19..fa4968ae 100644
--- a/ivy/ivy.xml
+++ b/ivy/ivy.xml
@@ -10,11 +10,10 @@
-
+
-
diff --git a/src/java/integration/ivory/integration/wikipedia/VerifyWikipediaProcessingMonolingual.java b/src/java/integration/ivory/integration/wikipedia/VerifyWikipediaProcessingMonolingual.java
new file mode 100644
index 00000000..683b98dd
--- /dev/null
+++ b/src/java/integration/ivory/integration/wikipedia/VerifyWikipediaProcessingMonolingual.java
@@ -0,0 +1,51 @@
+package ivory.integration.wikipedia;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import ivory.integration.IntegrationUtils;
+import ivory.integration.VerifyWt10gPositionalIndexIP;
+import junit.framework.JUnit4TestAdapter;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.io.IntWritable;
+import org.apache.hadoop.io.SequenceFile;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+import edu.umd.cloud9.io.map.HMapSFW;
+
+public class VerifyWikipediaProcessingMonolingual {
+
+ private ImmutableMap testTermDocVector1 =
+ ImmutableMap.of("total", 0.036282938f,
+ "posit", 0.047018476f,
+ "valid", 0.07093949f,
+ "formula", 0.06923077f);
+
+ @Test
+ public void verifyResults() throws Exception {
+ Configuration conf = IntegrationUtils.getBespinConfiguration();
+ FileSystem fs = FileSystem.get(conf);
+
+ SequenceFile.Reader reader = new SequenceFile.Reader(fs,
+ new Path("en-wiki/wt-term-doc-vectors/part-00000"), fs.getConf());
+
+ IntWritable key = new IntWritable();
+ HMapSFW value = new HMapSFW();
+ reader.next(key, value);
+ for (Map.Entry entry : testTermDocVector1.entrySet()) {
+ assertTrue(value.containsKey(entry.getKey()));
+ assertEquals(entry.getValue(), value.get(entry.getKey()), 10e-6);
+ }
+ }
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(VerifyWt10gPositionalIndexIP.class);
+ }
+}
diff --git a/src/java/main/ivory/core/data/document/WeightedIntDocVector.java b/src/java/main/ivory/core/data/document/WeightedIntDocVector.java
index 70e85ec1..8e90f1ca 100644
--- a/src/java/main/ivory/core/data/document/WeightedIntDocVector.java
+++ b/src/java/main/ivory/core/data/document/WeightedIntDocVector.java
@@ -95,6 +95,10 @@ public void normalizeWith (float l) {
}
}
+ @Override
+ public String toString() {
+ return weightedTerms.toString();
+ }
}
diff --git a/src/java/main/ivory/core/driver/PreprocessWikipedia.java b/src/java/main/ivory/core/driver/PreprocessWikipedia.java
index 930634ed..93c0d85c 100644
--- a/src/java/main/ivory/core/driver/PreprocessWikipedia.java
+++ b/src/java/main/ivory/core/driver/PreprocessWikipedia.java
@@ -90,7 +90,7 @@ public int run(String[] args) throws Exception {
printUsage();
return -1;
}
- Configuration conf = new Configuration();
+ Configuration conf = getConf();
String collectionLang = null, tokenizerModel = null, collectionVocab = null,
fVocab_f2e = null, eVocab_f2e = null, fVocab_e2f, eVocab_e2f = null, ttable_f2e = null, ttable_e2f = null;
@@ -141,6 +141,7 @@ public int run(String[] args) throws Exception {
LOG.info(" - Index path: " + indexRootPath);
LOG.info(" - Raw collection path: " + rawCollection);
LOG.info(" - Compressed collection path: " + seqCollection);
+ LOG.info(" - Collection language: " + collectionLang);
LOG.info(" - Tokenizer class: " + tokenizerClass);
LOG.info(" - Minimum # terms per article : " + MinNumTermsPerArticle);
@@ -173,7 +174,9 @@ public int run(String[] args) throws Exception {
Path mappingFile = env.getDocnoMappingData();
if (!fs.exists(mappingFile)) {
LOG.info(mappingFile + " doesn't exist, creating...");
- String[] arr = new String[] { "-input="+rawCollection, "-output_path="+ indexRootPath+"/wiki-docid-tmp", "-output_file="+mappingFile.toString()};
+ String[] arr = new String[] { "-input="+rawCollection,
+ "-output_path="+ indexRootPath+"/wiki-docid-tmp",
+ "-output_file="+mappingFile.toString()};
BuildWikipediaDocnoMapping tool = new BuildWikipediaDocnoMapping();
tool.setConf(conf);
@@ -188,7 +191,8 @@ public int run(String[] args) throws Exception {
p = new Path(seqCollection);
if (!fs.exists(p)) {
LOG.info(seqCollection + " doesn't exist, creating...");
- String[] arr = new String[] { "-input="+rawCollection, "-output="+seqCollection, "-mapping_file="+mappingFile.toString(), "-compression_type=block", "-wiki_language="+collectionLang};
+ String[] arr = new String[] { "-input="+rawCollection, "-output="+seqCollection, "-mapping_file="+mappingFile.toString(), "-compression_type=block",
+ "-wiki_language="+collectionLang};
RepackWikipedia tool = new RepackWikipedia();
tool.setConf(conf);
tool.run(arr);
@@ -218,7 +222,8 @@ public int run(String[] args) throws Exception {
startTime = System.currentTimeMillis();
LOG.info("Counting terms...");
new ComputeGlobalTermStatistics(conf).run();
- LOG.info("TermCount = "+env.readCollectionTermCount()+"\nJob finished in "+(System.currentTimeMillis()-startTime)/1000.0+" seconds");
+ LOG.info("TermCount = "+env.readCollectionTermCount());
+ LOG.info("Job finished in "+(System.currentTimeMillis()-startTime)/1000.0+" seconds");
// Build a map from terms to sequentially generated integer term ids
startTime = System.currentTimeMillis();
diff --git a/src/java/main/ivory/core/preprocess/BuildWeightedIntDocVectors.java b/src/java/main/ivory/core/preprocess/BuildWeightedIntDocVectors.java
index 043d41dd..fdbf8831 100644
--- a/src/java/main/ivory/core/preprocess/BuildWeightedIntDocVectors.java
+++ b/src/java/main/ivory/core/preprocess/BuildWeightedIntDocVectors.java
@@ -1,11 +1,11 @@
/*
- * Ivory: A Hadoop toolkit for Web-scale information retrieval
- *
+ * Ivory: A Hadoop toolkit for web-scale information retrieval
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,6 +15,7 @@
*/
package ivory.core.preprocess;
+
import ivory.core.Constants;
import ivory.core.RetrievalEnvironment;
import ivory.core.data.document.IntDocVector;
@@ -27,6 +28,7 @@
import java.io.IOException;
import java.net.URI;
+import java.util.Map;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.filecache.DistributedCache;
@@ -41,26 +43,26 @@
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
-import org.apache.hadoop.mapred.RunningJob;
import org.apache.hadoop.mapred.SequenceFileInputFormat;
import org.apache.hadoop.mapred.SequenceFileOutputFormat;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
+import com.google.common.collect.Maps;
+
import edu.umd.cloud9.io.map.HMapIFW;
import edu.umd.cloud9.util.PowerTool;
import edu.umd.cloud9.util.map.MapIF;
public class BuildWeightedIntDocVectors extends PowerTool {
private static final Logger LOG = Logger.getLogger(BuildWeightedIntDocVectors.class);
- static{
- LOG.setLevel(Level.INFO);
- }
- protected static enum Docs{
+
+ protected static enum Docs {
Total
}
+
private static class MyMapper extends MapReduceBase implements
- Mapper {
+ Mapper {
static IntWritable mDocno = new IntWritable();
private static DocLengthTable mDLTable;
@@ -70,60 +72,60 @@ private static class MyMapper extends MapReduceBase implements
private boolean normalize = false;
private boolean shortDocLengths = false;
- public void configure(JobConf conf){
- normalize = conf.getBoolean("Ivory.Normalize", true);
- shortDocLengths = conf.getBoolean("Ivory.ShortDocLengths", false);
+ public void configure(JobConf conf) {
+ LOG.setLevel(Level.WARN);
+
+ normalize = conf.getBoolean("Ivory.Normalize", false);
+ shortDocLengths = conf.getBoolean("Ivory.ShortDocLengths", true);
Path[] localFiles;
- String dfByIntFile, cfByIntFile, docLengthsFile;
+ Map pathMapping = Maps.newHashMap();
+ String dfFile;
+ String cfFile;
+ String dlFile;
+
try {
- String indexPath = conf.get (Constants.IndexPath);
- FileSystem fs = FileSystem.get (conf);
- RetrievalEnvironment env = new RetrievalEnvironment (indexPath, fs);
- dfByIntFile = env.getDfByIntData();
- cfByIntFile = env.getCfByIntData();
- docLengthsFile = env.getDoclengthsData().getName();
-
- // Detect if we're in standalone mode; if so, we can't us the
- // DistributedCache because it does not (currently) work in
- // standalone mode...
if (conf.get ("mapred.job.tracker").equals ("local")) {
- // use values from above
- } else {
- localFiles = DistributedCache.getLocalCacheFiles(conf);
- for (Path p : localFiles) {
- LOG.info("In DistributedCache: " + p);
- if (p.toString().contains(dfByIntFile)) {
- dfByIntFile = p.toString();
- } else if (p.toString().contains(cfByIntFile)) {
- cfByIntFile = p.toString();
- } else if (p.toString().contains(docLengthsFile)) {
- docLengthsFile = p.toString();
- }
- }
- LOG.info ("Df-by-int file: " + dfByIntFile);
- LOG.info ("Cf-by-int file: " + cfByIntFile);
- LOG.info ("Doc lengths file: " + docLengthsFile);
+ // Explicitly not support local mode.
+ throw new RuntimeException("Local mode not supported!");
}
- } catch (IOException e2) {
+ FileSystem fs = FileSystem.get(conf);
+ RetrievalEnvironment env = new RetrievalEnvironment(conf.get(Constants.IndexPath), fs);
+ dfFile = env.getDfByIntData();
+ cfFile = env.getCfByIntData();
+ dlFile = env.getDoclengthsData().toString();
+
+ // We need to figure out which file in the DistributeCache is which...
+ localFiles = DistributedCache.getLocalCacheFiles(conf);
+ for (Path p : localFiles) {
+ LOG.info("In DistributedCache: " + p);
+ if (p.toString().contains(dfFile)) {
+ pathMapping.put(dfFile, p);
+ } else if (p.toString().contains(cfFile)) {
+ pathMapping.put(cfFile, p);
+ } else if (p.toString().contains(dlFile)) {
+ pathMapping.put(dlFile, p);
+ }
+ }
+ } catch (IOException e) {
throw new RuntimeException("Local cache files not read properly.");
}
try {
- mDFTable = new DfTableArray(new Path(dfByIntFile), FileSystem.getLocal(conf));
+ mDFTable = new DfTableArray(pathMapping.get(dfFile), FileSystem.getLocal(conf));
} catch (IOException e1) {
- throw new RuntimeException("Error loading df table from "+dfByIntFile);
- }
+ throw new RuntimeException("Error loading df table from " + localFiles[0]);
+ }
try {
- if(shortDocLengths)
- mDLTable = new DocLengthTable2B(new Path(docLengthsFile), FileSystem.getLocal(conf));
- else
- mDLTable = new DocLengthTable4B(new Path(docLengthsFile), FileSystem.getLocal(conf));
+ if (shortDocLengths)
+ mDLTable = new DocLengthTable2B(pathMapping.get(dlFile), FileSystem.getLocal(conf));
+ else
+ mDLTable = new DocLengthTable4B(pathMapping.get(dlFile), FileSystem.getLocal(conf));
} catch (IOException e1) {
- throw new RuntimeException("Error loading dl table from "+docLengthsFile);
- }
+ throw new RuntimeException("Error loading dl table from " + localFiles[2]);
+ }
try {
mScoreFn = (ScoringModel) Class.forName(conf.get("Ivory.ScoringModel")).newInstance();
@@ -131,17 +133,19 @@ public void configure(JobConf conf){
mScoreFn.setDocCount(mDLTable.getDocCount());
mScoreFn.setAvgDocLength(mDLTable.getAvgDocLength());
} catch (Exception e) {
- throw new RuntimeException("Error initializing Ivory.ScoringModel from "+conf.get("Ivory.ScoringModel"));
- }
+ throw new RuntimeException("Error initializing Ivory.ScoringModel from "
+ + conf.get("Ivory.ScoringModel"));
+ }
}
HMapIFW vectorWeights = new HMapIFW();
int term;
float wt, sum2;
+
public void map(IntWritable docno, IntDocVector doc,
OutputCollector output, Reporter reporter)
- throws IOException {
+ throws IOException {
mDocno.set(docno.get());
int docLen = mDLTable.getDocLength(mDocno.get());
@@ -149,7 +153,7 @@ public void map(IntWritable docno, IntDocVector doc,
IntDocVector.Reader r = doc.getReader();
LOG.debug("===================================BEGIN READ DOC");
sum2 = 0;
- while(r.hasMoreTerms()){
+ while (r.hasMoreTerms()) {
term = r.nextTerm();
mScoreFn.setDF(mDFTable.getDf(term));
wt = mScoreFn.computeDocumentWeight(r.getTf(), docLen);
@@ -157,26 +161,25 @@ public void map(IntWritable docno, IntDocVector doc,
sum2 += wt * wt;
}
LOG.debug("===================================END READ DOC");
- if(normalize){
- /*length-normalize doc vectors*/
+ if (normalize) {
+ /* length-normalize doc vectors */
sum2 = (float) Math.sqrt(sum2);
- for(MapIF.Entry e : vectorWeights.entrySet()){
+ for (MapIF.Entry e : vectorWeights.entrySet()) {
float score = vectorWeights.get(e.getKey());
- vectorWeights.put(e.getKey(), score/sum2);
+ vectorWeights.put(e.getKey(), score / sum2);
}
}
- WeightedIntDocVector weightedVector = new WeightedIntDocVector (docLen, vectorWeights);
+ WeightedIntDocVector weightedVector = new WeightedIntDocVector(docLen, vectorWeights);
output.collect(mDocno, weightedVector);
reporter.incrCounter(Docs.Total, 1);
}
}
- public static final String[] RequiredParameters = { "Ivory.NumMapTasks",
- "Ivory.IndexPath",
- //"Ivory.OutputPath",
- "Ivory.ScoringModel",
- "Ivory.Normalize",
- };
+ public static final String[] RequiredParameters = {
+ "Ivory.NumMapTasks",
+ "Ivory.IndexPath",
+ "Ivory.ScoringModel",
+ "Ivory.Normalize" };
public String[] getRequiredParameters() {
return RequiredParameters;
@@ -186,9 +189,10 @@ public BuildWeightedIntDocVectors(Configuration conf) {
super(conf);
}
- @SuppressWarnings("deprecation")
public int runTool() throws Exception {
- LOG.info("PowerTool: GetWeightedIntDocVectors");
+ LOG.setLevel(Level.WARN);
+
+ LOG.info("PowerTool: BuildWeightedIntDocVectors");
// create a new JobConf, inheriting from the configuration of this
// PowerTool
@@ -238,7 +242,7 @@ public int runTool() throws Exception {
return 0;
}
- //fs.delete(weightedVectirsPath, true);
+ // fs.delete(weightedVectirsPath, true);
conf.setJobName("GetWeightedIntDocVectors:" + collectionName);
conf.setNumMapTasks(mapTasks);
@@ -257,11 +261,11 @@ public int runTool() throws Exception {
conf.setOutputValueClass(WeightedIntDocVector.class);
conf.setMapperClass(MyMapper.class);
- //conf.setInt("mapred.task.timeout",3600000);
+ // conf.setInt("mapred.task.timeout",3600000);
long startTime = System.currentTimeMillis();
- RunningJob job = JobClient.runJob(conf);
+ JobClient.runJob(conf);
LOG.info("Job Finished in " + (System.currentTimeMillis() - startTime) / 1000.0
+ " seconds");
diff --git a/src/java/main/ivory/core/preprocess/BuildWeightedTermDocVectors.java b/src/java/main/ivory/core/preprocess/BuildWeightedTermDocVectors.java
index b2df9545..afc287d8 100644
--- a/src/java/main/ivory/core/preprocess/BuildWeightedTermDocVectors.java
+++ b/src/java/main/ivory/core/preprocess/BuildWeightedTermDocVectors.java
@@ -1,11 +1,11 @@
/*
- * Ivory: A Hadoop toolkit for Web-scale information retrieval
- *
+ * Ivory: A Hadoop toolkit for web-scale information retrieval
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,6 +15,8 @@
*/
package ivory.core.preprocess;
+
+import ivory.core.Constants;
import ivory.core.RetrievalEnvironment;
import ivory.core.data.dictionary.DefaultFrequencySortedDictionary;
import ivory.core.data.document.LazyTermDocVector;
@@ -24,8 +26,11 @@
import ivory.core.data.stat.DocLengthTable2B;
import ivory.core.data.stat.DocLengthTable4B;
import ivory.pwsim.score.ScoringModel;
+
import java.io.IOException;
import java.net.URI;
+import java.util.Map;
+
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.filecache.DistributedCache;
import org.apache.hadoop.fs.FileSystem;
@@ -39,11 +44,12 @@
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
-import org.apache.hadoop.mapred.RunningJob;
import org.apache.hadoop.mapred.SequenceFileInputFormat;
import org.apache.hadoop.mapred.SequenceFileOutputFormat;
-import org.apache.log4j.Level;
import org.apache.log4j.Logger;
+
+import com.google.common.collect.Maps;
+
import edu.umd.cloud9.io.map.HMapSFW;
import edu.umd.cloud9.util.PowerTool;
import edu.umd.cloud9.util.map.MapKF;
@@ -51,14 +57,10 @@
public class BuildWeightedTermDocVectors extends PowerTool {
private static final Logger LOG = Logger.getLogger(BuildWeightedTermDocVectors.class);
- static{
- LOG.setLevel(Level.WARN);
- }
- protected static enum Docs{
- Total, ZERO, SHORT
- }
+ protected static enum Docs { Total, ZERO, SHORT }
+
private static class MyMapper extends MapReduceBase implements
- Mapper {
+ Mapper {
static IntWritable mDocno = new IntWritable();
private static DocLengthTable mDLTable;
@@ -71,45 +73,62 @@ private static class MyMapper extends MapReduceBase implements
DfTableArray dfTable;
public void configure(JobConf conf){
- LOG.setLevel(Level.INFO);
normalize = conf.getBoolean("Ivory.Normalize", false);
- shortDocLengths = conf.getBoolean("Ivory.ShortDocLengths", false);
+ shortDocLengths = conf.getBoolean("Ivory.ShortDocLengths", true);
MIN_SIZE = conf.getInt("Ivory.MinNumTerms", 0);
Path[] localFiles;
+ Map pathMapping = Maps.newHashMap();
+ String termsFile;
+ String termidsFile;
+ String idToTermFile;
+ String dfFile;
+ String dlFile;
+
try {
- // Detect if we're in standalone mode; if so, we can't us the
- // DistributedCache because it does not (currently) work in
- // standalone mode...
if (conf.get ("mapred.job.tracker").equals ("local")) {
- FileSystem fs = FileSystem.get (conf);
- //LOG.info ("fs: " + fs);
- String indexPath = conf.get ("Ivory.IndexPath");
- //LOG.info ("indexPath: " + indexPath);
- RetrievalEnvironment env = new RetrievalEnvironment (indexPath, fs);
- //LOG.info ("env: " + env);
- localFiles = new Path [5];
- localFiles [0] = new Path (env.getIndexTermsData ());
- localFiles [1] = new Path (env.getIndexTermIdsData ());
- localFiles [2] = new Path (env.getIndexTermIdMappingData ());
- localFiles [3] = new Path (env.getDfByIntData ());
- localFiles [4] = env.getDoclengthsData ();
-
- } else {
- localFiles = DistributedCache.getLocalCacheFiles (conf);
+ // Explicitly not support local mode.
+ throw new RuntimeException("Local mode not supported!");
+ }
+
+ FileSystem fs = FileSystem.get(conf);
+ RetrievalEnvironment env = new RetrievalEnvironment(conf.get(Constants.IndexPath), fs);
+ termsFile = env.getIndexTermsData();
+ termidsFile = env.getIndexTermIdsData();
+ idToTermFile = env.getIndexTermIdMappingData();
+ dfFile = env.getDfByIntData();
+ dlFile = env.getDoclengthsData().toString();
+
+ // We need to figure out which file in the DistributeCache is which...
+ localFiles = DistributedCache.getLocalCacheFiles(conf);
+ for (Path p : localFiles) {
+ LOG.info("In DistributedCache: " + p);
+ if (p.toString().contains(termsFile)) {
+ pathMapping.put(termsFile, p);
+ } else if (p.toString().contains(termidsFile)) {
+ pathMapping.put(termidsFile, p);
+ } else if (p.toString().contains(idToTermFile)) {
+ pathMapping.put(idToTermFile, p);
+ } else if (p.toString().contains(dfFile)) {
+ pathMapping.put(dfFile, p);
+ } else if (p.toString().contains(dlFile)) {
+ pathMapping.put(dlFile, p);
+ }
}
- } catch (IOException e2) {
+ } catch (IOException e) {
throw new RuntimeException ("Local cache files not read properly.");
}
- try{
- LOG.info("Index-terms = "+localFiles[0].toString());
- LOG.info("Index-termids = "+localFiles[1].toString());
- LOG.info("Index-termidmap = "+localFiles[2].toString());
- LOG.info("dftable = "+localFiles[3].toString());
+ LOG.info(" - terms: " + pathMapping.get(termsFile));
+ LOG.info(" - id: " + pathMapping.get(termidsFile));
+ LOG.info(" - idToTerms: " + pathMapping.get(idToTermFile));
+ LOG.info(" - df data: " + pathMapping.get(dfFile));
+ LOG.info(" - dl data: " + pathMapping.get(dlFile));
- dict = new DefaultFrequencySortedDictionary(localFiles[0], localFiles[1], localFiles[2], FileSystem.getLocal(conf));
- dfTable = new DfTableArray(localFiles[3], FileSystem.getLocal(conf));
+ try{
+ dict = new DefaultFrequencySortedDictionary(pathMapping.get(termsFile),
+ pathMapping.get(termidsFile), pathMapping.get(idToTermFile), FileSystem.getLocal(conf));
+ dfTable = new DfTableArray(pathMapping.get(dfFile), FileSystem.getLocal(conf));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error loading Terms File for dictionary from "+localFiles[0]);
@@ -119,12 +138,13 @@ public void configure(JobConf conf){
try {
if(shortDocLengths)
- mDLTable = new DocLengthTable2B(localFiles[4], FileSystem.getLocal(conf));
+ mDLTable = new DocLengthTable2B(pathMapping.get(dlFile), FileSystem.getLocal(conf));
else
- mDLTable = new DocLengthTable4B(localFiles[4], FileSystem.getLocal(conf));
+ mDLTable = new DocLengthTable4B(pathMapping.get(dlFile), FileSystem.getLocal(conf));
} catch (IOException e1) {
throw new RuntimeException("Error loading dl table from "+localFiles[4]);
- }
+ }
+
try {
mScoreFn = (ScoringModel) Class.forName(conf.get("Ivory.ScoringModel")).newInstance();
@@ -133,9 +153,10 @@ public void configure(JobConf conf){
mScoreFn.setAvgDocLength(mDLTable.getAvgDocLength());
} catch (Exception e) {
throw new RuntimeException("Error initializing Ivory.ScoringModel from "+conf.get("Ivory.ScoringModel"));
- }
+ }
}
+
HMapSFW weightedVector = new HMapSFW();
String term;
@@ -149,7 +170,7 @@ public void map(IntWritable docno, LazyTermDocVector doc,
weightedVector.clear();
TermDocVector.Reader r = doc.getReader();
- LOG.debug("===================================BEGIN READ DOC");
+ //LOG.debug("===================================BEGIN READ DOC");
sum2 = 0;
while(r.hasMoreTerms()){
term = r.nextTerm();
@@ -158,14 +179,14 @@ public void map(IntWritable docno, LazyTermDocVector doc,
int df = dfTable.getDf(id);
mScoreFn.setDF(df);
wt = mScoreFn.computeDocumentWeight(r.getTf(), docLen);
- LOG.debug(term+","+id+"==>"+r.getTf()+","+df+","+docLen+"="+wt);
+ //LOG.debug(term+","+id+"==>"+r.getTf()+","+df+","+docLen+"="+wt);
weightedVector.put(term, wt);
sum2 += wt * wt;
}else{
- LOG.debug("skipping term "+term+" (not in dictionary)");
+ //LOG.debug("skipping term "+term+" (not in dictionary)");
}
}
- LOG.debug("===================================END READ DOC");
+ //LOG.debug("===================================END READ DOC");
if(normalize){
/*length-normalize doc vectors*/
sum2 = (float) Math.sqrt(sum2);
@@ -174,7 +195,7 @@ public void map(IntWritable docno, LazyTermDocVector doc,
weightedVector.put(e.getKey(), score/sum2);
}
}
- LOG.debug("docvector size="+weightedVector.size());
+ //LOG.debug("docvector size="+weightedVector.size());
if(weightedVector.size()==0){
reporter.incrCounter(Docs.ZERO, 1);
}else if(weightedVector.size()
+ * Program that reads either a SequenceFile or a directory containing
+ * SequenceFiles. A maximum number of key-value pairs to read must be specified;
+ * in the of a directory, the value specifies the number of key-value pairs to
+ * read per file.
+ *
+ *
+ *
+ * args: [path] [max-num-of-records] (local)
+ *
+ *
+ *
+ * Note: specify "local" as the optional third argument for reading from local
+ * disk.
+ *
+ */
+public class ReadSequenceFile {
+
+ private ReadSequenceFile() {}
+
+ public static void main(String[] args) throws IOException {
+ if (args.length < 1) {
+ System.out.println("args: [path] [max-num-of-records-per-file]");
+ System.exit(-1);
+ }
+
+ String f = args[0];
+
+ int max = Integer.MAX_VALUE;
+ if (args.length >= 2) {
+ max = Integer.parseInt(args[1]);
+ }
+
+ boolean useLocal = args.length >= 3 && args[2].equals("local") ? true : false;
+
+ if (useLocal) {
+ System.out.println("Reading from local filesystem");
+ }
+
+ FileSystem fs = useLocal? FileSystem.getLocal(new Configuration()) : FileSystem.get(new Configuration());
+ Path p = new Path(f);
+
+ if (fs.getFileStatus(p).isDir()) {
+ readSequenceFilesInDir(p, fs, max);
+ } else {
+ readSequenceFile(p, fs, max);
+ }
+ }
+
+ private static int readSequenceFile(Path path, FileSystem fs, int max) throws IOException {
+ SequenceFile.Reader reader = new SequenceFile.Reader(fs, path, fs.getConf());
+
+ System.out.println("Reading " + path + "...\n");
+ try {
+ System.out.println("Key type: " + reader.getKeyClass().toString());
+ System.out.println("Value type: " + reader.getValueClass().toString() + "\n");
+ } catch (Exception e) {
+ throw new RuntimeException("Error: loading key/value class");
+ }
+
+ Writable key, value;
+ int n = 0;
+ try {
+ key = (Writable) reader.getKeyClass().newInstance();
+ value = (Writable) reader.getValueClass().newInstance();
+
+ while (reader.next(key, value)) {
+ System.out.println("Record " + n);
+ System.out.println("Key: " + key + "\nValue: " + value);
+ System.out.println("----------------------------------------");
+ n++;
+
+ if (n >= max)
+ break;
+ }
+ reader.close();
+ System.out.println(n + " records read.\n");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return n;
+ }
+
+ private static int readSequenceFilesInDir(Path path, FileSystem fs, int max) {
+ int n = 0;
+ try {
+ FileStatus[] stat = fs.listStatus(path);
+ for (int i = 0; i < stat.length; ++i) {
+ n += readSequenceFile(stat[i].getPath(), fs ,max);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println(n + " records read in total.");
+ return n;
+ }
+}
From ca59257c56c29f4d46251e52682c5f52b9700816 Mon Sep 17 00:00:00 2001
From: lintool
Date: Fri, 27 Jan 2012 00:09:00 -0500
Subject: [PATCH 2/7] Added integration tests for preprocessing Wikipedia.
---
data/vocab/en-sent.bin | Bin 0 -> 98533 bytes
data/vocab/en-token.bin | Bin 0 -> 439890 bytes
.../VerifyWikipediaProcessingMonolingual.java | 205 +++++++++++++++++-
.../data/document/WeightedIntDocVector.java | 8 +
.../core/driver/PreprocessWikipedia.java | 45 ++--
5 files changed, 225 insertions(+), 33 deletions(-)
create mode 100644 data/vocab/en-sent.bin
create mode 100644 data/vocab/en-token.bin
diff --git a/data/vocab/en-sent.bin b/data/vocab/en-sent.bin
new file mode 100644
index 0000000000000000000000000000000000000000..e89076be5ab24adc12ad9cdf14fe1299c4ff5e00
GIT binary patch
literal 98533
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