En 2018, nuestro equipo tradicionalmente participó en el Desafío RecSys . Este es un concurso anual sobre sistemas de recomendación realizado como parte de la conferencia RecSys. No es tan grande como las competiciones en Kaggle, pero se considera una de las competiciones más prestigiosas en sistemas de recomendación. Esta vez la tarea era musical: era necesario construir un sistema para continuar automáticamente las listas de reproducción. En esta publicación, hablo en detalle sobre nuestra decisión. Te invito a gato.

Sobre el concurso
Este año, los datos para la competencia fueron proporcionados por Spotify , un servicio de transmisión de música (que, lamentablemente, no está oficialmente disponible en la Federación de Rusia). Las recomendaciones son una de las partes más importantes del producto en Spotify y permiten a los usuarios encontrar nueva música, crear listas de reproducción o escuchar radio según sus preferencias.
Los participantes del concurso debían crear un algoritmo de continuación de lista de reproducción automática. El conjunto de datos Million Playlist, cuyo nombre habla por sí mismo, se presentó como datos de entrenamiento. Además de la información sobre qué pistas están contenidas en la lista de reproducción, también se proporcionó metainformación sobre las pistas: artista, título, duración, nombre del álbum.
Puedes leer más sobre el concurso aquí .

Desafío de la competencia
La tarea de la competencia es clásica para los sistemas de recomendación: generar recomendaciones top K para el usuario, conociendo el historial de sus acciones, pero en lugar del elemento de usuario habitual, aquí aparece la lista de reproducción. En términos más formales, partes de las listas de reproducción (en lo sucesivo denominadas semilla) se dieron en los datos de la prueba, y había varias formas diferentes de formarlas. Para K = (5, 10, 25, 100) hubo semillas con los primeros K tracks y K tracks elegidos al azar. También hubo semillas con la primera pista y solo con el nombre de la lista de reproducción. Las pistas que no se incluyeron en los holdouts tuvieron que predecirse. Para cada lista de reproducción, se requerían exactamente 500 predicciones.
Métricas
Una de las características de la competencia fue que la métrica no era una, como es habitual en la mayoría de las competiciones, sino varias. A continuación les contaré sobre cada uno de ellos.
Precisión R
Esta métrica muestra qué proporción de pistas relevantes adivinamos.
NDCG
Esta es una métrica de calidad de clasificación clásica, puede leer sobre ella, por ejemplo, aquí
Clics
Spotify tiene un mecanismo para continuar con la lista de reproducción (puede verla en la captura de pantalla al comienzo del artículo): ofrece varias pistas que pueden usarse para expandir la lista de reproducción, y si no aparece ninguna, puede hacer clic en el botón Actualizar y obtener el siguiente lote de recomendaciones. El número de tales actualizaciones a la primera opción es la métrica Clics. Más simplemente, la posición de la primera recomendación relevante (en este caso, dividida por 10).
A continuación, a los equipos se les asigna un rango para cada una de las métricas. Luego, los rangos se agregan de acuerdo con el esquema de la Estrategia Electoral del Conde Borda. Si Es el número de participantes, entonces un equipo con un rango de 1 obtiene puntos, un equipo con un rango de 2 recibe puntos y así sucesivamente.

