Сначала на всякий случай объясню, как я представлял документы, на которых хочу запустить модель LDA. Сначала я выполняю некоторую предварительную обработку, чтобы получить наиболее важные термины для человека во всех его документах, затем я получаю объединение всех наиболее важных слов.
val text = groupedByPerson.map(s => (s._1,preprocessing.run(s, numWords, stopWords)))
val unionText = text.flatMap(s=> s._2.map(l => l._2)).toSet
Я «токенизирую» все слова во всех документах с помощью регулярных выражений,
val df: Dataframe = ...
val regexpr = """[a-zA-Z]+""".r
val shaveText = df.select("text").map(row => regexpr.findAllIn(row.getString(0)).toSet)
val unionTextZip = unionText.zipWithIndex.toMap
Я также заметил, что мне нужно преобразовать строку 'words' в уникальное двойное значение, как в примере, приведенном в documents перед запуском модели LDA, поэтому я создал карту для преобразования всех слов.
val numbersText = shaveText.map(set => set.map(s => unionTextZip(s).toDouble))
Затем я создаю корпус
val corpus = numbersText.zipWithIndex.map(s => (s._2, Vectors.dense(s._1.toArray))).cache
Теперь я запускаю модель LDA
val ldaModel = new LDA().setK(3).run(corpus)
Когда я проверяю размер словаря, я замечаю, что он равен размеру первого документа в корпусе, несмотря на наличие документов с большими или меньшими словарями.
Поэтому матрица темы выдаст ошибку, которая выглядит примерно так
Exception in thread "main" java.lang.IndexOutOfBoundsException: (200,0) not in [-31,31) x [-3,3)
at breeze.linalg.DenseMatrix$mcD$sp.update$mcD$sp(DenseMatrix.scala:112)
at org.apache.spark.mllib.clustering.DistributedLDAModel$$anonfun$topicsMatrix$1.apply(LDAModel.scala:544)
at org.apache.spark.mllib.clustering.DistributedLDAModel$$anonfun$topicsMatrix$1.apply(LDAModel.scala:541)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)
at org.apache.spark.mllib.clustering.DistributedLDAModel.topicsMatrix$lzycompute(LDAModel.scala:541)
at org.apache.spark.mllib.clustering.DistributedLDAModel.topicsMatrix(LDAModel.scala:533)
at application.main.Main$.main(Main.scala:110)
at application.Main.main(Main.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Я подумал, что могу просто использовать вектор для представления набора слов. Должны ли векторы быть одинакового размера? То есть создать логическую функцию для каждого слова, независимо от того, есть оно в документе или нет?