Cyr*_*nix 3 hadoop mapreduce opennlp
我正在尝试将OpenNLP集成到Hadoop上的map-reduce工作中,从一些基本的句子分割开始.在map函数中,运行以下代码:
public AnalysisFile analyze(String content) {
InputStream modelIn = null;
String[] sentences = null;
// references an absolute path to en-sent.bin
logger.info("sentenceModelPath: " + sentenceModelPath);
try {
modelIn = getClass().getResourceAsStream(sentenceModelPath);
SentenceModel model = new SentenceModel(modelIn);
SentenceDetectorME sentenceBreaker = new SentenceDetectorME(model);
sentences = sentenceBreaker.sentDetect(content);
} catch (FileNotFoundException e) {
logger.error("Unable to locate sentence model.");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (modelIn != null) {
try {
modelIn.close();
} catch (IOException e) {
}
}
}
logger.info("number of sentences: " + sentences.length);
<snip>
}
Run Code Online (Sandbox Code Playgroud)
当我运行我的工作时,我在日志中收到一条错误,说"不能为空!" (类抛出错误的来源),这意味着我无法以某种方式打开一个InputStream到模型.其他花絮:
sentenceModelPath所指的位置.其中大部分是OpenNLP文档中的样板文件.在Hadoop方面或OpenNLP方面,我是否缺少某些东西,这会导致我无法从模型中读取?
你的问题就在getClass().getResourceAsStream(sentenceModelPath)于此.这将尝试从类路径加载文件 - HDFS中的文件和客户端本地文件系统上的文件都不是mapper/reducer运行时的类路径的一部分,因此这就是为什么你看到Null错误(getResourceAsStream()如果找不到资源,则返回null).
要解决这个问题,您有很多选择:
修改您的代码以从HDFS加载文件:
Run Code Online (Sandbox Code Playgroud)modelIn = FileSystem.get(context.getConfiguration()).open( new Path("/sandbox/corpus-analysis/nlp/en-sent.bin"));
修改您的代码以从本地目录加载文件,并使用-filesGenericOptionsParser选项(从本地文件系统复制到文件到HDFS,然后返回到正在运行的映射器/ reducer的本地目录):
Run Code Online (Sandbox Code Playgroud)modelIn = new FileInputStream("en-sent.bin");
Run Code Online (Sandbox Code Playgroud)modelIn = getClass().getResourceAsStream("/en-sent.bin");</li>