3

基本的な文の分割から始めて、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>
}

ジョブを実行すると、ログに「inはnullであってはなりません!」というエラーが表示されます。(クラススローエラーの原因)、これは、どういうわけか、モデルへのInputStreamを開くことができないことを意味します。その他の情報:

  • 参照先の場所にモデルファイルが存在することを確認しましたsentenceModelPath
  • opennlp-maxent:3.0.2-incubating、opennlp-tools:1.5.2-incubating、およびopennlp-uima:1.5.2-incubatingのMaven依存関係を追加しました。
  • Hadoopは私のローカルマシンで実行されています。

これのほとんどは、OpenNLPドキュメントの定型文です。Hadoop側またはOpenNLP側のいずれかで、モデルから読み取ることができなくなるような何かが欠けていますか?

4

1 に答える 1

6

あなたの問題はgetClass().getResourceAsStream(sentenceModelPath)線です。これにより、クラスパスからファイルが読み込まれます。HDFS内のファイルも、クライアントローカルファイルシステム上のファイルも、マッパー/レデューサーランタイムのクラスパスの一部ではないため、Nullエラー(getResourceAsStream())が表示されます。リソースが見つからない場合はnullを返します)。

これを回避するには、いくつかのオプションがあります。

  • コードを修正して、HDFSからファイルをロードします。

    modelIn = FileSystem.get(context.getConfiguration()).open(
                     new Path("/sandbox/corpus-analysis/nlp/en-sent.bin"));
    
  • コードを修正してローカルディレクトリからファイルをロードし、-filesGenericOptionsParserオプションを使用します(ローカルファイルシステムからHDFSにファイルをコピーし、実行中のマッパー/レデューサーのローカルディレクトリに戻します)。

    modelIn = new FileInputStream("en-sent.bin");
    
  • ファイルをジョブjar(jarのルートディレクトリ)にハードベイクし、コードを修正して先頭にスラッシュを含めます。
    modelIn = getClass().getResourceAsStream("/en-sent.bin");</li>
    

于 2012-05-14T23:51:52.723 に答える