2015-07-21 2 views
11

Wie können wir Top 10 empfohlene Produkte in PySpark bekommen. Ich verstehe, dass es Methoden wie recommendProducts gibt, um Produkte für einen einzelnen Benutzer zu empfehlen, und predictAll, um die Bewertung für das Paar {user, item} vorherzusagen. Aber gibt es eine effiziente Möglichkeit, die Top 10 Elemente für jeden Benutzer für alle Benutzer auszugeben?Wie empfehlen Top 10 Produkte in Spark ALS für alle Benutzer?

+0

Mit Scala können Sie 'recommendProductsForUser' verwenden, aber in diesem Moment ist diese Funktion nicht durch PySpark API ausgesetzt. – zero323

Antwort

5

Ich schrieb diese Funktion, die Benutzerfunktionen und Produktfunktionen durch Partitionen vervielfacht, so dass es verteilt wird, dann erhält es die Bewertungen für jedes Produkt nach Benutzer und sortiert sie nach Bewertung und gibt die Liste der 8 Top empfohlenen Produkte.

#Collect product feature matrix 
productFeatures = bestModel.productFeatures().collect() 
productArray=[] 
productFeaturesArray=[] 
for x in productFeatures: 
    productArray.append(x[0]) 
    productFeaturesArray.append(x[1]) 
matrix=np.matrix(productFeaturesArray) 
productArrayBroadCast=sc.broadcast(productArray) 
productFeaturesArraybroadcast=sc.broadcast(matrix.T) 

def func(iterator): 
     userFeaturesArray = [] 
     userArray = [] 
     for x in iterator: 
      userArray.append(x[0]) 
      userFeaturesArray.append(x[1]) 
      userFeatureMatrix = np.matrix(userFeaturesArray) 
      userRecommendationArray = userFeatureMatrix*(productFeaturesArraybroadcast.value) 
      mappedUserRecommendationArray = [] 
      #Extract ratings from the matrix 
      i=0 
      for i in range(0,len(userArray)): 
       ratingdict={} 
       j=0 
       for j in range(0,len(productArrayBroadcast.value)): 
        ratingdict[str(productArrayBroadcast.value[j])]=userRecommendationArray.item((i,j)) 
        j=j+1 
       #Take the top 8 recommendations for the user 
       sort_apps=sorted(ratingdict.keys(), key=lambda x: x[1])[:8] 
       sort_apps='|'.join(sort_apps) 
       mappedUserRecommendationArray.append((userArray[i],sort_apps)) 
       i=i+1 
     return [x for x in mappedUserRecommendationArray] 


recommendations=model.userFeatures().repartition(2000).mapPartitions(func) 
4

PySpark> = 1.6.0 bietet MatrixFactorizationModel.recommendProductsForUsers:

>> model.recommendProductsForUsers(3).take(2) 
[(1, 
    (Rating(user=1, product=2975, rating=0.003626774788608227), 
    Rating(user=1, product=1322, rating=0.002494393082165332), 
    Rating(user=1, product=8746, rating=0.002176665942528324))), 
(2, 
    (Rating(user=2, product=4060, rating=0.011020947406565042), 
    Rating(user=2, product=2332, rating=0.009479319983658458), 
    Rating(user=2, product=1979, rating=0.004587168057824856)))] 
+0

Bei impliziten Bewertungen, bei denen Benutzer Produkte nicht explizit bewerten, möchten Sie möglicherweise keine Testdaten herausfiltern. – hwaxxer

+0

Aber der Benutzer hat bereits eine Aktion (Ansicht, Kauf, was auch immer) an diesem Objekt ausgeführt, möchten Sie es ihm/ihr empfehlen? – tokland

+0

Wir können nicht davon ausgehen, dass irgendein "bewerteter" Gegenstand aus den Ergebnissen entfernt werden muss. Ein Benutzer, der mit einem Gegenstand interagiert, kann ein starker Indikator dafür sein, dass er den Gegenstand mag und dass er ihnen empfohlen werden sollte, unabhängig davon, ob sie ihn vorher gesehen haben oder nicht. Die Geschäftslogik zu den Empfehlungen, z. B. das Ausfiltern bestimmter Elemente, wird wahrscheinlich am besten außerhalb der Empfehlungs-Engine ausgeführt. Andere APIs lassen uns dies tun, wie [predictAll] (http://spark.apache.org/docs/latest/api/python/pyspark.mllib.html#pyspark.mllib.recommendation.MatrixFactorizationModel.predictAll). – hwaxxer