Я работаю над проблемой поиска информации и, чтобы найти расстояние между запросом и вектором документа, я делаю матричное умножение между IndexedRowMatrix и LocalMatrix. Однако я не уверен, как отследить, какая оценка принадлежит какой паре запрос-документ, так как идентификаторы LocalMatrix не доступны в результате умножения матрицы.
Вот моя проблема в более подробно: у меня есть две матрицы: одна матрица запросов (df1), которая является относительно небольшой, и одна матрица документов (df2), которая является очень большой (и, следовательно, не может быть собрана oid).
(Мои извинения за то, что я не публикую код для их воспроизведения, я не знал, как это сделать в короткие сроки, и не сделал ' Не нужно загрязнять вопрос фактическим кодом, который использует Tokenizer, CountVectorizer и Normalizer для получения этого результата.)
Цель состоит в том, чтобы найти косинусное сходство между каждой из комбинаций запроса и документа. Чтобы добиться этого, я нормализовал обе матрицы и искал точечное произведение между каждой комбинацией запроса и документа путем умножения двух матриц.
Я превратил матрицу запросов в LocalMatrix, содержащую QueryID и вектор нормализованных весов, а матрицу документа в IndexedRowMatrix, содержащий DocID и вектор нормализованных весов, и умножил их на два.
Итак, вот так:
df1 = IndexedRowMatrix(un_queries.select('QueryID', 'norm_features').rdd.map(lambda r: IndexedRow(r.QueryID, r.norm_features.toArray())))
df1 = df1.toBlockMatrix().transpose().toLocalMatrix()
df2 = IndexedRowMatrix(documents.select('doc_id', 'norm_features').rdd.map(lambda r: IndexedRow(r.doc_id, r.norm_features.toArray())))
cos_scores = df2.multiply(df1)
# Convert scores back to a spark dataframe
cos_scores = cos_scores.rows.map(lambda x: (x, )).toDF().select(col("_1.index").alias("doc_id"),
col("_1.vector").alias("scores"))
Итак, у меня есть кадр данных с документом и вектором баллов в каждой строке. Каждая из этих оценок представляет запрос. Моя цель - получить фрейм данных со строкой для каждой пары запрос-документ и сопровождающей оценкой, поэтому я делаю:
def dense_to_array(v):
new_array = list([float(x) for x in v])
return new_array
dense_to_array_udf = udf(dense_to_array, ArrayType(FloatType()))
cos_scores_total = cos_scores.withColumn("query_scores", dense_to_array_udf("scores")).drop("scores")
# Explode to achieve format: doc_id - q_id - score
qdoc_scores_total = qdoc_scores_total.withColumn("query", explode("query_scores"))
Как узнать, какая оценка принадлежит какому запросу? Поэтому я хочу иметь QueryID для каждой строки. Могу ли я просто предположить, что заказ не изменился из-за моих операций?