2015-10-02 2 views
1

TL; DR; Я пытаюсь обучить существующий набор данных (Seq[Words] с соответствующими категориями) и использовать этот подготовленный набор данных для фильтрации другого набора данных с использованием подобия категории.Как использовать RowMatrix.columnSymilarities (поиск подобия)

Я пытаюсь обучить корпус данных, а затем использовать его для анализа текста *. Я пробовал использовать NaiveBayes, но, похоже, работает только с данными, которые у вас есть, поэтому алгоритм прогнозирования всегда будет возвращать что-то, даже если он ничего не соответствует.

Итак, теперь я пытаюсь использовать TFIDF и передавать этот вывод в RowMatrix и вычислять сходства. Но я не уверен, как запустить мой запрос (одно слово на данный момент). Вот что я пытался:

val rddOfTfidfFromCorpus : RDD[Vector] 
val query = "word" 
val tf = new HashingTF().transform(List(query)) 
val tfIDF = new IDF().fit(sc.makeRDD(List(tf))).transform(tf) 
val mergedVectors = rddOfTfidfFromCorpus.union(sc.makeRDD(List(tfIDF))) 
val similarities = new RowMatrix(mergedVectors).columnSimilarities(1.0) 

Вот где я застрял (если я даже сделал все правильно, пока здесь). Я пробовал фильтровать similaritiesi и j вплоть до частей TFIDF моего запроса и заканчивать пустой коллекцией.

Суть в том, что я хочу тренироваться на корпусе данных и находить, в какую категорию он попадает. Вышеприведенный код, по крайней мере, пытается довести его до одной категории и проверить, могу ли я получить прогноз от как минимум ....

* Обратите внимание, что это игрушка пример, так что мне нужно только то, что работает достаточно хорошо * Я использую искру 1.4.0

+0

@ zero323 Исправлено, спасибо. И спасибо за редактирование кода .... забыл сдвинуть после того, как я закончил набирать –

+0

. Добро пожаловать. Итак, можно объяснить, что именно вы пытаетесь сделать здесь? Я не могу понять ваш код :(Какая-то кластеризация? Поиск подобия? – zero323

+0

Да. Поиск по подобию –

ответ

1

Использование columnSimilarities не имеет смысла здесь. Поскольку каждый столбец в вашей матрице представляет собой набор терминов, вы получите матрицу сходств между токенами, а не документами. Вы можете транспонировать матрицу, а затем использовать columnSimilarities, но насколько я понимаю, что вы хотите, это сходство между запросом и корпусом. Вы можете выразить это, используя умножение матрицы следующим образом:

Для начала вам понадобится IDFModel, который вы обучили на корпусе. Давайте предположим, что называется idf:

import org.apache.spark.mllib.feature.IDFModel 
val idf: IDFModel = ??? // Trained using corpus data 

и небольшой помощник:

def toBlockMatrix(rdd: RDD[Vector]) = new IndexedRowMatrix(
    rdd.zipWithIndex.map{case (v, i) => IndexedRow(i, v)} 
).toCoordinateMatrix.toBlockMatrix 

Первый позволяет преобразовать запрос РДУ и вычислительном TF:

val query: Seq[String] = ??? 
val queryTf = new HashingTF().transform(query) 

Далее мы можем применить IDF модель и преобразовать результат в матрицу:

val queryTfidf = idf.transform(queryTf) 
val queryMatrix = toBlockMatrix(queryTfidf) 

Нам нужна матрица мозолистое, а также:

val corpusMatrix = toBlockMatrix(rddOfTfidfFromCorpus) 

Если вы множественным как мы получим матрицу с числом строк, равным количеству докторов в запросе и число столбцов, равное количеству документов в корпусе.

val dotProducts = queryMatrix.multiply(corpusMatrix.transpose) 

Чтобы получить надлежащее косинуса сходство, вы должны разделить на произведение величин, но если вы можете справиться с этим.

Здесь есть две проблемы. Прежде всего, это довольно дорого. Более того, я не уверен, действительно ли это полезно.Чтобы снизить затраты, вы можете сначала применить алгоритм сокращения размерности, но теперь оставите его.

Судя по следующему заявлению

NaiveBayes (...), кажется, работает только с данными у вас есть, так что предсказать алгоритм всегда будет возвращать что-то, даже если он ничего не найдено.

Я думаю, вы хотите какой-то неконтролируемый метод обучения. Самая простая вещь, которую вы можете попробовать: K-означает:

import org.apache.spark.mllib.clustering.{KMeans, KMeansModel} 

val numClusters: Int = ??? 
val numIterations = 20 

val model = KMeans.train(rddOfTfidfFromCorpus, numClusters, numIterations) 
val predictions = model.predict(queryTfidf) 
+0

Принимается как ответ. ..Однако я все время сталкиваюсь с проблемами памяти из-за размера каждого вектора.Я могу попробовать использовать Word2Vec вместо TFIDF ... Мое понимание заключается в том, что это приведет к уменьшению объема памяти –

+0

В какой момент? K-означает или матричное умножение? – zero323

+0

В Kmeans есть где я oom –

Смежные вопросы