Ich versuche Spark MLib ALS mit implizitem Feedback für kollaboratives Filtern zu verwenden. Eingabedaten haben nur zwei Felder userId
und productId
. Ich habe keine Produktbewertungen, nur Informationen darüber, welche Produkte Benutzer gekauft haben, das ist alles. So ALS trainieren ich benutze:Wie werden Einstellungen für das implizite ALS-Feedback in Collaborative Filtering festgelegt?
def trainImplicit(ratings: RDD[Rating], rank: Int, iterations: Int): MatrixFactorizationModel
(http://spark.apache.org/docs/1.0.0/api/scala/index.html#org.apache.spark.mllib.recommendation.ALS $)
Diese API erfordert Rating
Objekt:
Rating(user: Int, product: Int, rating: Double)
Auf der anderen Seite Dokumentation auf trainImplicit
sagt: Zug eine Matrix-Faktorisierung Modell eine RDD von "implicit preferences" Bewertungen von Benutzern zu einigen Produkten gegeben, in Form von (userID, productID, Präferenz) Paare.
Als ich eingestellt Rating/Präferenzen 1
wie in:
val ratings = sc.textFile(new File(dir, file).toString).map { line =>
val fields = line.split(",")
// format: (randomNumber, Rating(userId, productId, rating))
(rnd.nextInt(100), Rating(fields(0).toInt, fields(1).toInt, 1.0))
}
val training = ratings.filter(x => x._1 < 60)
.values
.repartition(numPartitions)
.cache()
val validation = ratings.filter(x => x._1 >= 60 && x._1 < 80)
.values
.repartition(numPartitions)
.cache()
val test = ratings.filter(x => x._1 >= 80).values.cache()
Und dann mit dem Zug AlSl:
val model = ALS.trainImplicit(ratings, rank, numIter)
ich 0,9 RMSE, was ein großer Fehler bei der Präferenzen ist unter 0 oder 1 Wert:
val validationRmse = computeRmse(model, validation, numValidation)
/** Compute RMSE (Root Mean Squared Error). */
def computeRmse(model: MatrixFactorizationModel, data: RDD[Rating], n: Long): Double = {
val predictions: RDD[Rating] = model.predict(data.map(x => (x.user, x.product)))
val predictionsAndRatings = predictions.map(x => ((x.user, x.product), x.rating))
.join(data.map(x => ((x.user, x.product), x.rating)))
.values
math.sqrt(predictionsAndRatings.map(x => (x._1 - x._2) * (x._1 - x._2)).reduce(_ + _)/n)
}
Also meine Frage ist: zu welchem Wert ue soll ich rating
in:
Rating(user: Int, product: Int, rating: Double)
für implizites Training (in ALS.trainImplicit
Methode)?
aktualisieren
mit:
val alpha = 40
val lambda = 0.01
ich:
Got 1895593 ratings from 17471 users on 462685 products.
Training: 1136079, validation: 380495, test: 379019
RMSE (validation) = 0.7537217888106758 for the model trained with rank = 8 and numIter = 10.
RMSE (validation) = 0.7489005441881798 for the model trained with rank = 8 and numIter = 20.
RMSE (validation) = 0.7387672873747732 for the model trained with rank = 12 and numIter = 10.
RMSE (validation) = 0.7310003522283959 for the model trained with rank = 12 and numIter = 20.
The best model was trained with rank = 12, and numIter = 20, and its RMSE on the test set is 0.7302343904091481.
baselineRmse: 0.0 testRmse: 0.7302343904091481
The best model improves the baseline by -Infinity%.
die immer noch ein großer Fehler ist, denke ich. Auch bekomme ich merkwürdige Grundlinienverbesserung, wo Grundlinienmodell einfach gemein ist (1).
Was das ist 'numPartitions' hier? Das ist eine interessante Frage. Auch für implizite Daten können wir wirklich einen RMSE bekommen, RMSE ist in 1-5 Likert richtig besser skaliert oder? –
Könntest du bitte sagen, was das hier für computeRMSE ist? Danke, –