2016-07-06 5 views
2

現在、大量のテキストを処理しようとしています。このプロセスの一環として、トークン化やステミングなどの処理を行いたいと考えています。しかし、いくつかのステップでは外部モデルをロードする必要があります(たとえば、OpenNLP tokenizers)。私は現在、次のアプローチを試みています:Spark Dataframesの処理時に外部モデルをロードする方法は?

SparkConf sparkConf = new SparkConf().setAppName("Spark Tokenizer"); 
    JavaSparkContext sparkContext = new JavaSparkContext(sparkConf); 
    SQLContext sqlContext = new SQLContext(sparkContext); 
    DataFrame corpus = sqlContext.read().text("/home/zezke/document.nl"); 

    // Create pipeline components 
    Tokenizer tokenizer = new Tokenizer() 
      .setInputCol("value") 
      .setOutputCol("tokens"); 
    DataFrame tokenizedCorpus = tokenizer.transform(corpus); 

    // Save the output 
    tokenizedCorpus.write().mode(SaveMode.Overwrite).json("/home/zezke/experimentoutput"); 

私が試みている現在のアプローチは、UnaryTransformerを使用しています。

public class Tokenizer extends UnaryTransformer<String, List<String>, Tokenizer> implements Serializable { 

    private final static String uid = Tokenizer.class.getSimpleName() + "_" + UUID.randomUUID().toString(); 

    private static Map<String, String> stringReplaceMap; 

    @Override 
    public void validateInputType(DataType inputType) { 
     assert (inputType.equals(DataTypes.StringType)) : 
       String.format("Input type must be %s, but got %s", DataTypes.StringType.simpleString(), inputType.simpleString()); 
    } 

    public Function1<String, List<String>> createTransformFunc() { 
     Function1<String, List<String>> f = new TokenizerFunction(); 
     return f; 
    } 

    public DataType outputDataType() { 
     return DataTypes.createArrayType(DataTypes.StringType, true); 
    } 

    public String uid() { 
     return uid; 
    } 

    private class TokenizerFunction extends AbstractFunction1<String, List<String>> implements Serializable { 
     public List<String> apply(String sentence) { 
      ... code goes here 
     } 
    } 

} 

は今私の質問は以下のとおりです。

  1. モデルをロードするための最良の時間は何?私はモデルを複数回ロードしたくありません。
  2. モデルをさまざまなノードに配布するにはどうすればよいですか?

事前に感謝しますが、スパークは少し難しいですが、それは有望です。

答えて

0

ドライバコードにモデルをロードして、Tokenizerオブジェクトに属性として格納することができます。モデルはシリアライズされ、ワー​​カーノードに自動的に転送されます。この方法では、モデルがドライバのメモリ内に収まる必要があります。

createTransformFunc()の中にモデルをロードして、TokenizerFunctionオブジェクトを属性として格納することができます。私はこの方法を信じていますが、各作業者ノードはモデルを独自にロードしますが、100%確実ではありません。

+0

OpenNLPクラスは直列化できないため、動作しないようです。 シリアル化スタック: - オブジェクト直列化可能ではない(クラス:opennlp.tools.tokenize.TokenizerME、値:[email protected]) –

+0

第二の方法を試し、そして 'の過渡属性としてONLPモデルを格納しますTokenizerFunction' – Dikei

+0

これらの一時的な属性に関するドキュメントへのリンクがありますか?私はそれらに精通していないし、Googleはその問題に役立つではありません。 –

関連する問題