Solución
Esquema de validación
Para reproducir divisiones de tren / prueba, dividimos el conjunto de datos original en tres partes: la primera parte contenía 980k listas de reproducción, la segunda y la tercera parte contenían 10k cada una. Luego, cada lista de reproducción de la segunda y la tercera parte se dividió en partes semilla y reserva, y los tamaños de las partes semilla se seleccionaron de la misma manera que en el conjunto de prueba provisto, y las pistas restantes cayeron en espera.
Selección de candidatos
Los sistemas recomendados a menudo usan un enfoque de dos etapas: primero, usando un modelo más simple (por ejemplo, factorización matricial ), los candidatos se seleccionan de todo el conjunto de elementos, y luego los candidatos se clasifican por un modelo más complejo (por ejemplo, aumento de gradiente ) en un conjunto más amplio de atributos. La selección de candidatos es necesaria, en primer lugar, debido a los recursos informáticos limitados: si usamos todo el conjunto de pistas disponibles como candidatos, entonces para una lista de reproducción tendríamos que conducir alrededor de un millón de objetos a través del modelo.
Selección de candidatos mediante factorización matricial.
La factorización matricial es uno de los enfoques más comunes para construir sistemas de recomendación. La idea principal de este método es presentar una matriz escasa de interacciones entre usuarios y elementos en forma de un producto de dos matrices (U e I) de menor dimensión. Entonces podemos obtener recomendaciones para el usuario multiplicando el vector de la matriz U por la matriz I.
Para la factorización matricial, utilizamos la biblioteca LightFM con pérdida WARP ( Parámetros ponderados de rango aproximado) . También teníamos dos modelos diferentes: uno para las listas de reproducción que tienen una semilla no vacía y el otro para las listas de reproducción que solo tienen un nombre (inicio en frío).
Pérdida de WARP
Esta función de pérdida es mejor que otras en las tareas de clasificación. Funciona con triples (user, positive_item, negative_item) y tiene una característica muy importante: la selección de ejemplos negativos no ocurre por casualidad, pero de tal manera que los ejemplos negativos seleccionados "rompen" la clasificación actual del modelo, es decir fueron más altos que un ejemplo positivo.
Por lo tanto, el procedimiento para entrenar a un modelo con pérdida de WARP será aproximadamente el siguiente:
- Para una pareja elegiremos un ejemplo negativo aleatorio entre todos los demás elementos (es importante comprender que esto solo es necesario si la probabilidad de elegir un ejemplo negativo, que en realidad será positivo, es bastante pequeña). Calcular la predicción de pareja y y si no hubo desorden (es decir, el modelo predijo una puntuación más alta para un ejemplo positivo), entonces continuamos tomando muestras de ejemplos negativos hasta que ocurra la violación.
- Si recibimos una violación en el primer intento, entonces podemos dar un gran paso de gradiente, ya que esto significa que en este momento el modelo a menudo pone ejemplos negativos por encima de los positivos y es necesario actualizar sus pesos. Si tuvimos que buscar un ejemplo negativo adecuado durante mucho tiempo, entonces damos un pequeño paso: el modelo ya está bien entrenado.
Se puede encontrar una descripción más formal de la pérdida de WARP en el artículo original o en esta publicación .
Lightfm
La primera versión del modelo utilizaba solo información colaborativa: la presencia de la pista track_id en la lista de reproducción playlist_id, presentada como una matriz dispersa binaria. Varias matrices correspondían a una lista de reproducción, una columna a una pista.
Funciones de texto LightFM +
Este modelo utiliza incrustaciones de palabras del nombre de la lista de reproducción en lugar de playlist_id. La inclusión de una lista de reproducción es la suma de las incrustaciones de sus palabras.
, ,
donde - Estas son las palabras del nombre de la lista de reproducción.
Por lo tanto, resolvemos el problema de un arranque en frío: podemos ofrecer mejores recomendaciones para las listas de reproducción que solo tienen un nombre.
Los organizadores del concurso también proporcionaron información sobre cuántas pistas había en la parte oculta de la lista de reproducción. Si la parte oculta fuera pistas entonces elegimos candidatos La naturaleza de estos números es una simple heurística, inventada a partir de las siguientes consideraciones: queremos tener suficientes candidatos para pequeñas listas de reproducción (por lo tanto ), y también queremos que el conjunto de datos final tenga aproximadamente 10 millones de filas por razones de rendimiento en términos de tiempo y memoria (por lo tanto, k 15, no k 50, por ejemplo).
Ranking
Después de haber seleccionado candidatos, podemos considerar la tarea de construir recomendaciones como un problema de clasificación binaria: para cada una de las pistas en los candidatos seleccionados, aprendemos a predecir si esta pista realmente estaba en la lista de reproducción.
En nuestro conjunto de datos de entrenamiento, cada fila contendrá signos para el par (lista de reproducción, pista), y la etiqueta será 1 si hay una pista en la lista de reproducción y 0 si no.
Como signos, se utilizaron varios grupos diferentes.
Características basadas en el modelo LightFM
Como se describió anteriormente, en el modelo LightFM obtuvimos vectores y escalares .
Como signos usaremos , < y el rango de la pista t entre todos los candidatos para la lista de reproducción p (el rango se calculó mediante la fórmula ). Estos cuatro atributos fueron tomados de los modelos LightFM y LightFM Text.
Signos basados en la coincidencia de pistas
Dejar Es la cantidad de listas de reproducción que contienen pistas y juntos también - número de listas de reproducción que contienen la pista . Estos valores se calcularon en un conjunto fijo de listas de reproducción que consta de todas las partes semilla.
Deja que la lista de reproducción consiste en pistas . Para la pista calcular los valores y para ellos calcularemos varias estadísticas: mínimo, máximo, promedio y mediana. Luego calculamos las mismas estadísticas para las cantidades . En el primer caso, solo observamos con qué frecuencia se reunió la pista objetivo junto con las pistas de la lista de reproducción, y en el segundo caso, también normalizamos esto a la frecuencia de aparición de otras pistas. La normalización ayuda al modelo a no volver a entrenar para pistas populares y extraer con mayor precisión información sobre cuánto son realmente similares las pistas.
Otros signos
Todas las características se calculan para el par. .
- El número de artistas únicos en la lista de reproducción. .
- Número de álbumes únicos en la lista de reproducción .
- Número y porcentaje de pistas en una lista de reproducción con el mismo álbum / artista que la canción .
- ¿Cuántas veces se encontró la pista? en todas las listas de reproducción.
- ¿Cuántas veces rastreó el artista / álbum? en todas las listas de reproducción.
- El número de pistas en las partes semilla y reservada de la lista de reproducción .
Modelo de recomendación
Para construir las recomendaciones finales, usamos XGBoost . El modelo fue entrenado en , se seleccionaron hiperparámetros en por ROC AUC métrica. Se eligió esta métrica porque es clásica para problemas de clasificación. No todas las características son igualmente útiles, por lo que será interesante observar los valores de importancia de las características del modelo.
Característica | Ganar |
co-ocurrencia media normalizada
| 1049 |
modelo, producto de punto | 101 |
recuento de listas de reproducción | 100 |
co-ocurrencia normalizada max | 74 |
rastrea el recuento de reservas | 63 |
mediana de concurrencia | 33 |
recuento de pistas | 29 |
modelo, producto de punto | 28 |
modelo, rango de puntaje | 26 |
co-ocurrencia media | 20 |
Se puede ver que el signo de co-ocurrencia media normalizada se destaca significativamente de los demás. Esto significa que la información sobre la coincidencia de pistas da una señal muy fuerte, que, en general, no es sorprendente. Además, esta característica podría usarse como una selección de candidatos en lugar del modelo LightFM, y esto no dio peores resultados.
Otros
Hierro
Todos los modelos fueron entrenados en el servidor con Intel Xeon E5-2679 v3 (28 núcleos, 56 hilos), 256 Gb de RAM. Aprender la tubería final tomó aproximadamente 100 horas y consumió 200 Gb de memoria en el pico, y una parte significativa (aproximadamente el 90%) del tiempo se dedicó a entrenar el modelo de selección de candidatos. El modelo de clasificación se entrenó con bastante rapidez, aproximadamente dos horas (sin contar la selección de hiperparámetros).
Falla
No sin fallas.
En el penúltimo día de la competencia, decidimos organizar un mini-hackathon, al final reunimos todo lo que teníamos: selección de candidatos basada en la concurrencia, un montón de nuevas características para impulsar, y parece que podría ser así.
Pero la velocidad de validación realmente creció un poco, así que cegamos el envío y lo enviamos, planeando que nos quedaría un día para arreglar las jambas. Después de enviar el envío, se enteraron de que no era el penúltimo día, sino el último. Y la velocidad de la nueva presentación fue mucho más baja que nuestra mejor presentación. No hubo tiempo para averiguar por qué sucedió esto, por lo que saboteamos la mejor presentación, que permaneció en el tercer lugar.
También en el último día, aprendimos que hay dos tipos diferentes de semillas: con las primeras pistas K y las aleatorias, y en la validación siempre elegimos las aleatorias, pero es poco probable que esto afecte en gran medida a la tabla de clasificación.
Un día de la competencia, el valor de la métrica R-Precision para todos los equipos en la tabla de clasificación aumentó considerablemente. No le dimos ninguna importancia a esto, pero al final de la competencia descubrimos que los organizadores agregaron un componente más a la métrica: una coincidencia del artista de la pista. Esto también podría agregarse a la métrica de validación y, posiblemente, a una velocidad mejorada.
Código
Nuestra solución está diseñada en forma de computadoras portátiles Jupyter y puede reproducirse (!) Al iniciarlas secuencialmente. Solo para esto necesita una máquina con 200Gb + RAM y un par de días de tiempo.
Decisiones de otros participantes.
El equipo que ganó el primer lugar también participa regularmente en el Desafío RecSys y ocupa lugares altos. Su solución es similar a la nuestra, pero implementada en Java .
Los segundos finalistas tienen un enfoque bastante interesante: utilizaron Denoising Autoencoder para restaurar las listas de reproducción de sus partes .
Conclusión
Si observa la tabla de clasificación final, nuestro equipo ocupa el sexto y cuarto lugar en las métricas de clasificación (R-Precision y NDCG), y primero en la métrica Clics. Como sucedio Y sucedió así debido a una buena solución al problema de arranque en frío utilizando el modelo LightFM Text. La métrica de clics impone multas más severas cuando no adivinamos una sola pista de una lista de reproducción. El uso del modelo LightFM Text mejoró la métrica promedio de clics de 2.2 a 1.78.
El enfoque con la selección de candidatos utilizando un modelo más simple y una clasificación adicional con un modelo más complejo sigue siendo uno de los más exitosos en los problemas clásicos de la construcción de recomendaciones top-K. Pero al mismo tiempo, es muy importante construir correctamente el esquema de validación para poder comparar tanto los modelos de selección de candidatos como los modelos de clasificación.
Además, este esquema es bastante adecuado para los sistemas de producción: puede comenzar a construir su sistema de recomendaciones sobre la base de la factorización matricial y luego mejorarlo agregando una segunda etapa.
Si tiene alguna pregunta sobre el artículo, no dude en hacerla en los comentarios :)
PD: Escribimos un artículo más detallado sobre esto para el taller en la conferencia RecSys. El acceso a sus materiales en el sitio es limitado, por lo que si está interesado en conocer un poco más sobre nuestra solución, escríbame en PM.