Java 处理Spark数据帧时如何加载外部模型?

Java 处理Spark数据帧时如何加载外部模型?,java,apache-spark,spark-dataframe,Java,Apache Spark,Spark Dataframe,我目前正在尝试处理大量文本。作为这个过程的一部分,我想做一些事情,比如标记化和词干分析。但是,我的一些步骤需要加载外部模型(例如。我目前正在尝试以下方法: SparkConf sparkConf = new SparkConf().setAppName("Spark Tokenizer"); JavaSparkContext sparkContext = new JavaSparkContext(sparkConf); SQLContext sqlContext = ne

我目前正在尝试处理大量文本。作为这个过程的一部分,我想做一些事情,比如标记化和词干分析。但是,我的一些步骤需要加载外部模型(例如。我目前正在尝试以下方法:

    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");
我正在尝试的当前方法是使用一个非AryTransformer

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
        }
    }

}
公共类标记器扩展UnaryTransformer实现可序列化{
私有的最终静态字符串uid=Tokenizer.class.getSimpleName()+““+UUID.randomUUID().toString();
私有静态映射;
@凌驾
public void validateInputType(数据类型inputType){
断言(inputType.equals(DataTypes.StringType)):
String.format(“输入类型必须是%s,但得到的是%s”,DataTypes.StringType.simpleString(),inputType.simpleString());
}
公共函数1 createTransformFunc(){
Function1f=新的TokenizerFunction();
返回f;
}
公共数据类型outputDataType(){
返回DataTypes.createArrayType(DataTypes.StringType,true);
}
公共字符串uid(){
返回uid;
}
私有类TokenizerFunction扩展了AbstractFunction1实现了可序列化{
公共列表应用(字符串语句){
…代码在这里
}
}
}
现在我的问题是:

  • 加载模型的最佳时间是什么时候?我不想多次加载模型
  • 如何将模型分发到各个节点

  • 提前感谢,Spark有点让人望而生畏,但它看起来很有希望。

    您可以在驱动程序代码中加载模型,并将其作为属性存储在
    标记器
    对象中。模型将被序列化并自动传输到工作节点。这种方法还要求模型适合驾驶员的记忆


    否则,您可以在
    createTransformFunc()
    中加载模型,并将其作为属性存储在
    TokenizerFunction
    对象中。我相信通过这种方式,每个工作节点都将自己加载模型,尽管我不是100%确定。

    这似乎不起作用,因为OpenNLP类是不可序列化的。序列化堆栈:-对象不可序列化(类:opennlp.tools.tokenize.TokenizerME,值:opennlp.tools.tokenize)。TokenizerME@100fc5a)尝试第二种方法,并将ONLP模型作为瞬态属性存储在
    TokenizerFunction
    中。是否有关于这些瞬态属性的文档链接?我对他们不熟悉,谷歌在这方面也没什么帮助。