{"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\/es\/blog\/administrirovanie\/kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij","title":{"rendered":"C\u00f3mo trabajamos en la calidad y velocidad de la selecci\u00f3n de recomendaciones","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Me llamo Pavel Parkhomenko, soy desarrollador de ML. En este art\u00edculo, me gustar\u00eda hablar sobre el funcionamiento del servicio Yandex.Zen y compartir mejoras t\u00e9cnicas cuya implementaci\u00f3n ha permitido aumentar la calidad de las recomendaciones. En la publicaci\u00f3n, aprender\u00e1s c\u00f3mo encontrar en cuesti\u00f3n de milisegundos los documentos m\u00e1s relevantes entre millones; c\u00f3mo realizar una descomposici\u00f3n continua de una gran matriz (que consta de millones de columnas y decenas de millones de filas) para que los nuevos documentos obtengan su vector en cuesti\u00f3n de minutos; c\u00f3mo reutilizar la descomposici\u00f3n de la matriz usuario-art\u00edculo para obtener una buena representaci\u00f3n vectorial para videos.<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo trabajamos en la calidad y velocidad de la selecci\u00f3n de recomendaciones\" 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 \/>\nNuestra base de recomendaciones contiene millones de documentos de diferentes formatos: art\u00edculos de texto creados en nuestra plataforma y tomados de sitios externos, videos, narrativas y publicaciones breves. El desarrollo de un servicio como este implica numerosos desaf\u00edos t\u00e9cnicos. Algunos de ellos son:<\/p>\n<ul>\n<li>Dividir las tareas computacionales: realizar todas las operaciones pesadas de forma offline, y aplicar modelos de forma r\u00e1pida en tiempo real, para responder en 100-200 ms.<\/li>\n<li>Registrar r\u00e1pidamente las acciones del usuario. Para ello, es necesario que todos los eventos se env\u00eden instant\u00e1neamente al recomendador y afecten los resultados de los modelos.<\/li>\n<li>Hacer que el feed se adapte r\u00e1pidamente al comportamiento de los nuevos usuarios. Los reci\u00e9n llegados al sistema deben sentir que sus comentarios influyen en las recomendaciones.<\/li>\n<li>Entender r\u00e1pidamente a qui\u00e9n recomendar un nuevo art\u00edculo.<\/li>\n<li>Reaccionar de manera \u00e1gil a la aparici\u00f3n constante de nuevo contenido. Decenas de miles de art\u00edculos se publican cada d\u00eda, y muchos de ellos tienen una vida \u00fatil limitada (como las noticias). Esta es la diferencia con las pel\u00edculas, la m\u00fasica y otro contenido que es duradero y costoso de producir.<\/li>\n<li>Transferir conocimientos de un dominio a otro. Si en el sistema de recomendaci\u00f3n hay modelos entrenados para art\u00edculos de texto y agregamos videos, se pueden reutilizar los modelos existentes para que el nuevo tipo de contenido sea mejor clasificado.<\/li>\n<\/ul>\n<p>\nVoy a contar c\u00f3mo abordamos estos desaf\u00edos.<\/p>\n<h2>Selecci\u00f3n de candidatos<\/h2>\n<p>\n<b>\u00bfC\u00f3mo reducir en milisegundos la cantidad de documentos considerados en miles de veces, sin pr\u00e1cticamente perjudicar la calidad del ranking?<\/b><\/p>\n<p>Supongamos que hemos entrenado muchos modelos de ML, generado caracter\u00edsticas a partir de ellos y entrenado otro modelo que clasifica documentos para el usuario. Todo estar\u00eda bien, pero no se puede simplemente calcular todas las caracter\u00edsticas para todos los documentos en tiempo real, si hay millones de estos documentos y las recomendaciones deben generarse en 100-200 ms. La tarea consiste en seleccionar de entre millones un subconjunto que ser\u00e1 clasificado para el usuario. Este paso suele llamarse selecci\u00f3n de candidatos. Se le presentan varios requisitos. Primero, la selecci\u00f3n debe realizarse muy r\u00e1pidamente, para que quede el mayor tiempo posible para el propio ranking. En segundo lugar, al reducir dr\u00e1sticamente la cantidad de documentos para clasificar, debemos conservar al m\u00e1ximo los documentos relevantes para el usuario.<\/p>\n<p>Nuestro principio de selecci\u00f3n de candidatos ha evolucionado, y en este momento hemos llegado a un esquema de m\u00faltiples etapas:<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo trabajamos en la calidad y velocidad de la selecci\u00f3n de recomendaciones\" src=\"\/wp-content\/uploads\/2020\/02\/ed9657ed1febe871f36dc7cf7e585963.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nPrimero, todos los documentos se dividen en grupos, y de cada grupo se eligen los documentos m\u00e1s populares. Los grupos pueden ser sitios web, temas, cl\u00fasteres. Para cada usuario, se seleccionan los grupos m\u00e1s cercanos a su historial, y de ellos se sacan los mejores documentos. Tambi\u00e9n utilizamos un \u00edndice kNN para encontrar los documentos m\u00e1s cercanos al usuario en tiempo real. Existen varios m\u00e9todos para construir el \u00edndice kNN, y el que mejor nos ha funcionado es <noindex><a rel=\"nofollow\" href=\"https:\/\/arxiv.org\/abs\/1603.09320\">HNSW<\/a><\/noindex> (gr\u00e1ficas de mundo peque\u00f1o jer\u00e1rquicas navegables). Este es un modelo jer\u00e1rquico que permite encontrar en milisegundos los N vectores m\u00e1s cercanos al usuario de una base de millones. Previamente, indexamos toda nuestra base de documentos fuera de l\u00ednea. Dado que la b\u00fasqueda en el \u00edndice es bastante r\u00e1pida, con varios embeddings potentes, se pueden crear varios \u00edndices (uno por cada embedding) y acceder a cada uno de ellos en tiempo real.<\/p>\n<p>Tenemos decenas de miles de documentos para cada usuario. A\u00fan as\u00ed, sigue siendo mucho para contabilizar todas las caracter\u00edsticas, as\u00ed que en esta etapa aplicamos un ranking ligero: un modelo simplificado de ranking pesado con menos caracter\u00edsticas. La tarea es predecir qu\u00e9 documentos estar\u00e1n en el top de un modelo pesado. Los documentos con la mayor predicci\u00f3n se utilizar\u00e1n en el modelo pesado, es decir, en la \u00faltima etapa del ranking. Este enfoque permite reducir en decenas de milisegundos la base de documentos considerados para el usuario de millones a miles.<\/p>\n<h2>Paso ALS en tiempo de ejecuci\u00f3n<\/h2>\n<p>\n<b>\u00bfC\u00f3mo tener en cuenta la retroalimentaci\u00f3n del usuario inmediatamente despu\u00e9s de hacer clic?<\/b><\/p>\n<p>Un factor importante en las recomendaciones es el tiempo de respuesta a la retroalimentaci\u00f3n del usuario. Esto es especialmente crucial para los nuevos usuarios: cuando una persona comienza a utilizar el sistema de recomendaciones, recibe un feed no personalizado de documentos diversos por tem\u00e1tica. Tan pronto como hace su primer clic, es necesario tener en cuenta esto de inmediato y ajustarse a sus intereses. Si se calculan todos los factores fuera de l\u00ednea, la r\u00e1pida respuesta del sistema se vuelve imposible debido a la latencia. Por lo tanto, es necesario procesar las acciones del usuario en tiempo real. Para estos fines, utilizamos el paso ALS en tiempo de ejecuci\u00f3n para construir una representaci\u00f3n vectorial del usuario.<\/p>\n<p>Supongamos que tenemos una representaci\u00f3n vectorial para todos los documentos. Por ejemplo, podemos construir incrustaciones fuera de l\u00ednea bas\u00e1ndonos en el texto del art\u00edculo utilizando ELMo, BERT u otros modelos de aprendizaje autom\u00e1tico. \u00bfC\u00f3mo se puede obtener una representaci\u00f3n vectorial de los usuarios en este mismo espacio a partir de sus interacciones en el sistema?<\/p>\n<p><b class=\"spoiler_title\">Principio general de formaci\u00f3n y descomposici\u00f3n de la matriz usuario-documento<\/b>Supongamos que tenemos m usuarios y n documentos. Para algunos usuarios, se conoce su relaci\u00f3n con ciertos documentos. Entonces, esta informaci\u00f3n se puede representar en forma de una matriz m x n: las filas corresponden a los usuarios y las columnas a los documentos. Dado que la mayor\u00eda de los documentos no han sido vistos por el usuario, la mayor parte de las celdas de la matriz permanecer\u00e1n vac\u00edas, mientras que otras estar\u00e1n llenas. Para cada evento (me gusta, no me gusta, clic), hay un valor en la matriz, pero consideremos un modelo simplificado, en el que me gusta corresponde a 1 y no me gusta a -1.<\/p>\n<p>Descomponemos la matriz en dos: P (m x d) y Q (d x n), donde d es la dimensi\u00f3n de la representaci\u00f3n vectorial (generalmente un n\u00famero peque\u00f1o). Entonces, a cada objeto le corresponde un vector de d dimensiones (al usuario le corresponde una fila en la matriz P, al documento le corresponde una columna en la matriz Q). Estos vectores ser\u00e1n los embeddings de los objetos correspondientes. Para predecir si a un usuario le gustar\u00e1 un documento, simplemente podemos multiplicar sus embeddings.<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo trabajamos en la calidad y velocidad de la selecci\u00f3n de recomendaciones\" src=\"\/wp-content\/uploads\/2020\/02\/a0c721bccb3806f2c4a18693a9458a89.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nUna de las posibles formas de descomposici\u00f3n de la matriz es ALS (Alternating Least Squares). Vamos a optimizar la siguiente funci\u00f3n de p\u00e9rdida:<\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo trabajamos en la calidad y velocidad de la selecci\u00f3n de recomendaciones\" src=\"\/wp-content\/uploads\/2020\/02\/aab8a1ae1cdf39de21e7469864c5190a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>\nAqu\u00ed rui es la interacci\u00f3n del usuario u con el documento i, qi es el vector del documento i, pu es el vector del usuario u.<\/p>\n<p>Entonces, el vector \u00f3ptimo desde el punto de vista del error cuadr\u00e1tico medio del usuario (con los vectores de documentos fijos) se encuentra anal\u00edticamente resolviendo la correspondiente regresi\u00f3n lineal.<\/p>\n<p>Esto se llama el \"paso ALS\". Y el propio algoritmo ALS consiste en que alternamos la fijaci\u00f3n de una de las matrices (de usuarios y art\u00edculos) y actualizamos la otra, encontrando la soluci\u00f3n \u00f3ptima.<\/p>\n<p>Afortunadamente, encontrar la representaci\u00f3n vectorial del usuario es una operaci\u00f3n bastante r\u00e1pida, que se puede realizar en tiempo de ejecuci\u00f3n, utilizando instrucciones vectoriales. Este truco permite tener en cuenta de inmediato la retroalimentaci\u00f3n del usuario en el ranking. El mismo embedding se puede usar en el \u00edndice kNN para mejorar la selecci\u00f3n de candidatos.<\/p>\n<h2>Filtrado colaborativo distribuido<\/h2>\n<p>\n<b>\u00bfC\u00f3mo hacer factorizaci\u00f3n matricial distribuida incremental y encontrar r\u00e1pidamente la representaci\u00f3n vectorial de nuevos art\u00edculos?<\/b><\/p>\n<p>El contenido no es la \u00fanica fuente de se\u00f1ales para recomendaciones. Otra fuente importante es la informaci\u00f3n colaborativa. Las buenas se\u00f1ales en el ranking tradicionalmente se pueden obtener de la descomposici\u00f3n de la matriz usuario-documento. Sin embargo, al intentar realizar dicha descomposici\u00f3n, nos encontramos con problemas:<\/p>\n<p>1. Tenemos millones de documentos y decenas de millones de usuarios. La matriz no cabe en una sola m\u00e1quina y la descomposici\u00f3n ser\u00e1 muy larga.<br \/>\n2. La mayor parte del contenido en el sistema tiene una corta vida \u00fatil: los documentos solo son relevantes durante unas pocas horas. Por lo tanto, es necesario construir su representaci\u00f3n vectorial lo m\u00e1s r\u00e1pido posible.<br \/>\n3. Si se realiza la descomposici\u00f3n justo despu\u00e9s de publicar un documento, no habr\u00e1 sido evaluado por un n\u00famero suficiente de usuarios. Por lo tanto, su representaci\u00f3n vectorial probablemente no ser\u00e1 muy buena.<br \/>\n4. Si un usuario ha dado un 'me gusta' o un 'no me gusta', no podremos tener en cuenta esto de inmediato en la descomposici\u00f3n.<\/p>\n<p>Para resolver los problemas mencionados, implementamos una descomposici\u00f3n distribuida de la matriz usuario-documento con actualizaciones incrementales frecuentes. \u00bfC\u00f3mo funciona esto exactamente?<\/p>\n<p>Supongamos que tenemos un cl\u00faster de N m\u00e1quinas (N cuenta en cientos) y queremos realizar una descomposici\u00f3n distribuida de una matriz que no cabe en una sola m\u00e1quina. La pregunta es: \u00bfc\u00f3mo llevar a cabo esta descomposici\u00f3n de manera que, por un lado, cada m\u00e1quina tenga suficientes datos y, por otro, los c\u00e1lculos sean independientes? <\/p>\n<p><img decoding=\"async\" alt=\"C\u00f3mo trabajamos en la calidad y velocidad de la selecci\u00f3n de recomendaciones\" src=\"\/wp-content\/uploads\/2020\/02\/9170b0fecb6efcd41754ec20ee539a15.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nUsaremos el algoritmo de descomposici\u00f3n ALS descrito anteriormente. Veamos c\u00f3mo realizar un paso de ALS de forma distribuida; los pasos restantes ser\u00e1n similares. Supongamos que tenemos fijada la matriz de documentos y queremos construir la matriz de usuarios. Para ello, la dividiremos en N partes por filas, cada parte contendr\u00e1 aproximadamente la misma cantidad de filas. Enviaremos a cada m\u00e1quina las celdas no vac\u00edas de las filas correspondientes, as\u00ed como la matriz de embeddings de documentos (en su totalidad). Dado que su tama\u00f1o no es muy grande y la matriz usuario-documento suele estar muy dispersa, estos datos cabr\u00e1n en una m\u00e1quina convencional.<\/p>\n<p>Este truco se puede repetir durante varias \u00e9pocas hasta que el modelo converja, cambiando de manera alterna la matriz fija. Pero incluso as\u00ed, la descomposici\u00f3n de la matriz puede tardar varias horas. Y esto no resuelve el problema de que se necesitan obtener r\u00e1pidamente las incrustaciones de nuevos documentos y actualizar las incrustaciones de aquellos de los que hab\u00eda poca informaci\u00f3n al construir el modelo. <\/p>\n<p>Nos ayud\u00f3 la implementaci\u00f3n de una actualizaci\u00f3n incremental r\u00e1pida del modelo. Supongamos que tenemos el modelo entrenado actual. Desde que se entren\u00f3, han aparecido nuevos art\u00edculos con los que interactuaron nuestros usuarios, as\u00ed como art\u00edculos que tuvieron poca interacci\u00f3n durante el entrenamiento. Para obtener r\u00e1pidamente la incrustaci\u00f3n de tales art\u00edculos, utilizamos las incrustaciones de los usuarios obtenidas durante el primer gran entrenamiento del modelo y hacemos un paso de ALS para calcular la matriz de documentos mientras la matriz de usuarios se mantiene fija. Esto permite obtener las incrustaciones bastante r\u00e1pido, en unos minutos despu\u00e9s de la publicaci\u00f3n del documento, y actualizar con frecuencia las incrustaciones de documentos recientes.<\/p>\n<p>Para que las recomendaciones tengan en cuenta inmediatamente las acciones del usuario, en tiempo de ejecuci\u00f3n no utilizamos las incrustaciones de usuarios obtenidas fuera de l\u00ednea. En cambio, hacemos un paso de ALS y obtenemos el vector de usuario actualizado.<\/p>\n<h2>Transferencia a otro dominio.<\/h2>\n<p>\n<b>\u00bfC\u00f3mo utilizar el feedback del usuario en art\u00edculos textuales para construir una representaci\u00f3n vectorial de videos?<\/b><\/p>\n<p>Inicialmente, solo recomend\u00e1bamos art\u00edculos textuales, por lo que muchos de nuestros algoritmos est\u00e1n adaptados a este tipo de contenido. Pero al agregar contenido de otro tipo, nos enfrentamos a la necesidad de adaptar los modelos. \u00bfC\u00f3mo abordamos esta tarea en el caso de videos? Una opci\u00f3n es volver a entrenar todos los modelos desde cero. Pero esto lleva tiempo, adem\u00e1s, algunos algoritmos son exigentes en cuanto al volumen de la muestra de entrenamiento, la cual a\u00fan no est\u00e1 disponible en la cantidad necesaria para el contenido de un nuevo tipo en los primeros momentos de su vida en el servicio.<\/p>\n<p>Hemos tomado un camino diferente y reutilizado modelos de texto para videos. En la creaci\u00f3n de representaciones vectoriales de videos, nos ayud\u00f3 el mismo truco con ALS. Tomamos la representaci\u00f3n vectorial de los usuarios basada en art\u00edculos de texto y dimos un paso de ALS, utilizando la informaci\u00f3n sobre las vistas de los videos. De este modo, obtuvimos sin esfuerzo la representaci\u00f3n vectorial de los videos. Y en tiempo de ejecuci\u00f3n, simplemente calculamos la cercan\u00eda entre el vector de usuario, obtenido a partir de art\u00edculos de texto, y el vector del video.<\/p>\n<h2>Conclusi\u00f3n<\/h2>\n<p>\nEl desarrollo del n\u00facleo de un sistema de recomendaci\u00f3n en tiempo real est\u00e1 asociado con numerosas tareas. Es necesario procesar datos r\u00e1pidamente y aplicar m\u00e9todos de ML para un uso efectivo de esos datos; construir sistemas distribuidos complejos, capaces de procesar se\u00f1ales de usuario y nuevas unidades de contenido en el menor tiempo posible; y muchas otras tareas.<\/p>\n<p>En el sistema actual, cuya estructura describ\u00ed, la calidad de las recomendaciones para el usuario aumenta con su actividad y la duraci\u00f3n de su permanencia en el servicio. Pero, por supuesto, aqu\u00ed radica la principal dificultad: al sistema le cuesta entender de inmediato los intereses de una persona que ha interactuado poco con el contenido. Mejorar las recomendaciones para nuevos usuarios es nuestra tarea clave. Continuaremos optimizando los algoritmos para que el contenido relevante para la persona llegue m\u00e1s r\u00e1pido a su feed, mientras que el contenido no relevante no se muestre.<br \/>\n<br \/>Fuente: <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.2 - 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\/es\/blog\/administrirovanie\/kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\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\/es\/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\udd47C\u00f3mo trabajamos en la calidad y velocidad de las recomendaciones | ProHoster","description":"Me llamo Pavel P\u0430\u0440\u0445\u043e\u043c\u0435\u043d\u043a\u043e, soy desarrollador de ML. En este art\u00edculo, me gustar\u00eda hablar sobre la estructura del servicio Yandex.Zen y compartir las mejoras t\u00e9cnicas cuya implementaci\u00f3n ha permitido aumentar la calidad de las recomendaciones.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/kak-my-rabotaem-nad-kachestvom-i-skorostyu-podbora-rekomendaczij","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/71852","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=71852"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/71852\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/71853"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=71852"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=71852"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=71852"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}