2015-07-21 10 views
11

Come possiamo ottenere i primi 10 prodotti consigliati in PySpark. Capisco che ci sono metodi come recommendProducts per raccomandare prodotti per un singolo utente e predireTutto per prevedere la valutazione per la coppia {user, item}. Ma esiste un modo efficace per pubblicare i primi 10 articoli per ciascun utente per tutti gli utenti?Come raccomandare i primi 10 prodotti in Spark ALS per tutti gli utenti?

+0

Con Scala si può usare 'recommendProductsForUser', ma in questo momento questa funzione non è esposto attraverso PySpark API. – zero323

risposta

5

Ho scritto questa funzione che moltiplica le caratteristiche utente e le caratteristiche del prodotto per partizioni in modo che venga distribuito, quindi ottiene le valutazioni per ciascun prodotto per utente e le ordina in base alla valutazione e genera l'elenco di 8 prodotti consigliati.

#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 fornisce 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

In caso di valutazioni implicite, in cui gli utenti non valutano esplicitamente i prodotti, è possibile che non si desideri filtrare i dati di test. – hwaxxer

+0

Ma l'utente ha già eseguito un'azione (visualizzare, acquistare, qualsiasi cosa) su quell'elemento, vorremmo raccomandarlo a lui/lei? – tokland

+0

Non possiamo presumere che qualsiasi elemento "valutato" debba essere rimosso dai risultati. Un utente che interagisce con un oggetto può essere un forte indicatore del fatto che gli piace l'oggetto e che dovrebbe essere raccomandato a loro, indipendentemente dal fatto che lo abbiano già visto. La logica aziendale pertinente alle raccomandazioni, come il filtraggio di determinati articoli, è probabilmente la migliore da fare al di fuori del motore di raccomandazione. Altre API ci permettono di farlo, come [predictAll] (http://spark.apache.org/docs/latest/api/python/pyspark.mllib.html#pyspark.mllib.recommendation.MatrixFactorizationModel.predictAll). – hwaxxer

Problemi correlati