Шта ако ваша онлине продавница зна шта клијент жели пре него што то учине? Шта ако ваша онлине продавница зна шта клијент жели пре него што то учине? они предлажу „популарне“ или „сличне“ ставке на основу ограничених, застарелих података. када су корисници нови (проблем хладног почетка), и ретко се довољно брзо прилагођавају када се корисничке преференције мењају у реалном времену. Most recommendation engines are like helpful but slightly clueless assistants: struggle Али шта ако ваш систем може као трговац – комбинујући статичке податке о производу и понашање корисника у реалном времену на површину U pravo vreme? Заправо мислим Pravi predmeti Заправо мислим Коришћење , један који превазилази ове традиционалне недостатке тако што претвара ваше податке у акциони, еволуирајуће корисничке профиле користећи векторску инфраструктуру. This guide walks you through building a modern recommendation engine Superlinked (Желите да скочите директно на код? Погледајте отворени код на ГитХубу овде. спремни да испробате системе за препоручивање за сопствени случај употребе? ovde ovde ovde ovde Такође можете пратити заједно са туторијалом у претраживачу са нашим Колаб Др ; др : Већина препоручивача е-трговине су или превише статични (на основу правила) или превише црне кутије (нејасни МЛ модели). Суперлинкед нуди средњи пут: флексибилне, препоруке у реалном времену које се могу прилагодити корисницима хладног старта комбиновањем метаподатака са живом понашањем - све без преиспитивања МЛ модела. Постизање персонализације упркос изазовима уграђивања рецСис вектора Док векторска уграђења могу значајно побољшати системе препоруке, ефикасна имплементација захтева рјешавање неколико изазова, укључујући: Квалитет и релевантност: Процес уграђивања генерације, архитектура и подаци морају се пажљиво размотрити. Спарсе и бучни подаци: Уграђивања су мање ефикасна када имају непотпуни или бучни улаз. Скалабилност: Потребне су ефикасне методе за велике сетове података; у супротном, латенција ће бити проблем. Superlinked vam omogućava da rešite ove izazove tako što ćete kombinovati sve dostupne podatke o korisnicima i proizvodima u bogate multimodalne vektore.U našem primeru e-trgovine RecSys ispod, mi to radimo pomoću sledećih elemenata Superlinked biblioteke: min_max Бројне просторе: за разумевање рецензија купаца и информација о ценама текст-сличност Простор: за семантичко разумевање информација о производу Схема догађаја и ефекти за модификацију вектора Временске тежине упита - да дефинишете како желите да се подаци обрађују када покренете упит, омогућавајући вам да оптимизујете и скалирате без поновног уграђивања целог скупа података (латенција) Уграђујући наше у почетку ретке податке специфичне за кориснике (почетне преференције производа корисника), можемо се носити са проблемом хладног старта. - персонализовање препорука тако што ћете уградити ове податке о догађају, стварајући петљу за повратне информације која вам омогућава да ажурирате векторе са корисничким преференцијама у реалном времену.Поред тога, Суперлинкед-ове временске тежине упита омогућавају вам да фино прилагодите резултате претраживања, прилагођавајући их да одговарају специфичним корисничким преференцијама. Хипер Let's get started! Изградња мотора за препоруку е-трговине са Суперлинкед-ом Na početku razvoja imamo sledeće • : product data Број рецензента Рејтинг производа Текстски опис Назив производа (обично садржи бренд) Категорије Takođe imamo sledeće • : data about users and products сваки корисник бира један од три понуђене производа приликом регистрације (тј. подаци о преференцијама производа) корисничко понашање (након регистрације) пружа додатне податке о догађају - преференције за текстуалне карактеристике производа (опис, име, категорија) Такође, класична економија нам каже да, у просеку, сви корисници цетерис парибус преферирају производе који: Manje košta Ima mnogo recenzija Imaju veće ocene Možemo da podesimo naše prostorije tako da uzmu u obzir ove podatke, tako da naši RecSys funkcionišu u scenarijima hladnog početka - preporučujući stavke korisnicima o kojima znamo veoma malo.Kada se naš RecSys pokrene i pokrene, takođe ćemo imati podatke o ponašanju: korisnici će kliknuti na određene proizvode, kupiti određene proizvode, itd. Možemo da uhvatimo i koristimo ove podatke o događaju da bismo kreirali povratne informacije, ažurirali naše vektore kako bismo odražavali preferencije korisnika i poboljšali kvalitet preporuka. Постављање суперлинкова Прво, морамо да инсталирамо Суперлинкед библиотеку и увеземо класе. %pip install superlinked==6.0.0 import altair as alt import os import pandas as pd import sys from superlinked.framework.common.embedding.number_embedding import Mode from superlinked.framework.common.schema.schema import schema from superlinked.framework.common.schema.event_schema import event_schema from superlinked.framework.common.schema.schema_object import String, Integer from superlinked.framework.common.schema.schema_reference import SchemaReference 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.index.effect import Effect from superlinked.framework.dsl.query.param import Param from superlinked.framework.dsl.query.query import Query 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.number_space import NumberSpace alt.renderers.enable(get_altair_renderer()) pd.set_option("display.max_colwidth", 190) Такође дефинишемо наше скупове података и створимо константу за складиштење првих 10 ставки - види U beležnici ћелије 3 Сада када су инсталиране библиотеке, увезене класе и локације сета података идентификоване, можемо погледати наш сет података како бисмо информисали како смо подесили наше просторе. У почетку, имамо податке из регистрације корисника - тј. који је од три производа user_1 и user_2 изабрао. # the user preferences come from the user being prompted to select a product out of 3 - those will be the initial preferences # this is done in order to give somewhat personalised recommendations user_df: pd.DataFrame = pd.read_json(USER_DATASET_URL) user_df Такође можемо поставити детаљан преглед података о дистрибуцији наших производа - види Ово вам даје слику о томе колико су производи на различитим ценама, имају различите бројеве прегледа и имају различите оцене (укључујући и где већина производа лежи у овим опсеговима). ћелије 5 Cene za proizvode su uglavnom ispod cene od 1000 dolara. Možda bismo želeli da postavimo raspon prostora na 25-1000 da bi bio reprezentativan, a da ne bude iskrivljen vanjskim vrednostima. Broj pregleda proizvoda je ravnomerno raspodeljen, a ocene pregleda su relativno ravnomerno raspodeljene, tako da nema potrebe za dodatnim tretmanom. . . Књиге 7-9 Изградња индекса за претрагу вектора Библиотека Суперлинкед-а садржи скуп основних грађевинских блокова које користимо за изградњу индекса и управљање претрагом. . . ovde Хајде да ставимо грађевинске блокове ове библиотеке за употребу у нашем ЕЦомм РецСис. da kažete sistemu o vašim podacima. define your Schema # schema is the way to describe the input data flowing into our system - in a typed manner @schema class ProductSchema: description: String name: String category: String price: Integer review_count: Integer review_rating: Integer id: IdField @schema class UserSchema: preference_description: String preference_name: String preference_category: String id: IdField @event_schema class EventSchema: product: SchemaReference[ProductSchema] user: SchemaReference[UserSchema] event_type: String id: IdField # we instantiate schemas as follows product = ProductSchema() user = UserSchema() event = EventSchema() Затим користите Простране да бисте рекли како желите да третирате сваки део података приликом уграђивања. У Пространим дефиницијама описујемо како да уградите уносе тако да одражавају семантичке односе у нашим подацима. Сваки Пространи је оптимизован да угради податке како би вратио највиши могући квалитет резултата претраживања. Који Пространи се користе зависи од вашег типа података. # textual inputs are embedded in a text similarity space powered by a sentence_transformers model description_space = TextSimilaritySpace( text=[user.preference_description, product.description], model="sentence-transformers/all-distilroberta-v1", ) name_space = TextSimilaritySpace( text=[user.preference_name, product.name], model="sentence-transformers/all-distilroberta-v1", ) category_space = TextSimilaritySpace( text=[user.preference_category, product.category], model="sentence-transformers/all-distilroberta-v1", ) # NumberSpaces encode numeric input in special ways to reflect a relationship # here we express relationships to price (lower the better), or ratings and review counts (more/higher the better) price_space = NumberSpace( number=product.price, mode=Mode.MINIMUM, min_value=25, max_value=1000 ) review_count_space = NumberSpace( number=product.review_count, mode=Mode.MAXIMUM, min_value=0, max_value=100 ) review_rating_space = NumberSpace( number=product.review_rating, mode=Mode.MAXIMUM, min_value=0, max_value=4 ) # create the index using the defined spaces product_index = Index( spaces=[ description_space, name_space, category_space, price_space, review_count_space, review_rating_space, ] ) # parse our data into the schemas - not matching column names can be conformed to schemas using the mapping parameter product_df_parser = DataFrameParser(schema=product) user_df_parser = DataFrameParser( schema=user, mapping={user.preference_description: "preference_desc"} ) # setup our application source_product: InMemorySource = InMemorySource(product, parser=product_df_parser) source_user: InMemorySource = InMemorySource(user, parser=user_df_parser) executor: InMemoryExecutor = InMemoryExecutor( sources=[source_product, source_user], indices=[product_index] ) app: InMemoryApp = executor.run() # load the actual data into our system source_product.put([products_df]) source_user.put([user_df]) Сада када имате своје податке дефинисане у просторима, спремни сте да се играте са својим подацима и оптимизујете резултате. - наше хладно-старт решење Шта можемо учинити без догађаја Решавање проблема РеЦСИс хладног старта Овде дефинишемо кориснички упит који претражује само вектор преференција корисника.Имамо контролу конфигурације над важношћу (тежинама) сваког типа уноса (простор). user_query = ( Query( product_index, weights={ description_space: Param("description_weight"), name_space: Param("name_weight"), category_space: Param("category_weight"), price_space: Param("price_weight"), review_count_space: Param("review_count_weight"), review_rating_space: Param("review_rating_weight"), }, ) .find(product) .with_vector(user, Param("user_id")) .limit(Param("limit")) ) # simple recommendations for our user_1 # these are based only on the initial product the user chose when first entering our site simple_result = app.query( user_query, user_id="user_1", description_weight=1, name_weight=1, category_weight=1, price_weight=1, review_count_weight=1, review_rating_weight=1, limit=TOP_N, ) simple_result.to_pandas() Резултати овог упита одражавају чињеницу да је user_1 изабрао торбу када се први пут регистровао на нашем сајту ecomm. Такође је могуће препоручити производе кориснику_1 који су привлачан - то јест, на основу њихове ниске цене и са пуно добрих рецензија. Наши резултати ће сада одражавати и избор производа корисника_1 при регистрацији Општа популарност производа. (Такође можемо играти са овим теговима да искривимо резултате у правцу једног простора или другог.) Генерално и general_result = app.query( user_query, user_id="user_1", description_weight=0, name_weight=0, category_weight=0, price_weight=1, review_count_weight=1, review_rating_weight=1, limit=TOP_N, ) general_result.to_pandas() Претрага новог корисника уводи текст упита као унос за наше резултате препоруке - погледајте . . ћелије 20 U našem primeru, user_1 je pretraživao po rečima "ženska odeća".Možemo da optimizujemo naše rezultate dajući (на језику ), да препоручи више "жена одећа јакне" производа. additional weight to the category space category_weight = 10 women_cat_result = app.query( search_query, user_id="user_1", query_text="women clothing jackets", description_weight=1, name_weight=1, category_weight=10, price_weight=1, review_count_weight=1, review_rating_weight=1, limit=TOP_N, ) women_cat_result.to_pandas() Наша додатна категорија тежине производи више резултата женске одеће. Такође можемо да подијелимо наше препоруке на најбоље оцењене производе ( Резултати сада одражавају почетну преференцију корисника_1 за торбе и предмете који су генерално популарни, док се производи са ниским оценама у потпуности уклањају. . . review_rating_weight=5 Ћелија 22 Korišćenje podataka o događajima za kreiranje personalizovanih iskustava Брзо напред месец дана. Наши корисници су комуницирали са нашом платформом - user_1 више, user_2 мање. (погледајте испод), представљен као догађаји: behavioral data корисник заинтересован за случајне и рекреативне производе (user_2) корисник заинтересован за елегантне производе за излазак и формалне радне прилике (user_1) events_df = ( pd.read_json(EVENT_DATASET_URL) .reset_index() .rename(columns={"index": "id"}) .head(NROWS) ) events_df = events_df.merge( products_df[["id"]], left_on="product", right_on="id", suffixes=("", "r") ).drop("idr", axis=1) events_df = events_df.assign(created_at=1715439600) events_df Хајде да проценимо специфичне акције за регистрацију нивоа интересовања корисника за одређени производ и прилагодимо подешавање да би се узели у обзир догађаји приликом извођења претраге. event_weights = { "clicked_on": 0.2, "buy": 1, "put_to_cart": 0.5, "removed_from_cart": -0.5, } # adjust the setup to events product_index_with_events = Index( spaces=[ description_space, category_space, name_space, price_space, review_count_space, review_rating_space, ], effects=[ Effect( description_space, event.user, event_weight * event.product, event.event_type == event_type, ) for event_type, event_weight in event_weights.items() ] + [ Effect( category_space, event.user, event_weight * event.product, event.event_type == event_type, ) for event_type, event_weight in event_weights.items() ] + [ Effect( name_space, event.user, event_weight * event.product, event.event_type == event_type, ) for event_type, event_weight in event_weights.items() ], ) event_df_parser: DataFrameParser = DataFrameParser(schema=event) source_event: InMemorySource = InMemorySource(schema=event, parser=event_df_parser) executor_with_events: InMemoryExecutor = InMemoryExecutor( sources=[source_product, source_user, source_event], indices=[product_index_with_events], ) app_with_events: InMemoryApp = executor_with_events.run() Сада креирамо нови индекс који узима у обзир догађаје корисника, а затим персонализујемо препоруке сваком кориснику у складу с тим. # for a new index, all data has to be put into the source again source_product.put([products_df]) source_user.put([user_df]) source_event.put([events_df]) # a query only searching with the user's vector the preferences are now much more personalised thanks to the events personalised_query = ( Query( product_index_with_events, weights={ description_space: Param("description_weight"), category_space: Param("category_weight"), name_space: Param("name_weight"), price_space: Param("price_weight"), review_count_space: Param("review_count_weight"), review_rating_space: Param("review_rating_weight"), }, ) .find(product) .with_vector(user, Param("user_id")) .limit(Param("limit")) ) Можемо посматрати утицај укључивања догађаја у наше РецСис тежином персонализације или Прво, хајде да видимо ефекат (у поређењу са излазном линијом) тежине простора који су под утицајем ових (понашања података) догађаја. samo malo Тешко # with small weight on event-affected spaces, we mainly just alter the results below position 4 general_event_result = app_with_events.query( personalised_query, user_id="user_1", description_weight=1, category_weight=1, name_weight=1, price_weight=1, review_count_weight=1, review_rating_weight=1, limit=TOP_N, ) general_event_result.to_pandas().join( simple_result.to_pandas(), lsuffix="", rsuffix="_base" )[["description", "id", "description_base", "id_base"]] Са врло малом тежином која се ставља на Простор који утиче на догађаје, примећујемо промену, али углавном само у другој половини наше топ 10 у поређењу са претходним резултатима ("ид_басе", на десној страни). Али ако тежимо просторе погођене догађајима теже, на листи препорука наносимо потпуно нове ставке. # with larger weight on the the event-affected spaces, more totally new items appear in the TOP10 event_weighted_result = app_with_events.query( personalised_query, user_id="user_1", query_text="", description_weight=5, category_weight=1, name_weight=1, price_weight=1, review_count_weight=1, review_rating_weight=1, limit=TOP_N, ) event_weighted_result.to_pandas().join( simple_result.to_pandas(), lsuffix="", rsuffix="_base" )[["description", "id", "description_base", "id_base"]] Такође, наравно, можемо користити тегове за персонализацију наших препорука на основу понашања одређеног корисника (подаци о догађајима) и На пример, цена (погледајте ) истовремено даје приоритет другим атрибутима производа ћелије 31 Закључак Implementacija eComm RecSys Superlinked biblioteke (iznad) pokazuje vam kako da ostvarite moć vektorskih ugrađivanja tako što ćete integrisati semantičko značenje korisničkih upita i podataka o ponašanju. Koristeći naše min_max brojeve i tekstovne sličnosti, sheme događaja i efekte, kao i vremenske težine upita, možete da rešite izazove hladnog početka, kvaliteta i relevantnosti i skalabilnosti RecSys-a i da pružite veoma precizne, korisnicima prilagođene preporuke u proizvodnji. Сада је твој ред! . . Покушајте сами да имплементирате Суперлинкед библиотеку користећи наш нотебоок Try It Yourself – Get the Code & Demo! Покушајте сами - добити код и демо! Ухватите код: Погледајте пуну имплементацију у нашем ГитХуб репо-у овде.Форк га, подесите га и направите га својим! Гледајте га у акцији: Желите да видите да ово ради у реалном свету? резервишите брзу демо и истражите како Суперлинкед може преоптеретити ваше препоруке. ovde ovde . . Мотори за препоруке обликују начин на који откривамо садржај, било да се ради о популарним панталонама, музици или другим производима, — и сада имате алате за изградњу своје. vector search is the future