Spark中的潜在Dirichlet分配(LDA)-复制模型

时间:2019-02-04 12:17:29

标签: apache-spark pyspark lda

我想从pyspark ml-clustering包中保存LDA模型,并在保存后将其应用于训练和测试数据集。然而,尽管播下了种子,结果却有所不同。我的代码如下:

1)导入软件包

from pyspark.ml.clustering import LocalLDAModel, DistributedLDAModel
from pyspark.ml.feature import CountVectorizer , IDF

2)准备数据集

countVectors = CountVectorizer(inputCol="requester_instruction_words_filtered_complete", outputCol="raw_features", vocabSize=5000, minDF=10.0)
cv_model = countVectors.fit(tokenized_stopwords_sample_df)
result_tf = cv_model.transform(tokenized_stopwords_sample_df)
vocabArray = cv_model.vocabulary
idf = IDF(inputCol="raw_features", outputCol="features")
idfModel = idf.fit(result_tf)
result_tfidf = idfModel.transform(result_tf)
result_tfidf = result_tfidf.withColumn("id", monotonically_increasing_id())    
corpus = result_tfidf.select("id", "features")

3)训练LDA模型

lda = LDA(k=number_of_topics, maxIter=100, docConcentration = [alpha], topicConcentration = beta, seed = 123)
model = lda.fit(corpus)
model.save("LDA_model_saved")
topics = model.describeTopics(words_in_topic)  
topics_rdd = topics.rdd
modelled_corpus = model.transform(corpus)

4)复制模型

#Prepare the data set
countVectors = CountVectorizer(inputCol="requester_instruction_words_filtered_complete", outputCol="raw_features", vocabSize=5000, minDF=10.0)
cv_model = countVectors.fit(tokenized_stopwords_sample_df)
result_tf = cv_model.transform(tokenized_stopwords_sample_df)
vocabArray = cv_model.vocabulary
idf = IDF(inputCol="raw_features", outputCol="features")
idfModel = idf.fit(result_tf)
result_tfidf = idfModel.transform(result_tf)   
result_tfidf = result_tfidf.withColumn("id", monotonically_increasing_id())
corpus_new = result_tfidf.select("id", "features")

#Load the model to apply to new corpus
newModel = LocalLDAModel.load("LDA_model_saved")
topics_new = newModel.describeTopics(words_in_topic)  
topics_rdd_new = topics_new.rdd
modelled_corpus_new = newModel.transform(corpus_new)

尽管我认为相等,但以下结果是不同的: topics_rdd != topics_rdd_newmodelled_corpus != modelled_corpus_new(同样,在检查提取的主题时,它们与数据集上的预测类也不相同)

因此,即使我在模型生成中设置了种子,我还是感到奇怪的是,同一模型在同一数据集上预测了不同的类(“主题”)。有复制LDA模型经验的人可以提供帮助吗?

谢谢:)

1 个答案:

答案 0 :(得分:0)

在PYSPARK中实施LDA时,我遇到了类似的问题。即使我使用的是种子,每次我对具有相同参数的相同数据重新运行代码时,结果都是不同的。

尝试了多种方法后,我想出了以下解决方案:

  1. 运行一次后保存 cv_model ,并在下一次迭代中加载它,然后重新调整它。

  2. 这与我的数据集更相关。我使用的语料库中某些文档的大小很小(每个文档大约3个单词)。我过滤掉了这些文档并设置了一个限制,这样,语料库中将至少包含15个单词(可能更高)。我不确定为什么这个方法可行,可能与模型的下划线复杂度有关。

总而言之,即使经过多次迭代,我的结果也是相同的。希望这可以帮助。