{"id":71852,"date":"2020-02-28T20:59:58","date_gmt":"2020-02-28T17:59:58","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij"},"modified":"2020-03-03T16:14:08","modified_gmt":"2020-03-03T13:14:08","slug":"kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij","title":{"rendered":"Jak pracujemy nad jako\u015bci\u0105 i szybko\u015bci\u0105 rekomendacji","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Nazywam si\u0119 Pawe\u0142 Parhomenko, jestem deweloperem ML. W tym artykule chcia\u0142bym opowiedzie\u0107 o dzia\u0142aniu us\u0142ugi Yandex Zen i podzieli\u0107 si\u0119 technicznymi usprawnieniami, kt\u00f3rych wdro\u017cenie pozwoli\u0142o zwi\u0119kszy\u0107 jako\u015b\u0107 rekomendacji. Z wpisu dowiesz si\u0119, jak w zaledwie kilka milisekund znale\u017a\u0107 w\u015br\u00f3d milion\u00f3w dokument\u00f3w te najbardziej relevantne dla u\u017cytkownika; jak przeprowadza\u0107 ci\u0105g\u0142e rozk\u0142adanie du\u017cej macierzy (sk\u0142adaj\u0105cej si\u0119 z milion\u00f3w kolumn i dziesi\u0105tek milion\u00f3w wierszy), aby nowe dokumenty otrzymywa\u0142y sw\u00f3j wektor w ci\u0105gu dziesi\u0105tek minut; jak ponownie wykorzysta\u0107 rozk\u0142adanie macierzy u\u017cytkownik-artyk\u00f3\u0142, aby uzyska\u0107 dobre wektorowe przedstawienie dla wideo.<\/p>\n<p><img decoding=\"async\" alt=\"Jak pracujemy nad jako\u015bci\u0105 i szybko\u015bci\u0105 rekomendacji\" src=\"\/wp-content\/uploads\/2020\/02\/d63caf9162ca3533548fdef9cd740c24.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex> <br \/>\nNasza baza rekomendacyjna zawiera miliony dokument\u00f3w r\u00f3\u017cnego formatu: artyku\u0142y tekstowe, stworzone na naszej platformie i pobrane z zewn\u0119trznych stron, wideo, narracje i kr\u00f3tkie posty. Rozw\u00f3j takiej us\u0142ugi wi\u0105\u017ce si\u0119 z wieloma wyzwaniami technicznymi. Oto niekt\u00f3re z nich:<\/p>\n<ul>\n<li>Podzieli\u0107 zadania obliczeniowe: wszystkie ci\u0119\u017ckie operacje realizowa\u0107 offline, a w czasie rzeczywistym wykonywa\u0107 tylko szybkie zastosowanie modeli, aby odpowiada\u0107 w ci\u0105gu 100-200 ms.<\/li>\n<li>Szybko uwzgl\u0119dnia\u0107 dzia\u0142ania u\u017cytkownika. W tym celu wszystkie zdarzenia musz\u0105 by\u0107 natychmiast dostarczane do rekomendatora i wp\u0142ywa\u0107 na wyniki pracy modeli.<\/li>\n<li>Sprawi\u0107, aby feed nowych u\u017cytkownik\u00f3w szybko dostosowywa\u0142 si\u0119 do ich zachowa\u0144. Osoby, kt\u00f3re w\u0142a\u015bnie do\u0142\u0105czy\u0142y do systemu, powinny odczuwa\u0107, \u017ce ich feedback wp\u0142ywa na rekomendacje.<\/li>\n<li>Szybko rozumie\u0107, komu poleci\u0107 nowy artyku\u0142.<\/li>\n<li>B\u0142yskawicznie reagowa\u0107 na ci\u0105g\u0142e pojawianie si\u0119 nowej tre\u015bci. Codziennie ukazuje si\u0119 dziesi\u0105tki tysi\u0119cy artyku\u0142\u00f3w, wiele z nich ma ograniczony czas \u017cycia (powiedzmy, wiadomo\u015bci). W tym r\u00f3\u017cni\u0105 si\u0119 od film\u00f3w, muzyki i innej d\u0142ugotrwa\u0142ej i kosztownej w produkcji tre\u015bci.<\/li>\n<li>Przenosi\u0107 wiedz\u0119 z jednej dziedziny na drug\u0105. Je\u015bli w systemie rekomendacyjnym znajduj\u0105 si\u0119 wytrenowane modele dla artyku\u0142\u00f3w tekstowych i dodajemy do niego wideo, mo\u017cna ponownie wykorzysta\u0107 istniej\u0105ce modele, aby tre\u015b\u0107 nowego typu by\u0142a lepiej klasyfikowana.<\/li>\n<\/ul>\n<p>\nOpowiem, jak rozwi\u0105zali\u015bmy te zadania.<\/p>\n<h2>Selekcja kandydat\u00f3w<\/h2>\n<p>\n<b>Jak w kilka milisekund skr\u00f3ci\u0107 liczb\u0119 analizowanych dokument\u00f3w tysi\u0105ckrotnie, praktycznie nie pogarszaj\u0105c jako\u015bci ranking\u00f3w?<\/b><\/p>\n<p>Za\u0142\u00f3\u017cmy, \u017ce wytrenujemy wiele modeli ML, wygenerujemy na ich podstawie cechy i wytrenujemy kolejny model, kt\u00f3ry klasyfikuje dokumenty dla u\u017cytkownika. Wszystko by\u0142oby dobrze, ale nie mo\u017cna po prostu obliczy\u0107 wszystkich cech dla wszystkich dokument\u00f3w w czasie rzeczywistym, gdy tych dokument\u00f3w s\u0105 miliony, a zalecenia musz\u0105 by\u0107 tworzone w ci\u0105gu 100-200 ms. Zadanie polega na wybraniu z milion\u00f3w pewnego podzbioru, kt\u00f3ry zostanie sklasyfikowany dla u\u017cytkownika. Ten etap zazwyczaj nazywamy selekcj\u0105 kandydat\u00f3w. Istnieje kilka wymaga\u0144. Po pierwsze, selekcja musi przebiega\u0107 bardzo szybko, aby na samo klasyfikowanie pozosta\u0142o jak najwi\u0119cej czasu. Po drugie, znacznie redukuj\u0105c liczb\u0119 dokument\u00f3w do klasyfikacji, powinni\u015bmy jak najdok\u0142adniej zachowa\u0107 dokumenty istotne dla u\u017cytkownika.<\/p>\n<p>Nasza zasada selekcji kandydat\u00f3w ewoluowa\u0142a i obecnie doszli\u015bmy do wieloetapowego schematu:<\/p>\n<p><img decoding=\"async\" alt=\"Jak pracujemy nad jako\u015bci\u0105 i szybko\u015bci\u0105 rekomendacji\" src=\"\/wp-content\/uploads\/2020\/02\/ed9657ed1febe871f36dc7cf7e585963.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nNa pocz\u0105tku wszystkie dokumenty s\u0105 dzielone na grupy, a z ka\u017cdej grupy wybierane s\u0105 najbardziej popularne dokumenty. Grupami mog\u0105 by\u0107 strony, tematy, klastry. Dla ka\u017cdego u\u017cytkownika na podstawie jego historii dobierane s\u0105 najbli\u017csze mu grupy, a nast\u0119pnie z nich wybierane s\u0105 najlepsze dokumenty. U\u017cywamy r\u00f3wnie\u017c indeksu kNN do dobierania najbardziej zbli\u017conych dokument\u00f3w do u\u017cytkownika w czasie rzeczywistym. Istnieje kilka metod budowy indeksu kNN, u nas najlepiej dzia\u0142a <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1603.09320\">HNSW<\/a><\/noindex> (Hierarchical Navigable Small World graphs). To hierarchiczny model, kt\u00f3ry pozwala w kilka milisekund znale\u017a\u0107 N najbli\u017cszych wektor\u00f3w dla u\u017cytkownika z milionowej bazy. Wcze\u015bniej indeksujemy ca\u0142\u0105 nasz\u0105 baz\u0119 dokument\u00f3w offline. Poniewa\u017c wyszukiwanie w indeksie dzia\u0142a do\u015b\u0107 szybko, przy obecno\u015bci kilku silnych embedding\u00f3w mo\u017cna stworzy\u0107 kilka indeks\u00f3w (po jednym dla ka\u017cdego embeddingu) i odnosi\u0107 si\u0119 do ka\u017cdego z nich w czasie rzeczywistym.<\/p>\n<p>Mamy dziesi\u0105tki tysi\u0119cy dokument\u00f3w dla ka\u017cdego u\u017cytkownika. Nadal jest to du\u017co do zliczenia wszystkich cech, wi\u0119c na tym etapie stosujemy lekkie rankingowanie \u2014 uproszczony model ci\u0119\u017ckiego rankingowania z mniejsz\u0105 liczb\u0105 cech. Celem jest przewidzenie, kt\u00f3re dokumenty znajd\u0105 si\u0119 na czo\u0142owej pozycji w ci\u0119\u017ckim modelu. Dokumenty z najwy\u017cszym predyktem b\u0119d\u0105 wykorzystane w ci\u0119\u017ckim modelu, czyli na ostatnim etapie rankingowania. To podej\u015bcie pozwala w ci\u0105gu dziesi\u0105tek milisekund skr\u00f3ci\u0107 baz\u0119 rozpatrywanych dokument\u00f3w z milion\u00f3w do tysi\u0119cy.<\/p>\n<h2>Krok ALS w czasie rzeczywistym<\/h2>\n<p>\n<b>Jak uwzgl\u0119dnia\u0107 feedback u\u017cytkownika zaraz po klikni\u0119ciu?<\/b><\/p>\n<p>Wa\u017cnym czynnikiem w rekomendacjach jest czas reakcji na feedback u\u017cytkownika. Jest to szczeg\u00f3lnie istotne dla nowych u\u017cytkownik\u00f3w: gdy osoba dopiero zaczyna korzysta\u0107 z systemu rekomendacji, otrzymuje niepersonalizowany strumie\u0144 r\u00f3\u017cnorodnych dokument\u00f3w tematycznych. Gdy tylko dokona pierwszego klikni\u0119cia, konieczne jest, aby natychmiast to uwzgl\u0119dni\u0107 i dostosowa\u0107 si\u0119 do jego zainteresowa\u0144. Je\u015bli wszystkie czynniki b\u0119d\u0105 obliczane offline, szybka reakcja systemu stanie si\u0119 niemo\u017cliwa z powodu op\u00f3\u017anienia. Z tego powodu konieczne jest przetwarzanie dzia\u0142a\u0144 u\u017cytkownika w czasie rzeczywistym. Do tych cel\u00f3w u\u017cywamy kroku ALS w czasie rzeczywistym do budowy wektorowego przedstawienia u\u017cytkownika.<\/p>\n<p>Za\u0142\u00f3\u017cmy, \u017ce dla wszystkich dokument\u00f3w mamy wektorowe przedstawienie. Na przyk\u0142ad, mo\u017cemy offline na podstawie tekstu artyku\u0142u zbudowa\u0107 embeddingi przy u\u017cyciu ELMo, BERT lub innych modeli uczenia maszynowego. Jak mo\u017cna uzyska\u0107 wektorowe przedstawienie u\u017cytkownik\u00f3w w tej samej przestrzeni na podstawie ich interakcji w systemie?<\/p>\n<p><b class=\"spoiler_title\">Og\u00f3lny zasada formowania i rozk\u0142adu macierzy u\u017cytkownik-dokument<\/b>Za\u0142\u00f3\u017cmy, \u017ce mamy m u\u017cytkownik\u00f3w i n dokument\u00f3w. Dla niekt\u00f3rych u\u017cytkownik\u00f3w znana jest ich relacja z niekt\u00f3rymi dokumentami. Informacje te mo\u017cna przedstawi\u0107 w postaci macierzy m x n: wiersze odpowiadaj\u0105 u\u017cytkownikom, a kolumny \u2013 dokumentom. Poniewa\u017c wi\u0119kszo\u015b\u0107 dokument\u00f3w nie zosta\u0142a przez cz\u0142owieka zobaczona, wi\u0119kszo\u015b\u0107 kom\u00f3rek macierzy pozostanie pustych, a inne b\u0119d\u0105 wype\u0142nione. Dla ka\u017cdego zdarzenia (polubienia, niepolubienia, klikni\u0119cia) w macierzy przewidziana jest jaka\u015b warto\u015b\u0107 \u2013 na razie rozwa\u017cmy uproszczony model, w kt\u00f3rym polubienie odpowiada 1, a niepolubienie \u20131.<\/p>\n<p>Roz\u0142o\u017cymy macierz na dwie: P (m x d) i Q (d x n), gdzie d to wymiar wektorowego przedstawienia (zazwyczaj jest to ma\u0142a liczba). W\u00f3wczas ka\u017cdy obiekt b\u0119dzie odpowiada\u0142 wektorowi d-wymiarowemu (u\u017cytkownik \u2013 wiersz w macierzy P, dokument \u2013 kolumna w macierzy Q). Te wektory b\u0119d\u0105 embeddingami odpowiednich obiekt\u00f3w. Aby przewidzie\u0107, czy u\u017cytkownikowi spodoba si\u0119 dokument, wystarczy pomno\u017cy\u0107 ich embeddingi.<\/p>\n<p><img decoding=\"async\" alt=\"Jak pracujemy nad jako\u015bci\u0105 i szybko\u015bci\u0105 rekomendacji\" src=\"\/wp-content\/uploads\/2020\/02\/a0c721bccb3806f2c4a18693a9458a89.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nJednym z mo\u017cliwych sposob\u00f3w rozk\u0142adu macierzy jest ALS (Alternating Least Squares). B\u0119dziemy optymalizowa\u0107 nast\u0119puj\u0105c\u0105 funkcj\u0119 straty:<\/p>\n<p><img decoding=\"async\" alt=\"Jak pracujemy nad jako\u015bci\u0105 i szybko\u015bci\u0105 rekomendacji\" src=\"\/wp-content\/uploads\/2020\/02\/aab8a1ae1cdf39de21e7469864c5190a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>\nTutaj rui to interakcja u\u017cytkownika u z dokumentem i, qi to wektor dokumentu i, pu to wektor u\u017cytkownika u.<\/p>\n<p>Wtedy optymalny z punktu widzenia \u015bredniego b\u0142\u0119du kwadratowego wektor u\u017cytkownika (przy sta\u0142ych wektorach dokument\u00f3w) znajduje si\u0119 analitycznie poprzez rozwi\u0105zanie odpowiedniej regresji liniowej.<\/p>\n<p>Nazywa si\u0119 to \u201ekrokiem ALS\u201d. Sam algorytm ALS polega na tym, \u017ce na przemian ustalamy jedn\u0105 z macierzy (u\u017cytkownik\u00f3w i artyku\u0142\u00f3w) i aktualizujemy drug\u0105, znajduj\u0105c optymalne rozwi\u0105zanie.<\/p>\n<p>Na szcz\u0119\u015bcie, znalezienie wektorowego przedstawienia u\u017cytkownika to do\u015b\u0107 szybka operacja, kt\u00f3r\u0105 mo\u017cna wykonywa\u0107 w czasie rzeczywistym, wykorzystuj\u0105c instrukcje wektorowe. Ten trik pozwala od razu uwzgl\u0119dni\u0107 opinie u\u017cytkownika w rankingach. Ten sam embedding mo\u017cna wykorzysta\u0107 tak\u017ce w indeksie kNN, aby ulepszy\u0107 wyb\u00f3r kandydat\u00f3w.<\/p>\n<h2>Rozproszona filtracja wsp\u00f3\u0142pracy<\/h2>\n<p>\n<b>Jak przeprowadza\u0107 inkrementaln\u0105 rozproszon\u0105 faktoryzacj\u0119 macierzy i szybko znajdowa\u0107 wektorowe przedstawienie nowych artyku\u0142\u00f3w?<\/b><\/p>\n<p>Tre\u015b\u0107 to nie jedyne \u017ar\u00f3d\u0142o sygna\u0142\u00f3w dla rekomendacji. Innym wa\u017cnym \u017ar\u00f3d\u0142em jest informacja kolaboracyjna. Dobre wskaz\u00f3wki w rankingach tradycyjnie mo\u017cna uzyska\u0107 z dekompozycji macierzy u\u017cytkownik-dokument. Jednak podczas pr\u00f3by przeprowadzenia takiej dekompozycji napotkali\u015bmy problemy:<\/p>\n<p>1. Mamy miliony dokument\u00f3w i dziesi\u0105tki milion\u00f3w u\u017cytkownik\u00f3w. Macierz nie mie\u015bci si\u0119 w ca\u0142o\u015bci na jednym urz\u0105dzeniu, a dekompozycja zajmie bardzo du\u017co czasu.<br \/>\n2. Wi\u0119kszo\u015b\u0107 tre\u015bci w systemie ma kr\u00f3tki czas \u017cycia: dokumenty pozostaj\u0105 aktualne tylko przez kilka godzin. Dlatego trzeba jak najszybciej zbudowa\u0107 ich wektorowe przedstawienie.<br \/>\n3. Je\u015bli dekompozycja zostanie przeprowadzona tu\u017c po publikacji dokumentu, nie zd\u0105\u017cy on by\u0107 oceniony przez wystarczaj\u0105c\u0105 liczb\u0119 u\u017cytkownik\u00f3w. Dlatego jego wektorowe przedstawienie ma du\u017c\u0105 szans\u0119 na to, \u017ce b\u0119dzie niew\u0142a\u015bciwe.<br \/>\n4. Je\u015bli u\u017cytkownik daje ocen\u0119 pozytywn\u0105 lub negatywn\u0105, nie b\u0119dziemy mogli uwzgl\u0119dni\u0107 tego na bie\u017c\u0105co w dekompozycji.<\/p>\n<p>Aby rozwi\u0105za\u0107 wymienione problemy, zrealizowali\u015bmy rozproszon\u0105 dekompozycj\u0119 macierzy u\u017cytkownik-dokument z cz\u0119stymi inkrementalnymi aktualizacjami. Jak dok\u0142adnie to dzia\u0142a?<\/p>\n<p>Przypu\u015b\u0107my, \u017ce mamy klaster z N maszynami (N liczony w setkach) i chcemy przeprowadzi\u0107 rozproszon\u0105 dekompozycj\u0119 macierzy, kt\u00f3ra nie mie\u015bci si\u0119 na jednej maszynie. Pytanie brzmi: jak wykona\u0107 t\u0119 dekompozycj\u0119, tak aby, z jednej strony, na ka\u017cdej maszynie by\u0142o wystarczaj\u0105co du\u017co danych, a z drugiej, obliczenia by\u0142y niezale\u017cne? <\/p>\n<p><img decoding=\"async\" alt=\"Jak pracujemy nad jako\u015bci\u0105 i szybko\u015bci\u0105 rekomendacji\" src=\"\/wp-content\/uploads\/2020\/02\/9170b0fecb6efcd41754ec20ee539a15.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nB\u0119dziemy u\u017cywa\u0107 algorytmu dekompozycji ALS opisanego powy\u017cej. Zobaczmy, jak rozproszono przeprowadzi\u0107 jeden krok ALS \u2013 pozosta\u0142e kroki b\u0119d\u0105 podobne. Za\u0142\u00f3\u017cmy, \u017ce mamy ustalon\u0105 macierz dokument\u00f3w i chcemy zbudowa\u0107 macierz u\u017cytkownik\u00f3w. W tym celu podzielimy j\u0105 na N cz\u0119\u015bci wed\u0142ug wierszy, a ka\u017cda cz\u0119\u015b\u0107 b\u0119dzie zawiera\u0107 mniej wi\u0119cej t\u0119 sam\u0105 liczb\u0119 wierszy. Roz\u015blemy do ka\u017cdej maszyny niepuste kom\u00f3rki odpowiednich wierszy, a tak\u017ce ca\u0142\u0105 macierz osadze\u0144 dokument\u00f3w. Poniewa\u017c nie jest ona zbyt du\u017cych rozmiar\u00f3w, a macierz u\u017cytkownik-dokument jest zazwyczaj bardzo rzadka, te dane zmieszcz\u0105 si\u0119 na zwyk\u0142ej maszynie.<\/p>\n<p>Taki trik mo\u017cna powtarza\u0107 przez kilka epok a\u017c do zbie\u017cno\u015bci modelu, zmieniaj\u0105c kolejno sta\u0142\u0105 macierz. Jednak nawet wtedy rozk\u0142ad macierzy mo\u017ce trwa\u0107 kilka godzin. I to nie rozwi\u0105zuje problemu szybkiego uzyskiwania embedding\u00f3w nowych dokument\u00f3w oraz aktualizowania embedding\u00f3w tych, o kt\u00f3rych by\u0142o ma\u0142o informacji podczas tworzenia modelu. <\/p>\n<p>Pomo\u017c\u0142a nam implementacja szybkiej inkrementalnej aktualizacji modelu. Za\u0142\u00f3\u017cmy, \u017ce mamy aktualnie wytrenowany model. Od momentu jego wytrenowania pojawi\u0142y si\u0119 nowe artyku\u0142y, z kt\u00f3rymi wsp\u00f3\u0142dzia\u0142ali nasi u\u017cytkownicy, oraz artyku\u0142y, kt\u00f3re mia\u0142y ma\u0142o interakcji podczas szkolenia. Aby szybko uzyska\u0107 embeddingi takich artyku\u0142\u00f3w, wykorzystujemy embeddingi u\u017cytkownik\u00f3w uzyskane podczas pierwszego du\u017cego szkolenia modelu i wykonujemy jeden krok ALS, aby obliczy\u0107 macierz dokument\u00f3w przy sta\u0142ej macierzy u\u017cytkownik\u00f3w. To pozwala na szybkie uzyskiwanie embedding\u00f3w \u2014 w ci\u0105gu kilku minut po publikacji dokumentu \u2014 i cz\u0119ste aktualizowanie embedding\u00f3w \u015bwie\u017cych dokument\u00f3w.<\/p>\n<p>Aby dzia\u0142ania cz\u0142owieka by\u0142y od razu uwzgl\u0119dniane w rekomendacjach, w czasie rzeczywistym nie korzystamy z embedding\u00f3w u\u017cytkownik\u00f3w uzyskanych offline. Zamiast tego wykonujemy krok ALS i uzyskujemy aktualny wektor u\u017cytkownika.<\/p>\n<h2>Przeniesienie do innej domeny<\/h2>\n<p>\n<b>Jak wykorzysta\u0107 opinie u\u017cytkownik\u00f3w dotycz\u0105ce artyku\u0142\u00f3w tekstowych do budowy wektorowego przedstawienia wideo?<\/b><\/p>\n<p>Pocz\u0105tkowo rekomendowali\u015bmy jedynie artyku\u0142y tekstowe, dlatego wiele naszych algorytm\u00f3w by\u0142o dostosowanych do tego typu tre\u015bci. Jednak przy dodawaniu tre\u015bci innego typu napotykali\u015bmy potrzeb\u0119 dostosowania modeli. Jak rozwi\u0105zali\u015bmy ten problem na przyk\u0142adzie wideo? Jednym z rozwi\u0105za\u0144 by\u0142oby ponowne wytrenowanie wszystkich modeli od zera. Jednak to zajmuje du\u017co czasu, a ponadto cz\u0119\u015b\u0107 algorytm\u00f3w jest wymagaj\u0105ca pod wzgl\u0119dem obj\u0119to\u015bci zbioru treningowego, kt\u00f3rego jeszcze nie ma w odpowiedniej ilo\u015bci dla nowego typu tre\u015bci w pierwszych momentach jej obecno\u015bci w serwisie.<\/p>\n<p>Poszli\u015bmy inn\u0105 drog\u0105 i wykorzystali\u015bmy modele tekstu dla wideo. W stworzeniu wektorowych reprezentacji wideo pomog\u0142a nam ta sama sztuczka z ALS. Wzi\u0119li\u015bmy wektorow\u0105 reprezentacj\u0119 u\u017cytkownik\u00f3w na podstawie artyku\u0142\u00f3w tekstowych i wykonali\u015bmy krok ALS, wykorzystuj\u0105c informacje o ogl\u0105daniu wideo. W ten spos\u00f3b bez trudu uzyskali\u015bmy wektorow\u0105 reprezentacj\u0119 wideo. W czasie rzeczywistym obliczamy po\u0142\u0105czenie mi\u0119dzy wektorem u\u017cytkownika, uzyskanym na podstawie artyku\u0142\u00f3w tekstowych, a wektorem wideo.<\/p>\n<h2>Podsumowanie<\/h2>\n<p>\nRozw\u00f3j rdzenia systemu rekomendacji w czasie rzeczywistym wi\u0105\u017ce si\u0119 z wieloma zadaniami. Nale\u017cy szybko przetwarza\u0107 dane i stosowa\u0107 metody ML do efektywnego wykorzystania tych danych; budowa\u0107 z\u0142o\u017cone rozproszone systemy, kt\u00f3re potrafi\u0105 w minimalnym czasie przetwarza\u0107 sygna\u0142y u\u017cytkownik\u00f3w oraz nowe jednostki tre\u015bci; i wiele innych zada\u0144.<\/p>\n<p>W obecnym systemie, kt\u00f3rego konstrukcj\u0119 opisuj\u0119, jako\u015b\u0107 rekomendacji dla u\u017cytkownika ro\u015bnie wraz z jego aktywno\u015bci\u0105 i czasem sp\u0119dzonym w serwisie. Ale oczywi\u015bcie, tu kryje si\u0119 r\u00f3wnie\u017c g\u0142\u00f3wna trudno\u015b\u0107: systemowi trudno jest na pierwszy rzut oka zrozumie\u0107 zainteresowania osoby, kt\u00f3ra ma\u0142o interagowa\u0142a z tre\u015bciami. Poprawa rekomendacji dla nowych u\u017cytkownik\u00f3w to nasze kluczowe zadanie. B\u0119dziemy nadal optymalizowa\u0107 algorytmy, aby odpowiednia dla danej osoby tre\u015b\u0107 szybciej trafia\u0142a do jego kana\u0142u, a nieodpowiednia nie by\u0142a wy\u015bwietlana.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/yandex\/blog\/490140\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u041f\u0430\u0440\u0445\u043e\u043c\u0435\u043d\u043a\u043e, \u044f ML-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0431 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u042f\u043d\u0434\u0435\u043a\u0441.\u0414\u0437\u0435\u043d \u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f\u043c\u0438, \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439. \u0418\u0437 \u043f\u043e\u0441\u0442\u0430 \u0432\u044b \u0443\u0437\u043d\u0430\u0435\u0442\u0435, \u043a\u0430\u043a \u0432\u0441\u0435\u0433\u043e \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0438\u043b\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u0440\u0435\u0434\u0438 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f; \u043a\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e\u0435 \u0440\u0430\u0437\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043c\u0430\u0442\u0440\u0438\u0446\u044b (\u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0439 \u0438\u0437 \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":71853,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-71852","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u041f\u0430\u0440\u0445\u043e\u043c\u0435\u043d\u043a\u043e, \u044f ML-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0431 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u042f\u043d\u0434\u0435\u043a\u0441.\u0414\u0437\u0435\u043d \u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f\u043c\u0438, \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043d\u0430\u0434 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0434\u0431\u043e\u0440\u0430 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u041f\u0430\u0440\u0445\u043e\u043c\u0435\u043d\u043a\u043e, \u044f ML-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0431 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u042f\u043d\u0434\u0435\u043a\u0441.\u0414\u0437\u0435\u043d \u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f\u043c\u0438, \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-02-28T17:59:58+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-03T13:14:08+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Jak pracujemy nad jako\u015bci\u0105 i szybko\u015bci\u0105 dobrania rekomendacji | ProHoster","description":"Nazywam si\u0119 Pawe\u0142 Parchomenko, jestem programist\u0105 ML. W tym artykule chcia\u0142bym opowiedzie\u0107 o konstrukcji serwisu Yandex.Zen oraz podzieli\u0107 si\u0119 technicznymi ulepszeniami, kt\u00f3rych wprowadzenie pozwoli\u0142o zwi\u0119kszy\u0107 jako\u015b\u0107 rekomendacji.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043d\u0430\u0434 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0438 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0434\u0431\u043e\u0440\u0430 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439 | ProHoster","og:description":"\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u041f\u0430\u0440\u0445\u043e\u043c\u0435\u043d\u043a\u043e, \u044f ML-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0431 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u042f\u043d\u0434\u0435\u043a\u0441.\u0414\u0437\u0435\u043d \u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f\u043c\u0438, \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0439.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-02-28T17:59:58+00:00","article:modified_time":"2020-03-03T13:14:08+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"71852","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 18:55:28","updated":"2022-10-09 15:47:56","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/71852","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=71852"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/71852\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/71853"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=71852"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=71852"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=71852"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}