"Sanoin, että haluan B-Movie-elokuvan!" Loppu loputtomalle vierittämiselle (ja kiistelyt siitä, mitä katsoa…) Oletko kyllästynyt Netflixin loputtomaan selaamiseen, etkä ole varma mitä katsoisi seuraavaksi? Mitä jos voisit rakentaa oman mukautetun tekoälypohjaisen suositusjärjestelmän, joka ennustaa seuraavan suosikkielokuvasi tarkasti? Tässä opetusohjelmassa opastamme sinua luomisessa käyttämällä . Opit kuinka modernit tekoälysuositusmoottorit toimivat ja saat käytännön kokemusta oman järjestelmäsi rakentamisesta avulla. elokuvasuositusjärjestelmän vektoritietokantoja (VectorDBs) Superlinkedin (Haluatko siirtyä suoraan koodiin? Tutustu GitHubin repoon . Oletko valmis kokeilemaan suosittelujärjestelmiä omaan käyttötapaasi varten? Hanki demo .) täällä tästä Suosittelemme! Seuraamme tätä koko artikkelin ajan. Voit myös suorittaa koodin suoraan selaimesta muistikirjaa Colabin avulla. Netflixin suositusalgoritmi tekee melko hyvää työtä ehdottaessaan asiaankuuluvaa sisältöä - ottaen huomioon valinnanvaran valtava määrä (noin 16 000 elokuvaa ja TV-ohjelmaa vuonna 2023) ja kuinka nopeasti sen on ehdotettava ohjelmia käyttäjille. Miten Netflix tekee sen? Sanalla sanoen . semanttinen haku Semanttinen haku ymmärtää käyttäjien kyselyjen ja elokuvien/TV-ohjelmien kuvausten takana olevan merkityksen ja kontekstin (sekä attribuutit että kulutustottumukset), ja voi siksi tarjota kyselyitään ja suosituksiinsa paremmin personoinnin kuin perinteiset avainsanapohjaiset lähestymistavat. Mutta semanttinen haku asettaa tiettyjä - ennen kaikkea: 1) tarkkojen hakutulosten varmistaminen, 2) tulkittavuus ja 3) skaalautuvuus - haasteita, joihin jokaisen onnistuneen sisällön suositusstrategian on vastattava. Superlinkedin kirjaston avulla voit nämä vaikeudet. haasteita voittaa Tässä artikkelissa näytämme, kuinka ja mieltymystesi perusteella. Superlinked-kirjaston avulla voit määrittää oman semanttisen haun luoda luettelon oleellisista elokuvista Semanttinen haku - Haasteet Semanttinen haku välittää paljon arvoa vektorihaussa, mutta asettaa kehittäjille kolme merkittävää vektorin upottamisen haastetta: : Sen varmistaminen, että upotuksesi kuvaavat tarkasti tietojesi semanttisen merkityksen, edellyttää upotustekniikoiden, harjoitustietojen ja hyperparametrien huolellista valintaa. Huonolaatuiset upotukset voivat johtaa epätarkkoihin hakutuloksiin ja epäolennaisiin suosituksiin. Laatu ja osuvuus : Korkeadimensionaaliset vektoriavaruudet ovat liian monimutkaisia, jotta niitä olisi helppo ymmärtää. Saadakseen käsityksen niihin koodatuista suhteista ja yhtäläisyyksistä datatieteilijöiden on kehitettävä menetelmiä niiden visualisoimiseksi ja analysoimiseksi. Tulkittavuus : Suuriulotteisten upotusten hallinta ja käsittely, erityisesti suurissa tietojoukoissa, voi rasittaa laskentaresursseja ja lisätä viivettä. Tehokkaat menetelmät indeksointiin, hakuun ja samankaltaisuuden laskentaan ovat välttämättömiä skaalautuvuuden ja reaaliaikaisen suorituskyvyn varmistamiseksi tuotantoympäristöissä. Skaalautuvuus Superlinked-kirjaston avulla voit vastata näihin haasteisiin. Alla rakennamme sisältösuosittelijan (erityisesti elokuvia varten) alkaen tiedoista, joita meillä on tietystä elokuvasta, upotamme nämä tiedot multimodaalisena vektorina, rakennamme haettavan vektoriindeksin kaikille elokuvillemme ja käytämme sitten kyselyn painotuksia tulosten säätämiseen ja hyvien elokuvasuositusten saamiseksi. Mennään asiaan. Luo nopea ja luotettava hakukokemus Superlinkedin avulla Alla teet semanttisen haun Netflix-elokuvatietojoukosta käyttämällä seuraavia Superlinked-kirjaston elementtejä: Äskettäisyystila – ymmärtääksesi tietojesi tuoreuden (valuutta ja osuvuus) ja tunnistaaksesi uudemmat elokuvat. TextSimilarity space - tulkita erilaisia elokuvan metatietoja, kuten kuvausta, otsikkoa ja genreä. Kyselyn aikapainot – voit valita, mikä tiedoistasi on tärkeintä, kun suoritat kyselyn. Näin voit optimoida ilman, että sinun tarvitsee upottaa koko tietojoukkoa uudelleen, suorittaa jälkikäsittelyä tai käyttää mukautettua uudelleensijoitusmallia (eli vähentää viivettä). Netflix Dataset ja mitä teemme sen kanssa Elokuvien suosittelu on vaikeaa lähinnä siksi, että vaihtoehtoja on niin paljon (> 9000 nimikettä vuonna 2023), ja käyttäjät haluavat suosituksia heti pyynnöstä. Otetaan löytääksemme jotain, jota haluamme katsoa. tiedämme: tietolähtöinen lähestymistapa Elokuvistamme kuvaus genre otsikko release_year Voimme upottaa nämä syötteet ja koota vektoriindeksin upotusten päälle, jolloin voimme luoda tilan, josta voimme etsiä semanttisesti. Kun meillä on indeksoitu vektoriavaruutemme, teemme: ensin selaa elokuvia idean mukaan (sydämen romanttinen komedia) seuraavaksi säädä tuloksia antamalla tiettyjen syöttökenttien osumille enemmän merkitystä (esim. painotuksen) hae sitten kuvauksen, tyylilajin ja nimen perusteella kullekin eri hakutermeillä ja kun olet löytänyt elokuvan, joka on läheinen, mutta ei tarkka vastaavuus, etsi myös kyseistä elokuvaa viitteenä Asennus ja tietojoukon valmistelu Ensimmäinen askel on asentaa kirjasto ja tuoda tarvittavat luokat. (Huomaa: muuta alla muotoon jos käytät tätä . Säilytä "mimetype", jos suoritat .) alt.renderers.enable(“mimetype”) alt.renderers.enable('colab') google colabissa githubissa %pip install superlinked==5.3.0 from datetime import timedelta, datetime import altair as alt import os import pandas as pd from superlinked.evaluation.charts.recency_plotter import RecencyPlotter from superlinked.framework.common.dag.context import CONTEXT_COMMON, CONTEXT_COMMON_NOW from superlinked.framework.common.dag.period_time import PeriodTime from superlinked.framework.common.schema.schema import schema from superlinked.framework.common.schema.schema_object import String, Timestamp from superlinked.framework.common.schema.id_schema_object import IdField from superlinked.framework.common.parser.dataframe_parser import DataFrameParser from superlinked.framework.dsl.executor.in_memory.in_memory_executor import ( InMemoryExecutor, InMemoryApp, ) from superlinked.framework.dsl.index.index import Index from superlinked.framework.dsl.query.param import Param from superlinked.framework.dsl.query.query import Query from superlinked.framework.dsl.query.result import Result from superlinked.framework.dsl.source.in_memory_source import InMemorySource from superlinked.framework.dsl.space.text_similarity_space import TextSimilaritySpace from superlinked.framework.dsl.space.recency_space import RecencySpace alt.renderers.enable("mimetype") # NOTE: to render altair plots in colab, change 'mimetype' to 'colab' alt.data_transformers.disable_max_rows() pd.set_option("display.max_colwidth", 190) Meidän on myös valmisteltava tietojoukko - määritettävä aikavakiot, asetettava datan URL-sijainti, luotava tietovaraston sanakirja, luettava CSV-tiedosto pandas DataFrame -kehykseen, puhdistettava datakehys ja tiedot, jotta niitä voidaan etsiä oikein, sekä tehtävä nopea tarkistus ja yleiskatsaus. (Katso lisätietoja ) soluista 3 ja 4. Nyt kun tietojoukko on valmis, voit optimoida haun käyttämällä Superlinked-kirjastoa. Vektorihaun indeksin luominen Superlinkedin kirjasto sisältää joukon ydinrakennuspalikoita, joita käytämme indeksin rakentamiseen ja haun hallintaan. Näistä rakennuspalikoista voit lukea tarkemmin . täältä Ensin sinun on määritettävä skeemasi kertoaksesi järjestelmälle tiedoistasi. # accommodate our inputs in a typed schema @schema class MovieSchema: description: String title: String release_timestamp: Timestamp genres: String id: IdField movie = MovieSchema() Seuraavaksi käytät välilyöntejä kertoaksesi, kuinka haluat käsitellä kutakin tiedon osaa upotuksen aikana. Mitä välilyöntejä käytetään, riippuu tietotyypistäsi. Jokainen tila on optimoitu upottamaan tiedot niin, että hakutulosten laatu on mahdollisimman korkea. Avaruusmäärittelyissä kuvataan, kuinka syötteet tulee upottaa, jotta se heijastelee datamme semanttisia suhteita. # textual fields are embedded using a sentence-transformers model description_space = TextSimilaritySpace( text=movie.description, model="sentence-transformers/paraphrase-MiniLM-L3-v2" ) title_space = TextSimilaritySpace( text=movie.title, model="sentence-transformers/paraphrase-MiniLM-L3-v2" ) genre_space = TextSimilaritySpace( text=movie.genres, model="sentence-transformers/paraphrase-MiniLM-L3-v2" ) # release date are encoded using our recency space # periodtimes aim to reflect notable breaks in our scores recency_space = RecencySpace( timestamp=movie.release_timestamp, period_time_list=[ PeriodTime(timedelta(days=4 * YEAR_IN_DAYS)), PeriodTime(timedelta(days=10 * YEAR_IN_DAYS)), PeriodTime(timedelta(days=40 * YEAR_IN_DAYS)), ], negative_filter=-0.25, ) movie_index = Index(spaces=[description_space, title_space, genre_space, recency_space]) Kun olet määrittänyt tilat ja luonut hakemiston, käytät kirjaston lähde- ja suorittajaosia kyselyjen määrittämiseen. Katso . solut 10-13 muistikirjasta Nyt kun kyselyt ovat valmiit, siirrytään kyselyjen suorittamiseen ja haun optimointiin painoja säätämällä. Äskettäisyyden ymmärtäminen ja sen käyttäminen Superlinkedissä Äskettäisyystilan avulla voit muuttaa kyselysi tuloksia hakemalla ensisijaisesti vanhemmat tai uudemmat julkaisut tietojoukostasi. Käytämme ajanjaksoina 4, 10 ja 40 vuotta, jotta voimme antaa vuosille enemmän nimikkeitä tarkennetuksi - katso ). solu 5 Huomaa pisteytyksen tauot 4, 10 ja 40 vuoden kohdalla. Yli 40 vuotta vanhemmille nimikkeille annetaan . negative_filter Hakutulosten tarkastelu ja optimointi käyttämällä erilaisia kyselyajan painotuksia Määritetään nopea apufunktio tulosten esittämiseksi muistikirjassa. def present_result( result: Result, cols_to_keep: list[str] = ["description", "title", "genres", "release_year", "id"], ) -> pd.DataFrame: # parse result to dataframe df: pd.DataFrame = result.to_pandas() # transform timestamp back to release year df["release_year"] = [ datetime.fromtimestamp(timestamp).year for timestamp in df["release_timestamp"] ] return df[cols_to_keep] Yksinkertaiset ja edistyneet kyselyt Superlinked-kirjaston avulla voit suorittaa erilaisia kyselyitä; tässä määrittelemme kaksi. Molemmat kyselytyypit (yksinkertaiset ja edistyneet) antavat minun punnita yksittäisiä välilyöntejä (kuvaus, otsikko, genre ja tietysti viimeaikaisuus) mieltymysteni mukaan. on se, että asetan yhden kyselytekstin ja näytän sitten samanlaisia tuloksia kuvaus-, otsikko- ja genre-tiloissa. Niiden välinen ero yksinkertaisella kyselyllä avulla minulla on tarkempi hallinta. Halutessasi voin kirjoittaa eri kyselytekstejä kuhunkin kuvaus-, otsikko- ja genre-tilaan. Tässä on kyselykoodi: Tarkennetun kyselyn query_text_param = Param("query_text") simple_query = ( Query( movie_index, weights={ description_space: Param("description_weight"), title_space: Param("title_weight"), genre_space: Param("genre_weight"), recency_space: Param("recency_weight"), }, ) .find(movie) .similar(description_space.text, query_text_param) .similar(title_space.text, query_text_param) .similar(genre_space.text, query_text_param) .limit(Param("limit")) ) advanced_query = ( Query( movie_index, weights={ description_space: Param("description_weight"), title_space: Param("title_weight"), genre_space: Param("genre_weight"), recency_space: Param("recency_weight"), }, ) .find(movie) .similar(description_space.text, Param("description_query_text")) .similar(title_space.text, Param("title_query_text")) .similar(genre_space.text, Param("genre_query_text")) .limit(Param("limit")) ) Yksinkertainen kysely Yksinkertaisissa kyselyissä asetan kyselytekstin ja käytän erilaisia painotuksia sen mukaan, miten ne ovat tärkeitä minulle. result: Result = app.query( simple_query, query_text="Heartfelt romantic comedy", description_weight=1, title_weight=1, genre_weight=1, recency_weight=0, limit=TOP_N, ) present_result(result) Tuloksemme sisältävät joitain otsikoita, jotka olen jo nähnyt. Pystyn käsittelemään tätä painottamalla viimeaikaisuutta ja painottamaan tuloksiani viimeaikaisiin nimikkeisiin. Painot normalisoidaan yksikkösummaksi (eli kaikki painot säädetään niin, että niiden summa on aina 1), joten sinun ei tarvitse huolehtia niiden asettamisesta. result: Result = app.query( simple_query, query_text="Heartfelt romantic comedy", description_weight=1, title_weight=1, genre_weight=1, recency_weight=3, limit=TOP_N, ) present_result(result) Tulokseni (yllä) ovat nyt vuoden 2021 jälkeisiä. Yksinkertaisen kyselyn avulla voin painottaa minkä tahansa tietyn tilan (kuvauksen, otsikon, tyylilajin tai äskettäisyyden) saadakseni sen merkityksellisempään tuloksia palauttaessani. Kokeillaan tätä. Alla annamme enemmän painoarvoa genrelle ja pienemmälle otsikolle - kyselytekstini on periaatteessa vain genre, jossa on lisäkontekstia. Pidän äskettäisyyteni ennallaan, koska haluaisin silti tulosteni olevan puolueellisia viimeaikaisia elokuvia kohtaan. result = app.query( simple_query, query_text="Heartfelt romantic comedy", description_weight=1, title_weight=0.1, genre_weight=2, recency_weight=1, limit=TOP_N, ) present_result(result) Tämä kysely siirtää julkaisuvuotta hieman taaksepäin, jotta saan enemmän genre-painotettuja tuloksia (alla). Tarkennettu kysely Tarkennettu kysely antaa minulle entistä tarkemman hallinnan. Hallitsen äskettäisyyttä, mutta voin myös määrittää hakutekstin kuvaukselle, otsikolle ja genrelle ja määrittää kullekin tietyn painoarvon mieltymysteni mukaan alla (ja ), solut 19-21 result = app.query( advanced_query, description_query_text="Heartfelt lovely romantic comedy for a cold autumn evening.", title_query_text="love", genre_query_text="drama comedy romantic", description_weight=0.2, title_weight=3, genre_weight=1, recency_weight=5, limit=TOP_N, ) present_result(result) Hae tietyn elokuvan avulla Sanotaan, että viime elokuvatuloksissani löysin elokuvan, jonka olen jo nähnyt ja haluaisin nähdä jotain vastaavaa. Oletetaan, että pidän Valkoisesta joulusta, vuoden 1954 romanttisesta komediasta (id = tm16479), joka kertoo laulajista ja tanssijoista, jotka kokoontuvat näyttämölle houkuttelemaan vieraita vaikeuksissa olevaan Vermontin majataloon. Kun lisäät ylimääräisen -lausekkeen (jossa on parametri) lisäkyselyyn, with_movie_query antaa minun tehdä hakuja tällä elokuvalla (tai millä tahansa elokuvasta, josta pidän), ja se antaa minulle täydellisen hallinnan erillisen alihakukyselyn tekstin ja painotuksen suhteen. with_vector movie_id Ensin lisäämme movie_id-parametrimme: with_movie_query = advanced_query.with_vector(movie, Param("movie_id")) Ja sitten voin asettaa muut alihakukyselyni joko tyhjiksi tai mikä tahansa olennaisin, sekä kaikki järkevät painotukset. Oletetaan, että ensimmäinen kyselyni palauttaa tuloksia, jotka kuvastavat White Christmasin näyttämöesitystä/bändiä (katso ), mutta haluan katsoa elokuvan, joka on perhekeskeisempi. Voin syöttää description_query_text-arvon vääristääkseni tuloksiani haluttuun suuntaan. solu 24 result = app.query( with_movie_query, description_query_text="family", title_query_text="", genre_query_text="", description_weight=1, title_weight=0, genre_weight=0, recency_weight=0, description_query_weight=1, movie_id="tm16479", limit=TOP_N, ) present_result(result) Mutta nyt kun näen tulokset, ymmärrän, että olen itse asiassa enemmän fiiliksissä johonkin kevyempään ja hauskaan. Muokataan kyselyäni vastaavasti: Result = app.query( with_movie_query, description_query_text="", title_query_text="", genre_query_text="comedy", description_weight=1, title_weight=0, genre_weight=2, recency_weight=0, description_query_weight=1, movie_id="tm16479", limit=TOP_N, ) present_result(result) Okei, tulokset ovat parempia. Valitsen yhden näistä. Laita popcornit päälle! Johtopäätös Superlinkedin avulla on helppo testata, iteroida ja parantaa hakulaatua. Yllä olemme opastaneet sinua Superlinked-kirjaston avulla, jotta voit tehdä semanttisen haun vektoriavaruudesta, kuten Netflix tekee, ja palauttaa tarkkoja, osuvia elokuvatuloksia. Olemme myös nähneet, kuinka voimme hienosäätää tuloksiamme, säätämällä painoja ja hakutermejä, kunnes saavutamme juuri oikean tuloksen. Kokeile nyt itse ja katso, mitä voit saavuttaa! muistikirjaa Kokeile itse – hanki koodi ja esittely! : Katso GitHub-repostamme täydellinen toteutus . Haarukkaa, säädä sitä ja tee siitä omasi! 💾 Tartu koodiin täältä . : Haluatko nähdä tämän toimivan tosielämässä? Varaa nopea kuinka voi täydentää suosituksiasi. ! 🚀 Katso se toiminnassa esittely ja tutki, Superlinked Hanki demo nyt Suositusmoottorit muokkaavat tapaamme löytää sisältöä. Olipa kyse elokuvista, musiikista tai tuotteista, – ja nyt sinulla on työkalut oman luomiseen. vektorihaku on tulevaisuutta Kirjailija: Mór Kapronczay