2016-02-24 10 views
5

Po pierwsze, mam historię użytkowania aplikacji użytkownika.Jak poprawić wyniki rekomendacji? Używam iskry ALS domyślnie

Na przykład:
użytk1, App1, 3 (czasy uruchamiania)
użytkownik2, App2 2 (czas uruchamiania)
Użytkownik3 App1, 1 (czas uruchamiania)

mam zasadniczo dwa żądania:

  1. Poleć niektóre aplikacje dla każdego użytkownika.
  2. Polecam podobną aplikację dla każdej aplikacji.

Używam więc ALS (implicit) z MLLib na iskrze, aby go zaimplementować. Na początku używam oryginalnych danych do szkolenia modelu. Rezultat jest okropny. Myślę, że może to wynikać z zakresu czasów uruchomienia. A czas uruchomienia wynosi od 1 do tysięcy. Przetwarzam oryginalne dane. Myślę, że wynik może odzwierciedlać prawdziwą sytuację i większą regularyzację. Wynik

= l/uMlt + l/aMlt

słabo jest wynikiem procesu szkolenia model.
lt Czas uruchomienia w oryginalnych danych.
uMlt to średnia czasy uruchomienia dla użytkownika w oryginalnych danych. uMlt (wszystkie czasy uruchomienia użytkownika)/(liczba aplikacji, które użytkownik kiedykolwiek uruchomił)
aMlt to czasy uruchamiania aplikacji w oryginalnych danych. aMlt (wszystkie czasy uruchomienia aplikacji)/(numer użytkownika, który kiedykolwiek uruchomił tę aplikację)
Oto przykład danych po przetworzeniu.

Ocena (95788,20992,0.14167073369026184)
Ocena (98696,20992,5.92363166809082)
Ocena (160020,11264,2.261538505554199)
Ocena (67904,11264,2.261538505554199)
Ocena (268430, 11264,0.13846154510974884)
Ocena (201369,11264,1.7999999523162842)
Ocena (180857,11264,2.2720916271209717)
Ocena (217692,11264,1.3692307472229004)
Ocena (186274,2867 2,2.4250855445861816)
Ocena (120820,28672,0.4422124922275543)
Ocena (221146,28672,1.0074234008789062)

Po Zrobiłem to i agregują aplikacje, które mają różne nazwy pakietu, wynik wydaje się lepsze . Ale wciąż nie jest wystarczająco dobry.
Uważam, że funkcje użytkowników i produktów są tak małe, a większość z nich jest negatywna.

Oto przykład 3 gamę produktów wymiarów elementów, 10 dla każdej linii:

((CompactBuffer (com.youlin.xyzs.shoumeng, com.youlin.xyzs.juhe.shoumeng)), (-4.798973236574966E-7, -7.641608021913271E-7,6.040852440492017E-7,2.82689171626771E-7, -4.255948056197667E-7,11,815822798789668E-7,5000047167413868E-7,2.0220664964654134E-7,6386763402588258E-7, -4,201261710255232 E-7))
((CompactBuffer (com.dncfcjaobhegbjccdhandkba.huojia)), (- 4,769295992446132E-5, -1,7072002810891718E-4,2.1351299074012786E-4,1.6345139010809362E-4, -1,4456869394052774E-4,2657657752899453044E -4, -4,508546771830879E-5,2.0895185298286378E-4,2.968782791867852E-4,1, 461760530248284E -4))
((CompactBuffer (com.tern.rest.pron)), (- 1.219763362314552E-5, -2,8371430744300596E-5,2.9869115678593516E-5,2.0747662347275764E-5, -2,0555471564875916E-5,2.632938776514493 E 5,2.934047643066151E-6,2.296348611707799E-5,3.8075613701948896E-5,1.2197584510431625E-5))

Oto 3 Przykład linia użytkowników funkcji, 10 wymiary dla każdej linii:

(96768, (- 0,0010857731103897095, -0.001926362863741815,0.0013726564357057214,6.345533765852451E-4 -9.048808133229613E-4 -4.1544197301846E-5,0.0014421759406104684, -9.77902309386991E-5,0.0010355513077229261, -0,0017878251383081079))
(97280, (- ,0022841691970825195, -0.0017134940717369318,0.001027365098707378,9.437055559828877E-4 -0.0011165080359205604,0.0017137592658400536,9.713359759189188E-4,8.947265450842679E-4,0.0014328152174130082, -5.738904583267868E-4))
(97792, (- +0,0017802991205826402, -0.003464450128376484,0.002837196458131075,0.0015725698322057724, -0.0018932095263153315,9.185600210912526E-4,0.0018971719546243548,7.250450435094535E-4,0.0027060359716415405, -0,0017731878906488419))

więc można sobie wyobrazić, jak małe kiedy się kropka iloczyn funkcji wektory do obliczania wartości macierzy elementów użytkownika.

Moje pytanie brzmi:

  1. Czy jest jakiś inny sposób na poprawę wyniku rekomendacji?
  2. Czy moje funkcje wyglądają prawidłowo, czy coś jest nie tak?
  3. Czy mogę przetworzyć oryginalne czasy uruchomienia (przekonwertować na wynik) prawda?

