Sustav za preporuku filtriranja u suradnji s Javom

1. Uvod

U ovom uputstvu naučit ćemo sve o algoritmu Slope One u Javi.

Pokazat ćemo i primjer provedbe za problem kolaborativnog filtriranja (CF) - tehnike strojnog učenja koriste sustavi preporuka.

To se može koristiti, na primjer, za predviđanje korisničkih interesa za određene stavke.

2. Suradničko filtriranje

Algoritam Slope One sustav je suradničkog filtriranja zasnovan na stavkama. To znači da se u potpunosti temelji na rangiranju stavki korisnika. Kada izračunavamo sličnost među objektima, znamo samo povijest rangiranja, a ne sam sadržaj. Ta se sličnost zatim koristi za predviđanje rangiranja potencijalnih korisnika za parove korisnik-stavka koji nisu prisutni u skupu podataka.

Slika ispod prikazuje cjelovit postupak dobivanja i izračunavanja ocjene za određenog korisnika:

U početku korisnici ocjenjuju različite stavke u sustavu. Dalje, algoritam izračunava sličnosti. Nakon toga sustav izrađuje predviđanja za ocjene korisničkih stavki, koje korisnik još nije ocijenio.

Za više detalja o temi suradničkog filtriranja možemo se obratiti članku Wikipedije.

3. Algoritam nagiba jedan

Slope One imenovan je najjednostavnijim oblikom netrivijalnog filtriranja na temelju stavki na temelju ocjena. Za izračunavanje matrice sličnosti uzimaju se podaci svih korisnika koji su ocijenili istu stavku i ostalih stavki koje je ocijenio isti korisnik.

U našem jednostavnom primjeru predvidjet ćemo rangiranje korisnika na artiklima u trgovini.

Počnimo s jednostavnim Java modelom za naš problem i domenu.

3.1. Java model

U našem modelu imamo dva glavna predmeta - predmete i korisnike. The Artikal klasa sadrži naziv predmeta:

private String itemName;

S druge strane, Korisnik klasa sadrži korisničko ime:

privatno korisničko ime niza;

Napokon, imamo a InputData klasa koja će se koristiti za inicijalizaciju podataka. Pretpostavimo da ćemo u trgovini stvoriti pet različitih proizvoda:

Stavke na popisu = Arrays.asList (nova stavka ("Candy"), nova stavka ("Piće"), nova stavka ("soda"), nova stavka ("kokice"), nova stavka ("grickalice"));

Štoviše, stvorit ćemo tri korisnika koji su nasumično ocijenili neke od gore spomenutih koristeći ljestvicu od 0,0-1,0, gdje 0 znači da nema interesa, 0,5 nekako zanima i 1,0 znači potpuno zainteresirano. Kao rezultat inicijalizacije podataka dobit ćemo Karta s podacima o rangiranju stavki korisnika:

Karta podaci;

3.2. Matrice razlika i frekvencija

Na temelju dostupnih podataka izračunat ćemo odnose između stavki, kao i broj pojavljivanja predmeta. Za svakog korisnika provjeravamo njegovu ocjenu predmeta:

