Et samarbejdsfiltreringsanbefalingssystem i Java

1. Introduktion

I denne vejledning lærer vi alt om Slope One-algoritmen i Java.

Vi viser også implementeringseksemplet til problemet med Collaborative Filtering (CF) - en maskinlæringsteknik bruges af anbefalingssystemer.

Dette kan f.eks. Bruges til at forudsige brugerinteresser for bestemte emner.

2. Samarbejdsfiltrering

Slope One-algoritmen er et elementbaseret samarbejdsfiltreringssystem. Det betyder, at det er fuldstændigt baseret på ranking af bruger-vare. Når vi beregner ligheden mellem objekter, kender vi kun ranglistehistorikken, ikke selve indholdet. Denne lighed bruges derefter til at forudsige potentielle brugerrangeringer for bruger-elementpar, der ikke findes i datasættet.

Billedet nedenfor viser den komplette proces med at opnå og beregne klassificeringen for den specifikke bruger:

Først bedømmer brugerne forskellige varer i systemet. Derefter beregner algoritmen lighederne. Derefter forudsiger systemet forudsigelser for bruger-varebedømmelser, som brugeren endnu ikke har bedømt.

For flere detaljer om emnet for samarbejdsfiltrering kan vi henvise til Wikipedia-artiklen.

3. Slope One-algoritmen

Slope One blev navngivet som den enkleste form for ikke-triviel varebaseret samarbejdsfiltrering baseret på vurderinger. Det tager både information fra alle brugere, der vurderede det samme element, og fra de andre varer, der er vurderet af den samme bruger, til at beregne lighedmatricen.

I vores enkle eksempel skal vi forudsige brugerrangeringer på varerne i butikken.

Lad os starte med en simpel Java-model til vores problem og domæne.

3.1. Java-model

I vores model har vi to hovedobjekter - varer og brugere. Det Vare klasse indeholder navnet på varen:

private String itemName;

På den anden side er Bruger klasse indeholder brugernavnet:

privat streng brugernavn;

Endelig har vi en InputData klasse, der skal bruges til at initialisere dataene. Lad os antage, at vi opretter fem forskellige produkter i butikken:

Listeelementer = Arrays.asList (nyt emne ("Candy"), nyt emne ("Drink"), nyt emne ("Soda"), nyt emne ("Popcorn"), nyt emne ("Snacks"));

Desuden opretter vi tre brugere, der tilfældigt vurderede nogle af de ovennævnte ved hjælp af skalaen fra 0,0-1,0, hvor 0 betyder ingen interesse, 0,5 på en eller anden måde interesseret og 1.0 betyder helt interesseret. Som et resultat af datainitialisering får vi en Kort med data om rangordning af brugeren:

Kort data;

3.2. Forskelle og frekvenser Matricer

Baseret på de tilgængelige data beregner vi forholdet mellem varerne samt antallet af forekomster af varer. For hver bruger kontrollerer vi hans / hendes vurdering af varerne:

for (HashMap-bruger: data.values ​​()) {for (Indtastning e: user.entrySet ()) {// ...}}

I det næste trin kontrollerer vi, om varen findes i vores matricer. Hvis dette er en første begivenhed, opretter vi den nye post i kortene:

hvis (! diff.containsKey (e.getKey ())) {diff.put (e.getKey (), ny HashMap ()); freq.put (e.getKey (), ny HashMap ()); } 

Den første matrix bruges til at beregne forskellene mellem brugerbedømmelserne. Værdierne af det kan være positive eller negative (da forskellen mellem vurderinger kan være negative) og lagres som Dobbelt. På den anden side lagres frekvenserne som Heltal værdier.

I det næste trin skal vi sammenligne klassificeringen af ​​alle varer:

for (Indtastning e2: bruger.entrySet ()) {int oldCount = 0; hvis (freq.get (e.getKey ()). indeholder Key (e2.getKey ())) {oldCount = freq.get (e.getKey ()). get (e2.getKey ()). intValue (); } dobbelt oldDiff = 0,0; hvis (diff.get (e.getKey ()). indeholder Key (e2.getKey ())) {oldDiff = diff.get (e.getKey ()). get (e2.getKey ()). doubleValue (); } dobbelt observeretDiff = e.getValue () - e2.getValue (); freq.get (e.getKey ()). sæt (e2.getKey (), oldCount + 1); diff.get (e.getKey ()). put (e2.getKey (), oldDiff + observeretDiff); }

Hvis nogen bedømte varen før, øger vi antallet af frekvenser med en. Desuden kontrollerer vi den gennemsnitlige forskel mellem varens vurderinger og beregner den nye observeretDiff.

Bemærk, at vi lægger summen af oldDiff og observeretDiff som en ny værdi af en vare.

Endelig beregner vi lighedsscore inde i matricerne:

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); }}

Hovedlogikken er at dividere den beregnede vareklassificerings forskel med antallet af dens forekomster. Efter dette trin kan vi udskrive vores sidste matrix for forskelle.

3.3. Forudsigelser

Som hoveddelen af ​​Slope One vil vi forudsige alle manglende ratings baseret på de eksisterende data. For at gøre det er vi nødt til at sammenligne klassificeringen af ​​bruger-varen med forskelmatrix beregnet i det foregående trin:

for (indgang e: data.entrySet ()) {for (Item j: e.getValue (). keySet ()) {for (Item k: diff.keySet ()) {double predictedValue = diff.get (k). get (j ) .doubleValue () + e.getValue (). get (j) .doubleValue (); dobbelt finalValue = forudsagt værdi * 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 ()); }} // ...}

Derefter skal vi forberede de "rene" forudsigelser ved hjælp af nedenstående kode:

HashMap ren = ny HashMap (); for (Item j: uPred.keySet ()) {if (uFreq.get (j)> 0) {clean.put (j, uPred.get (j) .doubleValue () / uFreq.get (j) .intValue ( )); }} for (Item j: InputData.items) {if (e.getValue (). containKey (j)) {clean.put (j, e.getValue (). get (j)); } ellers hvis (! clean.containsKey (j)) {clean.put (j, -1.0); }}

Tricket at overveje med større datasæt er kun at bruge de poster, der har en stor frekvensværdi (for eksempel> 1). Bemærk, at hvis forudsigelsen ikke er mulig, vil værdien af ​​den være lig med -1.

Endelig meget vigtig note. Hvis vores algoritme fungerede korrekt, vi skulle modtage forudsigelser for varer, som brugeren ikke bedømte, men også gentagne vurderinger for de varer, som han bedømte. Disse gentagne vurderinger bør ikke ændres, ellers betyder det, at der er en fejl i din algoritmeimplementering.

3.4. Tips

Der er få vigtige faktorer, der påvirker Slope One-algoritmen. Her er de få tip til, hvordan du øger nøjagtigheden og behandlingstiden:

  • overvej at skaffe bruger-varebedømmelser på DB-siden til store datasæt
  • indstil tidsrammen for hentning af ratings, da folks interesser kan ændre sig med tiden - det reducerer også den tid, der kræves til at behandle inputdata
  • opdele store datasæt i mindre - du behøver ikke beregne forudsigelser for alle brugere hver dag; du kan kontrollere, om brugeren interagerede med det forudsagte element og derefter tilføje / fjerne ham / hende fra behandlingskøen den næste dag

4. Konklusion

I denne vejledning kunne vi lære om Slope One-algoritmen. Desuden introducerede vi samarbejdsfiltreringsproblemet til vareanbefalingssystemer.

Det fuld implementering af denne vejledning kan findes i GitHub-projektet.


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