columnSimilarities()
вычисляет сходства между столбцами из RowMatrix
, а не между строками, поэтому ваши "идентификаторы" не имеют смысла в этом контексте, а индексы являются индексами в каждом векторе признаков.
Кроме того, эти методы предназначены для длинных, узких и данных, поэтому очевидный подход - просто кодировать id
с помощью StringIndexer
, создавать IndedxedRowMatrix
, транспонировать, вычислять сходства и возвращаться (с IndexToString
) просто выиграл '
Ваша лучшая ставка здесь - взять crossJoin
df.as("a").crossJoin(df.as("b")).where($"a.id" <= $"b.id").select(
$"a.id" as "id_x", $"b.id" as "id_y", cosine_similarity($"a.values", $b.values")
)
, где
val cosine_similarity = udf((xs: Array[Double], ys: Array[Double]) => ???)
- это то, что вы должны реализовать сами.
В качестве альтернативы вы можете разбить данные:
import org.apache.spark.sql.functions.posexplode
val long = ds.select($"id", posexplode($"values")).toDF("item", "feature", "value")
, а затем использовать метод, показанный в Spark Scala - Как сгруппировать строки данных и применить комплексную функцию к группам? для вычисления сходства.