據我所知,MLlib只支持整數。
然後,我想將字符串轉換爲scala中的整數。 例如,我在txtfile中有很多reviewerID,productID。在Spark MLlib中,如何將字符串轉換爲spark scala中的整數?
reviewerID productID
03905X0912 ZXASQWZXAS
0325935ODD PDLFMBKGMS
...
據我所知,MLlib只支持整數。
然後,我想將字符串轉換爲scala中的整數。 例如,我在txtfile中有很多reviewerID,productID。在Spark MLlib中,如何將字符串轉換爲spark scala中的整數?
reviewerID productID
03905X0912 ZXASQWZXAS
0325935ODD PDLFMBKGMS
...
StringIndexer
是解決方案。它將用估計器和變壓器裝入ML管道。本質上,一旦設置了輸入列,它就會計算每個類別的頻率並將它們從0開始編號。如果需要,您可以在管道末端添加IndexToString
以替換原始字符串。
有關更多詳細信息,請參閱ML文檔以瞭解「估算,轉換和選擇特徵」。
在你的情況下,它會像:
import org.apache.spark.ml.feature.StringIndexer
val indexer = new StringIndexer().setInputCol("productID").setOutputCol("productIndex")
val indexed = indexer.fit(df).transform(df)
indexed.show()
您可以爲每個reviewerID(productID)添加一個具有唯一ID的新行。您可以通過以下方式添加新行。
通過monotonicallyIncreasingId
:
import spark.implicits._
val data = spark.sparkContext.parallelize(Seq(
("123xyx", "ab"),
("123xyz", "cd")
)).toDF("reviewerID", "productID")
data.withColumn("uniqueReviID", monotonicallyIncreasingId).show()
通過使用zipWithUniqueId
:
val rows = data.rdd.zipWithUniqueId.map {
case (r: Row, id: Long) => Row.fromSeq(id +: r.toSeq)
}
val finalDf = spark.createDataFrame(rows, StructType(StructField("uniqueRevID", LongType, false) +: data.schema.fields))
finalDf.show()
您還可以通過在SQL語法使用row_number()
做到這一點:
import spark.implicits._
val data = spark.sparkContext.parallelize(Seq(
("123xyx", "ab"),
("123xyz", "cd")
)).toDF("reviewerID", "productID").createOrReplaceTempView("review")
val tmpTable1 = spark.sqlContext.sql(
"select row_number() over (order by reviewerID) as id, reviewerID, productID from review")
希望這有助於!
At通過使用zipWithUniqueId,發生錯誤。 scala> val rows = data.rdd.zipWithUniqueId.map { | case(r:Row,id:Long)=> Row.fromSeq(id +:r.toSeq) | }
你試過我的例子嗎?如果是的話,它應該工作。 –
你能詳細闡述_你要什麼用整數做「據我所知,只有MLlib整數支持。」?你將使用什麼算法。爲您的**真實**問題提供解決方案會容易得多。這可能是ALS嗎?或者其他推薦算法? –
我將使用ALS算法,矩陣分解。 – DaehyunPark