Wprowadzam tutaj kod. I to jest absolutnie pytanie programowe. Ale może nie da się tego rozwiązać za pomocą kilku linii kodu.

val model = ALS.trainImplicit(ratings, rank, iterations, lambda, alpha) 
print("recommendForAllUser") 
val userTopKRdd = recommendForAllUser(model, topN).join(userData.map(x => (x._2._1, x._1))).map { 
    case (uid, (appArray, mac)) => { 
    (mac, appArray.map { 
     case (appId, rating) => { 
     val packageName = appIdPriorityPackageNameDict.value.getOrElse(appId, Constants.PLACEHOLDER) 
     (packageName, rating) 
     } 
    }) 
    } 
} 
HbaseWriter.writeRddToHbase(userTopKRdd, "user_top100_recommendation", (x: (String, Array[(String, Double)])) => { 
    val mac = x._1 
    val products = x._2.map { 
    case (packageName, rating) => packageName + "=" + rating 
    }.mkString(",") 
    val putMap = Map("apps" -> products) 
    (new ImmutableBytesWritable(), Utils.getHbasePutByMap(mac, putMap)) 
}) 

print("recommendSimilarApp") 
println("productFeatures ******") 
model.productFeatures.take(1000).map{ 
    case (appId, features) => { 
    val packageNameList = appIdPackageNameListDict.value.get(appId) 
    val packageNameListStr = if (packageNameList.isDefined) { 
     packageNameList.mkString("(", ",", ")") 
    } else { 
     "Unknow List" 
    } 
    (packageNameListStr, features.mkString("(", ",", ")")) 
    } 
}.foreach(println) 
println("productFeatures ******") 
model.userFeatures.take(1000).map{ 
    case (userId, features) => { 
    (userId, features.mkString("(", ",", ")")) 
    } 
}.foreach(println) 
val similarAppRdd = recommendSimilarApp(model, topN).flatMap { 
    case (appId, similarAppArray) => { 
    val groupedAppList = appIdPackageNameListDict.value.get(appId) 
    if (groupedAppList.isDefined) { 
     val similarPackageList = similarAppArray.map { 
     case (destAppId, rating) => (appIdPriorityPackageNameDict.value.getOrElse(destAppId, Constants.PLACEHOLDER), rating) 
     } 
     groupedAppList.get.map(packageName => { 
     (packageName, similarPackageList) 
     }) 
    } else { 
     None 
    } 
    } 
} 
HbaseWriter.writeRddToHbase(similarAppRdd, "similar_app_top100_recommendation", (x: (String, Array[(String, Double)])) => { 
    val packageName = x._1 
    val products = x._2.map { 
    case (packageName, rating) => packageName + "=" + rating 
    }.mkString(",") 
    val putMap = Map("apps" -> products) 
    (new ImmutableBytesWritable(), Utils.getHbasePutByMap(packageName, putMap)) 
}) 

UPDATE:
Znalazłem coś nowego o moich danych po przeczytaniu papieru ("Collaborative Filtering za dorozumiane zbiorów danych feedback"). Moje dane są zbyt rzadkie w porównaniu do zestawu danych IPTV opisanego w artykule.

papieru: 300000 (użytkowników) 17.000 (produkty) 32.000.000 (dane)
Mine: 300000 (użytkowników) 31.000 (produkty) 700.000 (dane)

więc macierz dla użytkownika pozycja w zestaw danych papieru został wypełniony liczbą 0.00627 = (32 000 000/300 000/17 000). Proporcja mojego zbioru danych to 0,0000033. Myślę, że to oznacza, że ​​moja matryca elementów użytkownika jest 2000 razy rzadsza niż papier.
Czy to prowadzi do złych wyników? I jakikolwiek sposób na poprawę?

+0

Czy otrzymałeś jakąś aktualizację ze swojego problemu? Mam podobny problem. –

Odpowiedz

0

Są dwie rzeczy, które warto wypróbować:

  1. ujednolicić swoje dane tak, że ma zerową średnią i jednostkowej wariancji za wektorem użytkownika. Jest to częsty krok w wielu uczeniu maszynowym. Pomaga zredukować efekt wartości odstających, które powodują wartości zbliżone do zera, które widzisz.
  2. Usuń wszystkich użytkowników, którzy mają tylko jedną aplikację. Jedyną rzeczą, jakiej nauczysz się od tych użytkowników, jest nieco lepsza "średnia" wartość wyników aplikacji. Nie pomogą ci nauczyć się żadnych znaczących związków, czego tak naprawdę chcesz.

Po usunięciu użytkownika z modelu utracisz możliwość uzyskania rekomendacji dla tego użytkownika bezpośrednio z modelu, podając identyfikator użytkownika. Jednak i tak mają tylko jedną ocenę aplikacji. Zamiast tego możesz uruchomić wyszukiwanie KNN na macierzy produktów, aby znaleźć aplikacje najbardziej podobne do tych aplikacji dla użytkowników = rekomendacje.

Powiązane problemy