Soovitusmootor (mida mõnikord nimetatakse ka soovitajate süsteemiks) on tööriist, mis võimaldab algoritmide arendajad ennustada, mis võib kasutajale antud üksuste loendis meeldida või mitte. Soovitusmootorid on üsna huvitav alternatiiv otsinguväljadele, kuna soovitusmootorid aitavad kasutajatel leida tooteid või sisu, millega nad muidu ei pruugi kokku puutuda. See teeb soovitusmootoritest suure osa veebisaitidest ja teenustest, nagu Facebook, YouTube, Amazon ja palju muud.
Soovitusmootorid töötavad ideaalselt ühel kahel viisil. See võib tugineda kasutajale meeldivate üksuste omadustele, mida analüüsitakse, et teha kindlaks, mis kasutajale veel võib meeldida; või võib see tugineda teiste kasutajate meeldimistele ja mittemeeldimistele, mida soovitusmootor seejärel kasutajate vahelise sarnasuse indeksi arvutamiseks kasutab ja neile vastavalt üksusi soovitab. Mõlema meetodi ühendamine on ka palju jõulisema soovitusmootori loomiseks. Kuid nagu kõik muud teabega seotud probleemid, on hädavajalik valida see probleemile sobiv algoritm käsitletakse.
Selles õpetuses tutvustame teile koostöös ja mälupõhiste soovitusmootorite loomise protsessi. See soovitusmootor soovitab kasutajatele filme selle põhjal, mis neile meeldib ja mis ei meeldi ning toimib nagu teine näide, mida mainiti. Selle projekti jaoks kasutame põhilisi komplektioperatsioone, väikest matemaatikat ja Node.js / CoffeeScripti. Leiate kogu selle õpetuse jaoks asjakohase lähtekoodi siin .
kui palju on adobe xd
Enne koostöömälupõhise soovitusmootori juurutamist peame kõigepealt mõistma sellise süsteemi põhiideed. Selle mootori jaoks pole iga üksus ja iga kasutaja muud kui tunnused. Seetõttu ei võta me soovituste loomisel arvesse filmi muid atribuute (näiteks näitlejaid, režissööri, žanrit jne). Kahe kasutaja sarnasust esitatakse kümnendarvuna vahemikus -1,0 kuni 1,0. Nimetame seda numbrit sarnasuse indeksiks. Lõpuks esitatakse filmile meeldimise võimalus kasutajale teise kümnendarvu vahemikus -1,0 kuni 1,0. Nüüd, kui oleme selle süsteemi ümbritsevat maailma lihtsate terminitega modelleerinud, saame nende tunnuste ja numbrite vahelise seose määratlemiseks vallandada käputäie elegantseid matemaatilisi võrrandeid.
Oma soovituste algoritmis säilitame hulga komplekte. Igal kasutajal on kaks komplekti: komplekt filme, mis meeldivad kasutajale, ja komplekt, mis kasutajale ei meeldi. Iga filmiga on seotud ka kaks komplekti: kasutajate komplekt, kellele film meeldis, ja kasutajate komplekt, kellele see film ei meeldinud. Soovituste loomise etappide jooksul toodetakse mitmeid komplekte - enamasti teiste komplektide liidud või ristmikud. Samuti tellime igale kasutajale soovituste loendid ja sarnased kasutajad.
Sarnasuse indeksi arvutamiseks kasutame Jaccardi indeksi valemi variatsiooni. Algselt tuntud kui 'Coefficient de communauté' (mille on välja töötanud Paul Jaccard) valem võrdleb kahte komplekti ja annab lihtsa kümnendarvu statistika vahemikus 0 kuni 1,0:
Valem hõlmab mõlemas komplektis olevate ühiste elementide arvu jagamist mõlema hulga kõigi elementide arvuga (loendatakse ainult üks kord). Kahe ühesuguse hulga Jaccardi indeks on alati 1, samas kui kahe ühiste elementideta komplekti Jaccardi indeks annab alati 0. Nüüd, kui teame, kuidas kahte komplekti võrrelda, mõelgem strateegiale, mida saame kasutada kahe võrdlemiseks kasutajatele. Nagu varem arutletud, on kasutajatel süsteemi vaatepunktist kolm asja: identifikaator, meeldinud filmide komplekt ja mittemeeldivate filmide kogum. Kui peaksime määrama oma kasutajate sarnasuse indeksi ainult neile meeldinud filmide kogumi põhjal, võiksime kasutada otse Jaccardi indeksi valemit:
Siin on U1 ja U2 kaks kasutajat, keda me võrdleme ning L1 ja L2 on filmikomplektid, mis on vastavalt U1 ja U2 meeldinud. Kui nüüd järele mõelda, on kaks samale filmile meeldivat kasutajat sarnased, siis peaksid ka kaks samu filme mittemeeldivad kasutajad olema sarnased. Siin muudame võrrandit veidi:
Selle asemel, et valemi loendis lihtsalt arvestada levinud meeldimistega, lisame nüüd ka tavaliste mittemeeldimiste arvu. Nimetajana võtame kõigi üksuste arvu, mis on kas kasutajale meeldinud või mitte. Nüüd, kui oleme nii meeldimisi kui ka mittemeeldimisi iseseisvalt kaalunud, peaksime mõtlema ka juhtumile, kus kaks kasutajat on oma eelistustes polaarsed vastandid. Kahe kasutaja sarnasusindeks, kus ühele meeldib film ja teisele ei meeldi, ei tohiks olla 0:
See on üks pikk valem! Aga see on lihtne, luban. See sarnaneb meie eelmise valemiga, lugeja väikese erinevusega. Lahutame nüüd kahe kasutaja vastuoluliste meeldimiste ja mittemeeldimiste arvu nende ühiste meeldimiste ja mittemeeldimiste arvust. See põhjustab sarnasuse indeksi valemi väärtuste vahemiku -1,0 kuni 1,0. Kahe identse maitsega kasutaja sarnasuse indeks on 1,0, samal ajal kui kahel kasutajal, kellel on filmides täiesti vastuoluline maitse, on sarnasuse indeks -1,0.
Nüüd, kui teame, kuidas võrrelda kahte kasutajat nende filmimaitse põhjal, peame enne omatehtud soovitusmootori algoritmi juurutamist uurima veel ühte valemit:
Lammutame selle võrrandi veidi alla. Mida me mõtleme P(U,M)
all on kasutaja võimalus U
film meeldib M
. ZL
ja ZD
on kasutaja sarnasuse indeksite summa U
kõigi kasutajatega, kellele film on vastavalt meeldinud või ei meeldinud M
|ML|+|MD|
tähistab filmi meeldinud või mittemeeldinud kasutajate koguarvu M
Tulemus P(U,M)
annab arvu vahemikus -1,0 kuni 1,0.
Umbes nii. Järgmises jaotises saame neid valemeid kasutades hakata kasutama oma koostööl põhinevat mälupõhist soovitusmootorit.
Ehitame selle soovitusmootori kui väga lihtsa rakenduse Node.js. Eesosas on ka väga vähe tööd, enamasti mõned HTML-lehed ja vormid (lehtede ilusa väljanägemise jaoks kasutame Bootstrapi). Serveri poolel kasutame CoffeeScripti. Rakendusel on paar GET- ja POST-marsruuti. Isegi kui meil on rakenduses kasutajate mõiste, pole meil mingit täpsemat registreerimise / sisselogimise mehhanismi. Püsivuse huvides kasutame NPM-i kaudu pakutavat Bourne'i paketti, mis võimaldab rakendusel salvestada andmeid tavalistes JSON-failides ja täita nende alusel andmebaasi põhipäringuid. Marsruutide ja käitlejate haldamise protsessi hõlbustamiseks kasutame teenust Express.js.
Siinkohal, kui olete uus Node.js arendus , võiksite klooni kloonida GitHubi hoidla et seda õpetust oleks lihtsam järgida. Nagu kõigi teiste Node.js projektide puhul, alustame ka sellest faili package.json loomine ja selle projekti jaoks vajalike sõltuvuspakettide komplekti installimine. Kui kasutate kloonitud hoidlat, peaks fail pack.json juba olemas olema, kust sõltuvuste installimine nõuab '$ npm install' käivitamist. See installib kõik failis package.json loetletud paketid.
Selle projekti jaoks vajalikud Node.js paketid on:
Ehitame soovitusmootori, jagades kõik asjakohased meetodid neljaks eraldi CoffeeScripti klassiks, millest igaüks salvestatakse jaotises „lib / engine”: mootor, hindaja, sarnane versioon ja soovitused. Klassimootor vastutab soovitusmootori jaoks lihtsa API pakkumise eest ja seob ülejäänud kolm klassi kokku. Hindaja vastutab meeldimiste ja mittemeeldimiste jälgimise eest (klassi hindajate kahe eraldi eksemplarina). Sarnased ja soovitused vastutavad vastavalt sarnaste kasutajate ja neile soovitatud üksuste määramise ja jälgimise eest.
Alustame kõigepealt oma Hindajate klassist. See on lihtne:
class Rater constructor: (@engine, @kind) -> add: (user, item, done) -> remove: (user, item, done) -> itemsByUser: (user, done) -> usersByItem: (item, done) ->
Nagu selles õpetuses varem märgitud, on meil üks hindajate meeldimiste ja teine mittemeeldimiste esinemine. Kui soovite registreerida, et kasutajale meeldib üksus, edastame selle saidile „Hindaja # lisa ()”. Samamoodi edastame hinnangu eemaldamiseks need saidile „Hindaja # eemalda ()”.
Kuna kasutame Bourne'i serverivaba andmebaasilahendusena, salvestame need hinnangud faili nimega './db-#{@kind}.json', kus lahke on kas 'meeldib' või 'ei meeldi'. Avame andmebaasi Rateri eksemplari konstruktori sees:
constructor: (@engine, @kind) -> @db = new Bourne './db-#{@kind}.json'
See muudab reitingukirjete lisamise sama lihtsaks kui Bourne'i andmebaasimeetodi kutsumine meie meetodis 'Rater # add ()':
@db.insert user: user, item: item, (err) =>
Ja see on sarnane nende eemaldamisega („db.delete“ „db.insert“ asemel). Enne millegi lisamist või eemaldamist peame siiski veenduma, et seda pole andmebaasis juba olemas. Ideaalis oleksime tõelise andmebaasiga võinud seda teha ühe toiminguna. Bourne'iga peame kõigepealt tegema käsitsi kontrolli; ja kui sisestamine või kustutamine on tehtud, peame kindlasti arvutama selle kasutaja sarnasuse indeksid ümber ja looma seejärel hulga uusi ettepanekuid. Meetodid 'Hindaja # lisa ()' ja 'Hindaja # eemalda ()' näevad välja umbes sellised:
kuidas kantav tehnoloogia töötab
add: (user, item, done) -> @db.find user: user, item: item, (err, res) => if res.length > 0 return done() @db.insert user: user, item: item, (err) => async.series [ (done) => @engine.similars.update user, done (done) => @engine.suggestions.update user, done ], done remove: (user, item, done) -> @db.delete user: user, item: item, (err) => async.series [ (done) => @engine.similars.update user, done (done) => @engine.suggestions.update user, done ], done
Lühiduse huvides jätame need osad vahele, kus kontrollime vigu. See võib olla mõistlik asi, mida artiklis teha, kuid see ei ole vabandus reaalkoodi vigade ignoreerimiseks.
Selle klassi kaks ülejäänud meetodit: „Rater # itemsByUser ()” ja „Rater # usersByItem ()” hõlmavad seda, mida nende nimed tähendavad - otsida üles üksused, mille on hinnanud kasutaja ja üksused, kes on objekti hinnanud. Näiteks kui hindaja on installeeritud funktsiooniga kind = “likes”
, leiab „Hindaja # itemsByUser ()” kõik üksused, mille kasutaja on hinnanud.
Edasi meie järgmise klassi juurde: Similars. See klass aitab meil arvutada ja jälgida kasutajate sarnasuseindekseid. Nagu varem arutletud, hõlmab kahe kasutaja sarnasuse arvutamine neile meeldivate ja mittemeeldivate esemete komplektide analüüsimist. Selleks toetume asjakohaste üksuste komplektide toomisel hindaja eksemplaridele ja määrame seejärel sarnasuse indeksi valemi abil teatud kasutajate paaride sarnasuse indeksi.
Nii nagu meie eelmine klass Rater, paneme ka kõik Bourne'i andmebaasi nimega “./db-similars.json”, mille avame Rateri konstruktoris. Klassil on meetod „Similars # byUser ()”, mis võimaldab meil lihtsa andmebaasiotsingu kaudu otsida konkreetse kasutajaga sarnaseid kasutajaid:
@db.findOne user: user, (err, {others}) =>
Kuid selle klassi kõige olulisem meetod on „Similars # update ()”, mis töötab nii, et võtab kasutaja ja arvutab teiste sarnaste kasutajate loendi ning salvestab loendi koos nende sarnasuse indeksitega andmebaasi. See algab kasutaja meeldimiste ja mittemeeldimiste leidmisega.
async.auto userLikes: (done) => @engine.likes.itemsByUser user, done userDislikes: (done) => @engine.dislikes.itemsByUser user, done , (err, {userLikes, userDislikes}) => items = _.flatten([userLikes, userDislikes])
Leiame ka kõik kasutajad, kes on neid tooteid hinnanud:
async.map items, (item, done) => async.map [ @engine.likes @engine.dislikes ], (rater, done) => rater.usersByItem item, done , done , (err, others) =>
Järgmisena arvutame kõigi nende teiste kasutajate jaoks sarnasuse indeksi ja salvestame selle kõik andmebaasi:
async.map others, (other, done) => async.auto otherLikes: (done) => @engine.likes.itemsByUser other, done otherDislikes: (done) => @engine.dislikes.itemsByUser other, done , (err, {otherLikes, otherDislikes}) => done null, user: other similarity: (_.intersection(userLikes, otherLikes).length+_.intersection(userDislikes, otherDislikes).length-_.intersection(userLikes, otherDislikes).length-_.intersection(userDislikes, otherLikes).length) / _.union(userLikes, otherLikes, userDislikes, otherDislikes).length , (err, others) => @db.insert user: user others: others , done
Ülaltoodud jupis märkate, et meil on oma olemuselt identne väljend sarnasuse indeksi valemiga, mis on Jaccardi indeksi valemi variant.
Meie järgmine klass Ettepanekud on koht, kus kõik ennustused toimuvad. Nagu klass Similars, toetume ka teisele Bourne'i andmebaasile nimega “./db-suggestions.json”, mis on avatud konstruktori sees.
Klassil on meetod 'Suggestions # forUser ()', et otsida antud kasutajale arvutatud soovitusi:
forUser: (user, done) -> @db.findOne user: user, (err, {suggestions}={suggestion: []}) -> done null, suggestions
Nende tulemuste arvutamiseks on meetod „Suggestions # update ()”. See meetod, näiteks “Similars # update ()”, võtab kasutajana argumendi. Meetodi alguses loetletakse kõik antud kasutajale sarnased kasutajad ja kõik elemendid, mida antud kasutaja pole hinnanud:
@engine.similars.byUser user, (err, others) => async.auto likes: (done) => @engine.likes.itemsByUser user, done dislikes: (done) => @engine.dislikes.itemsByUser user, done items: (done) => async.map others, (other, done) => async.map [ @engine.likes @engine.dislikes ], (rater, done) => rater.itemsByUser other.user, done , done , done , (err, {likes, dislikes, items}) => items = _.difference _.unique(_.flatten items), likes, dislikes
Kui kõik teised kasutajad ja loetletud reitinguta üksused on meil olemas, võime hakata arvutama uut soovituste komplekti, eemaldades kõik varasemad soovituste komplektid, kordades iga üksuse ja arvutades võimaluse kasutajale see olemasoleva teabe põhjal meeldida:
@db.delete user: user, (err) => async.map items, (item, done) => async.auto likers: (done) => @engine.likes.usersByItem item, done dislikers: (done) => @engine.dislikes.usersByItem item, done , (err, {likers, dislikers}) => numerator = 0 for other in _.without _.flatten([likers, dislikers]), user other = _.findWhere(others, user: other) if other? numerator += other.similarity done null, item: item weight: numerator / _.union(likers, dislikers).length , (err, suggestions) =>
Kui see on tehtud, salvestame selle tagasi andmebaasi:
@db.insert user: user suggestions: suggestions , done
Mootoriklassis seotame kõik ilusa API-taolise struktuuriga, et välismaailmast oleks hõlbus pääseda:
class Engine constructor: -> @likes = new Rater @, 'likes' @dislikes = new Rater @, 'dislikes' @similars = new Similars @ @suggestions = new Suggestions @
Kui oleme mootori objekti instantsinud:
e = new Engine
Meeldivusi ja mittemeeldivusi saame hõlpsalt lisada või eemaldada:
e.likes.add user, item, (err) -> e.dislikes.add user, item, (err) ->
Samuti võime alustada kasutajate sarnasuse indeksite ja soovituste värskendamist.
e.similars.update user, (err) -> e.suggestions.update user, (err) ->
Lõpuks on oluline see mootoriklass (ja kõik teised klassid) eksportida vastavatest failidest .coffee:
module.exports = Engine
Seejärel eksportige mootor paketist, luues ühe reaga faili index.coffee:
module.exports = require './engine'
Selles õpetuses soovitusmootori algoritmi kasutamiseks peaksime pakkuma veebi kaudu lihtsat kasutajaliidest. Selleks kudeme oma faili 'web.iced' sisse Expressi rakenduse ja käsitleme mõnda marsruuti:
movies = require './data/movies.json' Engine = require './lib/engine' e = new Eengine app = express() app.set 'views', '#{__dirname}/views' app.set 'view engine', 'jade' app.route('/refresh') .post(({query}, res, next) -> async.series [ (done) => e.similars.update query.user, done (done) => e.suggestions.update query.user, done ], (err) => res.redirect '/?user=#{query.user}' ) app.route('/like') .post(({query}, res, next) -> if query.unset is 'yes' e.likes.remove query.user, query.movie, (err) => res.redirect '/?user=#{query.user}' else e.dislikes.remove query.user, query.movie, (err) => e.likes.add query.user, query.movie, (err) => if err? return next err res.redirect '/?user=#{query.user}' ) app.route('/dislike') .post(({query}, res, next) -> if query.unset is 'yes' e.dislikes.remove query.user, query.movie, (err) => res.redirect '/?user=#{query.user}' else e.likes.remove query.user, query.movie, (err) => e.dislikes.add query.user, query.movie, (err) => res.redirect '/?user=#{query.user}' ) app.route('/') .get(({query}, res, next) -> async.auto likes: (done) => e.likes.itemsByUser query.user, done dislikes: (done) => e.dislikes.itemsByUser query.user, done suggestions: (done) => e.suggestions.forUser query.user, (err, suggestions) => done null, _.map _.sortBy(suggestions, (suggestion) -> -suggestion.weight), (suggestion) => _.findWhere movies, id: suggestion.item , (err, {likes, dislikes, suggestions}) => res.render 'index', movies: movies user: query.user likes: likes dislikes: dislikes suggestions: suggestions[...4] )
Rakenduses tegeleme nelja marsruudiga. Indeksiteekond “/” on koht, kus serveerime esiotsa HTML-i, muutes Jade'i malli. Malli genereerimine eeldab filmide loendit, praeguse kasutaja kasutajanime, kasutaja meeldimisi ja mittemeeldivusi ning kasutaja jaoks nelja parimat soovitust. Jade'i malli lähtekood on artiklist välja jäetud, kuid see on saadaval GitHubi hoidla .
Marsruutidel '/ like' ja '/ dislike' nõustume POST-taotlustega kasutaja meeldimiste ja mittemeeldimiste registreerimiseks. Mõlemad marsruudid lisavad hinnangu, eemaldades vajaduse korral kõigepealt vastuolulise hinnangu. Näiteks, kui kasutajale meeldib midagi, mis talle varem ei meeldinud, põhjustab käitleja kõigepealt hinnangu „ei meeldi”. Need marsruudid võimaldavad kasutajal soovi korral ka üksust 'mitte meeldida' või 'mitte meeldida'.
Lõpuks võimaldab marsruut “/ värskendada” kasutajal vajadusel oma soovituste kogumit taastada. Kuigi see toiming viiakse läbi automaatselt alati, kui kasutaja annab üksusele hinnangu.
Kui olete seda artiklit järgides proovinud rakendust nullist juurutada, peate enne selle testimist sooritama viimase sammu. Peate looma „.json” -faili aadressil „data / movies.json” ja täitma selle mõne filmiandmega:
[ { 'id': '1', 'name': 'Transformers: Age of Extinction', 'thumb': { 'url': '//upload.wikimedia.org/wikipedia/en/7/7f/Inception_ver3.jpg' } }, // … ]
Võite kopeerida selle, mis on saadaval GitHubi hoidla , mis on eelnevalt täidetud käputäie filmide nimede ja pisipiltide URL-idega.
Kui kogu lähtekood on valmis ja ühendatud, on serveriprotsessi käivitamiseks vaja käivitada järgmine käsk:
$ npm start
Eeldades, et kõik läks sujuvalt, peaksite terminali nägema järgmist teksti:
Listening on 5000
Kuna me pole kasutanud ühtegi tõelist kasutaja autentimissüsteemi, tugineb prototüüprakendus ainult kasutajanimele, mis valiti pärast saidi “http: // localhost: 5000” külastamist. Kui kasutajanimi on sisestatud ja vorm on esitatud, peaksite minema teisele lehele, kus on kaks jaotist: „Soovitatavad filmid“ ja „Kõik filmid“. Kuna meil puudub koostöömälupõhise soovitusmootori kõige olulisem element (andmed), ei saa me sellele uuele kasutajale ühtegi filmi soovitada.
Siinkohal peaksite avama teise brauseriakna aadressile „http: // localhost: 5000” ja logima sisse teise kasutajana. Mõnele filmile meeldivad ja ei meeldi selle teise kasutajana. Naaske esimese kasutaja brauseriaknasse ja hinnake ka mõnda filmi. Hinnake kindlasti mõlema kasutaja jaoks vähemalt paari tavalist filmi. Peaksite kohe soovitusi nägema.
Selles algoritmiõpetuses on meie loodud prototüübi soovitusmootor. Selle mootori täiustamiseks on kindlasti võimalusi. Selles jaotises käsitletakse lühidalt mõnda valdkonda, kus selle laiaulatuslikuks kasutamiseks on vaja täiendusi. Kuid juhtudel, kui on vaja mastaapsust, stabiilsust ja muid selliseid omadusi, peaksite alati kasutama hea aja testitud lahendust. Nagu ülejäänud artikkel, on ka siin idee anda ülevaade soovitusmootori toimimisest. Selle asemel, et arutleda praeguse meetodi ilmsete vigade üle (näiteks võistlusolukord mõnel meie rakendatud meetodil), arutatakse edasiarendusi kõrgemal tasemel.
Üks väga ilmne edasiarendus on meie failipõhise lahenduse asemel kasutada tõelist andmebaasi. Failipõhine lahendus võib väikeses mahus prototüübis hästi töötada, kuid reaalseks kasutamiseks pole see üldse mõistlik valik. Üks võimalus paljude seas on Redis. Redis on kiire ja on erivõimalused mis on kasulikud komplektilaadsete andmestruktuuride käsitlemisel.
on soundcloud parem kui spotify
Teine probleem, mille abil saame lihtsalt ümber käia, on asjaolu, et arvutame uusi soovitusi iga kord, kui kasutaja koostab või muudab oma filmidele hinnanguid. Selle asemel, et reaalajas lennult ümber arvutada, peaksime need soovituste värskendustaotlused kasutajatele järjekorda panema ja lava taga sooritama - võib-olla seadistame ajastatud värskendusintervalli.
Lisaks nendele “tehnilistele” valikutele on soovituste täiustamiseks ka mõned strateegilised valikud. Kui üksuste ja kasutajate arv kasvab, muutub soovituste genereerimine (aja ja süsteemiressursside osas) järjest kallimaks. Selle on võimalik kiiremaks muuta, valides soovituste loomiseks ainult alamhulga kasutajaid, selle asemel et kogu andmebaasi iga kord töödelda. Näiteks kui see oli restoranide soovitusmootor, võite piirata sarnase kasutajate komplekti nii, et see sisaldaks ainult neid kasutajaid, kes elavad samas linnas või osariigis.
Muud täiustused võivad hõlmata hübriidset lähenemist, kus soovitused luuakse nii koostööl kui ka sisupõhisel filtreerimisel. See oleks eriti hea sellise sisuga nagu filmid, kus sisu omadused on hästi määratletud. Näiteks Netflix läheb seda teed, soovitades filme nii teiste kasutajate tegevuse kui ka filmide atribuutide põhjal.
Mälupõhised koostöösoovituste mootori algoritmid võivad olla üsna võimas asi. See, millega me selles artiklis katsetasime, võib olla primitiivne, kuid see on ka lihtne: arusaadav ja ülesehitatav. See ei pruugi kaugeltki täiuslik olla, kuid soovitusmootorite, näiteks Soovitatavate, jõuline rakendamine on üles ehitatud sarnastele põhiideedele.
Nagu enamik muid arvutiteaduse probleeme, mis hõlmavad palju andmeid, on ka õigete soovituste saamine palju vajalik õige algoritmi valimine ja sisu asjakohased atribuudid, millega töötada. Loodan, et see artikkel on andnud teile pilgu sellest, mis juhtub mälupõhise soovitusmootori koostöös, kui te seda kasutate.