2017-01-10 64 views
7

Modelleri toplu olarak eğiten işlemler arasında derecelendirmeler tahmin ediyorum. ALS model - öngörülen full_u * v^t * v puanları çok yüksek

import json 
import numpy as np 

pf = model.productFeatures() 

pf_vals = pf.sortByKey().values().collect() 
pf_keys = pf.sortByKey().keys().collect() 

Vt = np.matrix(np.asarray(pf_vals)) 

full_u = np.zeros(len(pf_keys)) 

def set_rating(pf_keys, full_u, key, val): 
    try: 
     idx = pf_keys.index(key) 
     full_u.itemset(idx, val) 
    except: 
     pass 

set_rating(pf_keys, full_u, 260, 9), # Star Wars (1977) 
set_rating(pf_keys, full_u, 1, 8), # Toy Story (1995) 
set_rating(pf_keys, full_u, 16, 7), # Casino (1995) 
set_rating(pf_keys, full_u, 25, 8), # Leaving Las Vegas (1995) 
set_rating(pf_keys, full_u, 32, 9), # Twelve Monkeys (a.k.a. 12 Monkeys) (1995) 
set_rating(pf_keys, full_u, 335, 4), # Flintstones, The (1994) 
set_rating(pf_keys, full_u, 379, 3), # Timecop (1994) 
set_rating(pf_keys, full_u, 296, 7), # Pulp Fiction (1994) 
set_rating(pf_keys, full_u, 858, 10), # Godfather, The (1972) 
set_rating(pf_keys, full_u, 50, 8) # Usual Suspects, The (1995) 

recommendations = full_u*Vt*Vt.T 

top_ten_ratings = list(np.sort(recommendations)[:,-10:].flat) 

print("predicted rating value", top_ten_ratings) 

top_ten_recommended_product_ids = np.where(recommendations >= np.sort(recommendations)[:,-10:].min())[1] 
top_ten_recommended_product_ids = list(np.array(top_ten_recommended_product_ids)) 

print("predict rating prod_id", top_ten_recommended_product_ids) 

tahmin derecelendirme yol çok yüksek görünüyor Ancak ... ALS model - how to generate full_u * v^t * v?

! rm -rf ml-1m.zip ml-1m 
! wget --quiet http://files.grouplens.org/datasets/movielens/ml-1m.zip 
! unzip ml-1m.zip 
! mv ml-1m/ratings.dat . 

from pyspark.mllib.recommendation import Rating 

ratingsRDD = sc.textFile('ratings.dat') \ 
       .map(lambda l: l.split("::")) \ 
       .map(lambda p: Rating(
            user = int(p[0]), 
            product = int(p[1]), 
            rating = float(p[2]), 
           )).cache() 

from pyspark.mllib.recommendation import ALS 

rank = 50 
numIterations = 20 
lambdaParam = 0.1 
model = ALS.train(ratingsRDD, rank, numIterations, lambdaParam) 

Ardından ürün özelliklerini ayıklamak:

('predicted rating value', [313.67320347694897, 315.30874327316576, 317.1563289268388, 317.45475214423948, 318.19788673744563, 319.93044594688428, 323.92448427140653, 324.12553531632761, 325.41052886977582, 327.12199687047649]) 
('predict rating prod_id', [49, 287, 309, 558, 744, 802, 1839, 2117, 2698, 3111]) 

Bu görünür Burada belirtilen yaklaşımı kullanıyorum yanlış olmak. Herhangi bir ipucu takdir edildi.

+1

Bunu kullanarak iyi sonuçlar elde ettim, ancak bu örtük geri bildirimle yapıldı, derecelendirmeler negatif veya bilinmeyen için 0 ve pozitif için 1 idi. 0 ile 1 arasında bir tahmin aldım ve bir metrik olarak rütbe kullanıyorum, yani puanlara fazla dikkat etmedim. –

+0

Ah, ilginç. Henüz gizli bir geri bildirim almadım. Yorumunuzu bir yanıt olarak gönderirseniz, başka kimse cevap vermezse varsayılan olarak ödül kazanırsınız;) –

+0

@ yoh.lej Ah, bu neden Chris gibi şişirilmiş derecelendirmeler aldığımı açıklıyor! Yani varsayım, o zaman derecelendirmelerin ikili olduğunu. Yohan, bu formülün neye dayandığını kısaca anlatabilir misin? Benzerlik ölçütlerini denedim ve görmedim. Benzerliği neye hesaplıyoruz? İlgi duyuyorum çünkü şu anda lineer cebir sınıfını alıyorum. Sadece mantıksal olarak, bu yeni kullanıcının hangi kullanıcıya benzediğini belirlemek istiyoruz ve derecelendirmeleri öngörmek için faktörlerini kullanıyoruz - bu yaklaşım daha karmaşık mı? Teşekkürler! (Chris - ALS'yi kontrol et.trainImplicit) – ScottEdwards2000

cevap

5

Bahsettiğim yaklaşım, yalnızca filmlerin sıralamasını önemsiyorsanız işe yarayacaktır. Gerçek bir derecelendirme almak istiyorsanız, boyut/ölçeklendirme açısından bir şey var gibi görünmektedir.

Buradaki fikir, yeni kullanıcınızın gizli temsilini tahmin etmektir. Normalde, faktorizasyonda bulunan bir kullanıcı için, kullanıcı i, u_i (model.userFeatures() içinde ith satırında) onun gizli temsilini var ve model.predict kullanarak temel bir şekilde u_i çarpanı tarafından gizli gösterim tarafından verilen bir film (film j) Ürün v_j. Tüm v: u_i*v ile çarptığınızda, tüm tahmini puanları bir kerede alabilirsiniz.

Yeni bir kullanıcı için numaralı gizli temsilinin ne olduğunu full_u_new numaralı telefondan öğrenebilirsiniz. Temel olarak, yeni kullanıcı ilişkinizi her bir gizli ürün faktörüne doğru temsil eden 50 katsayılar istiyorsunuz. Basitlik için ve örtülü geri bildirim kullanım durumum için yeterli olduğundan, ben sadece yeni kullanıcıyı ürün latent faktörüne yansıtan nokta ürününü kullandım: full_u_new*V^t size 50 katsayı verir, katsayı yeni kullanıcının nasıl göründüğünü ürün latent factor i. ve örtülü geri bildirim ile özellikle iyi çalışır. Yani, nokta ürününü kullanarak bunu size verecek ama ölçeklendirilmeyecek ve gördüğünüz yüksek puanları açıklıyor. Eğer daha doğru u_new ölçekli gerek kullanışlı puan almış olmak, onlar [buradan] yaptığım gibi https://github.com/apache/incubator-predictionio/blob/release/0.10.0/examples/scala-parallel-recommendation/custom-query/src/main/scala/ALSAlgorithm.scala

yorumunda @ ScottEdwards2000 bahsettiği yaklaşım çok ilginç, kosinüs benzerliği kullanarak o alabilir düşünüyorum, ama daha ziyade farklı. Gerçekten de eğitim setinizde en benzer kullanıcı (lar) ı arayabilirsiniz. Eğer birden fazla varsa ortalamayı alabilirsiniz. Çok kötü olacağını düşünmüyorum ama bu gerçekten farklı bir yaklaşım ve tam derecelendirme matrisine ihtiyacınız var (en benzer kullanıcıları bulmak için). Bir yakın kullanıcıyı almak, ölçekleme problemini kesinlikle çözmelidir. Her iki yaklaşımı da yönetmeyi başarırsanız sonuçları karşılaştırabilirsiniz!

İlgili konular