scala - 是否可以将 word2vec 预训练的可用向量加载到 Spark 中?

标签 scala apache-spark stanford-nlp word2vec

有没有办法加载Google'sGlove's预先训练的向量(模型),例如 GoogleNews-vectors-negative300.bin.gz进入 Spark 并执行 Spark 提供的诸如 findSynonyms 之类的操作?还是我需要从头开始加载和操作?

在这篇文章中Load Word2Vec model in Spark ,Tom Lous 建议将 bin 文件转换为 txt 并从那里开始,我已经这样做了..但是下一步是什么?

在我昨天发布的一个问题中,我得到了一个答案,即 Parquet 格式的模型可以加载到 Spark 中,因此我发布这个问题是为了确保没有其他选择。

最佳答案

免责声明:我对 Spark 还很陌生,但以下至少对我有用。

诀窍在于弄清楚如何从一组词向量构建 Word2VecModel 以及处理尝试以这种方式创建模型时遇到的一些问题。

首先,将词向量加载到 map 中。例如,我已将单词向量保存为 Parquet 格式(在名为“wordvectors.parquet”的文件夹中),其中“term”列保存字符串单词,“向量”列将向量保存为数组[float],我可以像 Java 中那样加载它:

// Loads the dataset with the "term" column holding the word and the "vector" column 
// holding the vector as an array[float] 
Dataset<Row> vectorModel = pSpark.read().parquet("wordvectors.parquet");

//convert dataset to a map.
Map<String, List<Float>> vectorMap = Arrays.stream((Row[])vectorModel.collect())
            .collect(Collectors.toMap(row -> row.getAs("term"), row -> row.getList(1)));

//convert to the format that the word2vec model expects float[] rather than List<Float>
Map<String, float[]> word2vecMap = vectorMap.entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, entry -> (float[]) Floats.toArray(entry.getValue())));

//need to convert to scala immutable map because that's what word2vec needs
scala.collection.immutable.Map<String, float[]> scalaMap = toScalaImmutableMap(word2vecMap);

private static <K, V> scala.collection.immutable.Map<K, V> toScalaImmutableMap(Map<K, V> pFromMap) {
        final List<Tuple2<K,V>> list = pFromMap.entrySet().stream()
                .map(e -> Tuple2.apply(e.getKey(), e.getValue()))
                .collect(Collectors.toList());

        Seq<Tuple2<K,V>> scalaSeq = JavaConverters.asScalaBufferConverter(list).asScala().toSeq();

        return (scala.collection.immutable.Map<K, V>) scala.collection.immutable.Map$.MODULE$.apply(scalaSeq);
    }

现在您可以从头开始构建模型。由于 Word2VecModel 工作方式的一个怪癖,您必须手动设置向量大小,并且以一种奇怪的方式进行设置。否则,它默认为 100,并且在尝试调用 .transform() 时会出现错误。这是我发现的一种可行的方法,不确定是否一切都必要:

 //not used for fitting, only used for setting vector size param (not sure if this is needed or if result.set is enough
Word2Vec parent = new Word2Vec();
parent.setVectorSize(300);

Word2VecModel result = new Word2VecModel("w2vmodel", new org.apache.spark.mllib.feature.Word2VecModel(scalaMap)).setParent(parent);
        result.set(result.vectorSize(), 300);

现在您应该能够像使用自训练模型一样使用 result.transform() 。

我没有测试其他 Word2VecModel 函数来查看它们是否正常工作,我只测试了 .transform()。

关于scala - 是否可以将 word2vec 预训练的可用向量加载到 Spark 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45506511/

相关文章:

hadoop - 无法获取 Master Kerberos 主体以用作 Talend 批处理作业的更新程序

python - 使用斯坦福 NLP for python 进行信息提取和关系提取

stanford-nlp - 斯坦福 NER 中的交叉验证

scala - 真值和假值

scala - Spark RDD - 它们是如何工作的

scala - Flink 的 JDBC 接收器失败并出现不可序列化错误

powershell - 尝试运行 Spark Submit、Hadoop 和其他命令行命令

java - 如何将 SUTime 对象转换为常规日历或日期对象?

scala - 使用 Spark 将 csv.gz 文件转换为 Parquet

scala - scala.js 1.0 中的@JSGlobalScope(JavaScriptException、ReferenceError、var 未定义)