za (HashMap korisnik: data.values ​​()) {za (Unos e: user.entrySet ()) {// ...}}

U sljedećem koraku provjeravamo postoji li stavka u našim matricama. Ako je ovo prva pojava, kreiramo novi unos na kartama:

if (! diff.containsKey (e.getKey ())) {diff.put (e.getKey (), novi HashMap ()); freq.put (e.getKey (), novi HashMap ()); } 

Prva matrica koristi se za izračunavanje razlika između korisničkih ocjena. Vrijednosti mogu biti pozitivne ili negativne (jer bi razlika između ocjena mogla biti negativna) i pohranjuju se kao Dvostruko. S druge strane, frekvencije se pohranjuju kao Cijeli broj vrijednosti.

U sljedećem ćemo koraku usporediti ocjene svih stavki:

za (Unos e2: user.entrySet ()) {int oldCount = 0; if (freq.get (e.getKey ()). containsKey (e2.getKey ())) {oldCount = freq.get (e.getKey ()). get (e2.getKey ()). intValue (); } dvostruko oldDiff = 0,0; if (diff.get (e.getKey ()). containsKey (e2.getKey ())) {oldDiff = diff.get (e.getKey ()). get (e2.getKey ()). doubleValue (); } dvostruko opaženoDiff = e.getValue () - e2.getValue (); freq.get (e.getKey ()). put (e2.getKey (), oldCount + 1); diff.get (e.getKey ()). put (e2.getKey (), oldDiff + obserDiff); }

Ako je netko stavku ocijenio prije, povećavamo broj frekvencija za jedan. Štoviše, provjeravamo prosječnu razliku između ocjena proizvoda i izračunavamo novo primijetioDiff.

Imajte na umu da smo stavili zbroj od oldDiff i primijetioDiff kao nova vrijednost predmeta.

Na kraju izračunavamo ocjene sličnosti unutar matrica:

for (Item j: diff.keySet ()) {for (Item i: diff.get (j) .keySet ()) {double oldValue = diff.get (j) .get (i) .doubleValue (); int count = freq.get (j) .get (i) .intValue (); diff.get (j) .put (i, oldValue / count); }}

Glavna logika je podijeliti razliku izračunate ocjene predmeta s brojem njegovih pojavljivanja. Nakon tog koraka možemo ispisati našu matricu konačnih razlika.

3.3. Predviđanja

Kao glavni dio Slope One, predvidjet ćemo sve ocjene koje nedostaju na temelju postojećih podataka. Da bismo to učinili, moramo usporediti ocjene korisničkih stavki s matricom razlika izračunatom u prethodnom koraku:

za (Unos e: data.entrySet ()) {for (Stavka j: e.getValue (). keySet ()) {for (Stavka k: diff.keySet ()) {dvostruko predviđenaValue = diff.get (k) .get (j ) .doubleValue () + e.getValue (). get (j) .doubleValue (); dvostruka finalValue = predvidjena vrijednost * freq.get (k) .get (j) .intValue (); uPred.put (k, uPred.get (k) + finalValue); uFreq.put (k, uFreq.get (k) + freq.get (k) .get (j) .intValue ()); }} // ...}

Nakon toga moramo pripremiti "čista" predviđanja koristeći donji kod:

HashMap clean = novi HashMap (); za (Stavka j: uPred.keySet ()) {if (uFreq.get (j)> 0) {clean.put (j, uPred.get (j) .doubleValue () / uFreq.get (j) .intValue ( )); }} za (Stavka j: InputData.items) {if (e.getValue (). containsKey (j)) {clean.put (j, e.getValue (). get (j)); } inače if (! clean.containsKey (j)) {clean.put (j, -1.0); }}

Trik koji treba razmotriti kod većeg skupa podataka jest korištenje samo unosa stavki koji imaju veliku vrijednost frekvencije (na primjer> 1). Napominjemo, ako predviđanje nije moguće, vrijednost će biti jednaka -1.

Napokon, vrlo važna napomena. Ako je naš algoritam ispravno radio, trebali bismo dobiti predviđanja za stavke koje korisnik nije ocijenio, ali i ponovljene ocjene za stavke koje je ocijenio. Te ponovljene ocjene ne bi se trebale mijenjati, inače to znači da postoji pogreška u implementaciji vašeg algoritma.

3.4. Savjeti

Postoji nekoliko glavnih čimbenika koji utječu na algoritam Slope One. Evo nekoliko savjeta kako povećati točnost i vrijeme obrade:

  • razmotrite dobivanje ocjena korisnika na DB strani za velike skupove podataka
  • postavite vremenski okvir za dohvaćanje ocjena, jer se interesi ljudi mogu mijenjati tijekom vremena - to će također smanjiti vrijeme potrebno za obradu ulaznih podataka
  • podijelite velike skupove podataka na manje - ne morate svaki dan izračunati predviđanja za sve korisnike; možete provjeriti je li korisnik komunicirao s predviđenom stavkom, a zatim ga dodati / ukloniti iz reda za obradu za sljedeći dan

4. Zaključak

U ovom smo tutorijalu mogli naučiti o algoritmu Slope One. Štoviše, uveli smo problem zajedničkog filtriranja za sustave preporuke predmeta.

The puna provedba ovog vodiča možete pronaći u projektu GitHub.


$config[zx-auto] not found$config[zx-overlay] not found