New to scala
(pyspark
guy) and trying to calculated cosine similarity between rows (items)
Followed this to create a sample df as an example:
Spark, Scala, DataFrame: create feature vectors
import org.apache.spark.ml.feature.VectorAssembler
val df = sc.parallelize(Seq(
(1, "cat1", 1), (1, "cat2", 3), (1, "cat9", 5), (2, "cat4", 6),
(2, "cat9", 2), (2, "cat10", 1), (3, "cat1", 5), (3, "cat7", 16),
(3, "cat8", 2))).toDF("userID", "category", "frequency")
// Create a sorted array of categories
val categories = df
.select($"category")
.distinct.map(_.getString(0))
.collect
.sorted
// Prepare vector assemble
val assembler = new VectorAssembler()
.setInputCols(categories)
.setOutputCol("features")
// Aggregation expressions
val exprs = categories.map(
c => sum(when($"category" === c, $"frequency").otherwise(lit(0))).alias(c))
val transformed = assembler.transform(
df.groupBy($"userID").agg(exprs.head, exprs.tail: _*))
.select($"userID", $"features")
transformed.show
+------+--------------------+
|userID| features|
+------+--------------------+
| 1|(7,[0,2,6],[1.0,3...|
| 3|(7,[0,4,5],[5.0,1...|
| 2|(7,[1,3,6],[1.0,6...|
+------+--------------------+
Trying to follow this post to convert the df into the IndexedRowMatrix
and having trouble with the scala
syntax on how to map the rdd
properly
Calculate Cosine Similarity Spark Dataframe
import org.apache.spark.sql.Row
val irm = new IndexedRowMatrix(transformed.rdd.map {
Row(_, v: org.apache.spark.ml.linalg.Vector) =>
org.apache.spark.mllib.linalg.Vectors.fromML(v)
}.zipWithIndex.map { case (v, i) => IndexedRow(i, v) })
<console>:5: error: not a legal formal parameter.
Note: Tuples cannot be directly destructured in method or function parameters.
Either create a single parameter accepting the Tuple1,
or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
Row(_, v: org.apache.spark.ml.linalg.Vector) =>
^
Thanks!