Capacitar modelos LTR en Elasticsearch con listas de juicio basadas en datos de comportamiento del usuario

Aprende a usar datos de RBU para crear listas de juicios que automatizen el entrenamiento de tus modelos Learning to Rank (LTR) en Elasticsearch.

Experimenta con Elasticsearch: Sumérgete en nuestros cuadernos de muestra, inicia una prueba gratuita del cloud o prueba Elastic en tu máquina local ahora.

Un gran reto al usar modelos Learning-to-rank es crear una lista de juicios de alta calidad para capacitar el modelo. Tradicionalmente, este proceso implica una evaluación manual de la relevancia de los documentos de consulta para asignar una calificación a cada uno. Es un proceso lento que no escala bien y es difícil de mantener (imagina tener que actualizar una lista con cientos de entradas a mano).

Ahora, ¿y si pudiéramos usar interacciones reales de usuario con nuestra aplicación de búsqueda para crear estos datos de entrenamiento? Emplear datos de RBU nos permite hacer precisamente eso. Crear un sistema automático que pueda capturar y usar nuestras búsquedas, clics y otras interacciones para generar una lista de juicios. Este proceso puede escalar y repetir mucho más fácilmente que una interacción manual y tendería a dar mejores resultados. En este blog, exploraremos cómo podemos consultar datos de RBU almacenados en Elasticsearch para calcular señales significativas que generen un conjunto de datos de entrenamiento para un modelo LTR .

Puedes encontrar el experimento completo aquí.

Por qué los datos de RBU pueden ser útiles para capacitar tu modelo de LTR

Los datos de la RBU ofrecen varios beneficios sobre una anotación manual:

  • Volumen: Dado que los datos de RBU provienen de interacciones reales, podemos recopilar muchos más datos de los que generamos manualmente. Esto suponiendo que tengamos suficiente tráfico para generar estos datos, por supuesto.
  • Intención real del usuario: Tradicionalmente, una lista de juicios manual proviene de una evaluación experta de los datos disponibles. Por otro lado, los datos de RBU reflejan el comportamiento real de los usuarios. Esto significa que podemos generar mejores datos de entrenamiento que mejorarán la precisión de nuestro sistema de búsqueda, porque se basan en cómo los usuarios interactúan y encuentran valor en tu contenido, más que en suposiciones teóricas sobre lo que debería ser relevante.
  • Actualizaciones continuas: Las listas de juicios necesitan actualizar con el tiempo. Si los creamos a partir de datos de la RBU, podemos tener datos actuales que resulten en listas de juicios actualizadas.
  • Rentabilidad: Sin la carga de crear manualmente una lista de juicios, el proceso puede repetir eficientemente cualquier número de veces.
  • Distribución natural de consultas: Los datos de RBU representan consultas reales de usuario, lo que puede impulsar cambios más profundos. Por ejemplo, ¿nuestros usuarios usan lenguaje natural para buscar en nuestro sistema? Si es así, podríamos querer implementar un enfoque de búsqueda semántica o de búsqueda híbrida.

Sin embargo, viene con algunas advertencias:

  • Amplificación de polarización: El contenido popular tiene más probabilidades de recibir clics, simplemente porque tiene más visibilidad. Así que esto podría acabar amplificando los productos populares y posiblemente ahogando opciones mejores.
  • Cobertura incompleta: El contenido nuevo carece de interacciones, por lo que puede ser difícil que los resultados sean altos. Las consultas raras también pueden carecer de suficientes puntos de datos para crear datos de entrenamiento significativos.
  • Variaciones estacionales: Si esperas que el comportamiento del usuario cambie significativamente con el tiempo, los datos históricos pueden no decirte mucho sobre qué es un buen resultado.
  • Ambigüedad de la tarea: Un clic no siempre garantiza que el usuario encontró lo que buscaba.

Cálculo de calificaciones

Calificaciones para el entrenamiento a largo plazo

Para capacitar modelos LTR, necesitamos proporcionar alguna representación numérica de cuán relevante es un documento para una consulta. En nuestra implementación, este número es un puntaje continuo que va de 0,0 a 5,0+, donde puntajes más altos indican mayor relevancia.

Para mostrar cómo funciona este sistema de calificación, consideremos este ejemplo creado manualmente:

BúsquedaContenido del documentoGradoExplicación
"La mejor receta de pizza""Receta auténtica de masa de pizza italiana con fotos paso a paso"4.0Muy relevante, exactamente lo que el usuario busca
"La mejor receta de pizza""Historia de la pizza en Italia"1.0Algo en el tema, trata sobre pizza pero no es una receta
"La mejor receta de pizza""Receta rápida de pizza de 15 minutos para principiantes"3.0Relevante, un buen resultado pero quizá no cumpla con la "mejor" receta.
"La mejor receta de pizza""Guía de mantenimiento de autos"0.0No tiene nada que ver, completamente ajeno a la consulta

Como podemos ver aquí, la calificación es una representación numérica de cuán relevante es un documento para nuestra consulta de ejemplo de "mejor receta de pizza". Con estos puntajes, nuestro modelo de LTR puede aprender qué documentos deben presentar mejor en los resultados.

Cómo calcular las notas es el núcleo de nuestro conjunto de datos de entrenamiento. Existen múltiples enfoques para hacerlo, cada uno con sus propias fortalezas y debilidades. Por ejemplo, podríamos asignar un puntaje binario de 1 para el 0 relevante para no relevante o simplemente contar el número de clics en un documento resultante para cada consulta.

En esta entrada del blog, emplearemos un enfoque diferente, teniendo en cuenta el comportamiento del usuario como nuestra entrada y calculando un número de calificación como resultado. También corregiremos el sesgo que podría surgir por el hecho de que los resultados más altos tienden a ser más clicados, independientemente de la relevancia del documento.

Cálculo de las calificaciones - algoritmo COEC

El algoritmo COEC (Clics over Expected Clics) es una metodología para calcular las calificaciones de juicio a partir de clics de los usuarios.
Como mencionamos antes, los usuarios tienden a hacer clic en resultados de mejor posición incluso si el documento no es el más relevante para la consulta; esto se llama sesgo de posición. La idea central para usar el algoritmo COEC es que no todos los clics son igual de significativos; Un clic en un documento en la posición 10 indica que el documento es mucho más relevante para la consulta que un clic en un documento en la posición 1. Para citar el artículo de investigación sobre el algoritmo COEC (enlazado arriba):

"Es bien sabido que la tasa de clics (CTR) de los resultados de búsqueda o anuncios disminuye significativamente dependiendo de la posición de los resultados."

Puedes leer más sobre el sesgo de posición aquí.

Para abordar esto con el algoritmo COEC, seguimos estos pasos:

1. Establecer líneas base de posición: Calculamos la tasa de clics (CTR) para cada posición de búsqueda del 1 al 10. Esto significa que determinamos qué porcentaje de usuarios suelen hacer clic en la posición 1, posición 2, y así sucesivamente. Este paso captura el sesgo natural de posición de los usuarios.

Calculamos el CTR usando:

CTRp=CpIpCTRp=CpIp

Dónde:

p = Posición. Del 1 al 10
Cp = Total de clics (en cualquier documento) en la posición p en todas las consultas
Ip = Total de impresiones: Cuántas veces apareció cualquier documento en la posición p en todas las consultas

Aquí, esperamos que los puestos más altos consigan más clics.

2. Calcular los clics esperados (EC):

Esta métrica establece cuántos clics "debería" recibir un documento en función de las posiciones en las que apareció y el CTR para esas posiciones. Calculamos la EC usando:

EC(foradocument)=qQdCTRpos(d,q)EC (for a document) = qQdCTRpos(d,q)

Dónde:

Qd = Todas las consultas donde apareció el documento d
pos(d,q)= Posición del documento d en los resultados de la consulta q

3. Contar clics reales: Contamos el total real de clics que un documento recibió en todas las consultas donde apareció, en adelante llamado A(d).

4. Calcular el puntaje del COEC: Esta es la proporción de clics reales (A(d)) sobre los clics esperados (EC(d)):

COEC=A(d)EC(d)COEC = A(d)EC(d)

Esta métrica normaliza para el sesgo de posición como este:

  • Un puntaje de 1,0 significa que el documento funcionó exactamente como se espera dadas las posiciones en las que apareció.
  • Un puntaje superior a 1,0 significa que el documento tuvo un mejor rendimiento de lo esperado al observar sus posiciones. Así que este documento es más relevante para la consulta.
  • Un puntaje inferior a 1,0 significa que el documento tuvo un rendimiento peor de lo esperado al observar sus posiciones. Así que este documento es menos relevante para la consulta.

El resultado final es un número de calificación que captura lo que los usuarios buscan, teniendo en cuenta expectativas basadas en la posición extraídas de interacciones reales con nuestro sistema de búsqueda.

Implementación técnica

Crearemos un script para crear una lista de juicios y capacitar un modelo de LTR.

La entrada para este script es los datos de la RBU indexados en Elastic (consultas y eventos).

La salida es una lista de juicios en un archivo CSV generada a partir de estos documentos de RBU empleando el algoritmo COEC. Esta lista de juicios puede usar con Eland para extraer características relevantes y capacitar un modelo LTR.

Inicio rápido

Para generar una lista de juicios a partir de los datos de muestra de este blog, puedes seguir estos pasos:

1. Clonar el repositorio:

2. Instalar las librerías necesarias

Para este guion, necesitamos las siguientes librerías:

  • Pandas: Para salvar la lista de juicios
  • elasticsearch: Para obtener los datos de RBU de nuestro despliegue de Elastic

También necesitamos Python 3.11

3. Actualizar las variables de entorno para tu despliegue de Elastic en un archivo .env

  • ES_HOST
  • API_KEY

Para agregar las variables de entorno, emplea:

4. Crear el ubi_queries, ubi_events índices y subir los datos de muestra. Ejecuta el archivo setup.py:

5. Ejecutar el script en Python:

Si sigues estos pasos, deberías ver un archivo nuevo llamado judgment_list.csv que se ve así:

Este script calcula las calificaciones aplicando el algoritmo COEC discutido antes de usar la función calculate_relevance_grade() que se muestra a continuación.

Arquitectura de datos

Consultas Ubi

Nuestro índice de consultas de RBU contiene información sobre las consultas ejecutadas en nuestro sistema de búsqueda. Este es un documento de ejemplo:

Aquí podemos ver datos del usuario (client_id), de los resultados de la consulta (query_response_object_ids) y de la propia consulta (marca de tiempo, user_query)

Eventos de Ubi Clic

Nuestro índice de ubi_events contiene datos de cada vez que un usuario hizo clic en un documento en los resultados. Este es un documento de ejemplo:

Script de generación de lista de sentencias

Resumen general de la escritura

Este script automatiza la generación de la lista de juicios empleando datos de RBU de los eventos de Consultas y Clics almacenados en Elasticsearch. Ejecuta estas tareas:

  • Recupera y procesa los datos de la RBU en Elasticsearch.
  • Correlaciona los eventos de RBU con sus consultas.
  • Calcula el CTR para cada posición.
  • Calcula los clics esperados (EC) para cada documento.
  • Cuenta los clics reales de cada documento.
  • Calcula el puntaje del COEC para cada par consulta-documento.
  • Genera una lista de juicios y la escribe en un archivo CSV.

Repasemos cada función:

connect_to_elasticsearch()

Esta función devuelve un objeto cliente de Elasticsearch usando la clave host y API.

fetch_ubi_data()

Esta función es la capa de extracción de datos; se conecta con Elasticsearch para obtener consultas de RBU usando una consulta match_all y filtra los eventos de RBU para obtener solo eventos 'CLICK_THROUGH'.

process_ubi_data()

Esta función se encarga de la generación de la lista de juicios. Comienza a procesar los datos de RBU asociando eventos y consultas de RBU. Luego llama a la función calculate_relevance_grade() para cada par documento-consulta para obtener las entradas de la lista de juicios. Finalmente, devuelve la lista resultante como un dataframe pandas.

calculate_relevance_grade()

Esta es la función que implementa el algoritmo COEC. Calcula el CTR para cada posición, luego compara los clics reales de un par documento-consulta, y finalmente calcula el puntaje real del COEC para cada una.

generate_judgment_statistics()

Genera estadísticas útiles a partir de la lista de valores, como el total de consultas, el total de documentos únicos o la distribución de calificaciones. Esto es puramente informativo y no cambia la lista de sentencias resultante.

Resultados e impacto

Si sigues las instrucciones de la sección de Inicio rápido, deberías ver un archivo CSV resultante que contiene una lista de juicios con 320 entradas (puedes ver una salida de ejemplo en el repositorio). Con estos campos:

  • qid: ID único de la consulta
  • DocID: Identificador único para un documento resultante
  • Grado: la calificación calculada para el par consulta-documento
  • consulta: La consulta de usuario

Veamos los resultados de la consulta "recetas italianas":

QiddocidgradoBúsqueda
Q1-recetas-italianasrecipe_pasta_basics0.0Recetas italianas
Q1-recetas-italianasrecipe_pizza_margherita3.333333Recetas italianas
Q1-recetas-italianasrecipe_risotto_guide10.0Recetas italianas
Q1-recetas-italianasrecipe_french_croissant0.0Recetas italianas
Q1-recetas-italianasrecipe_spanish_paella0.0Recetas italianas
Q1-recetas-italianasrecipe_greek_moussaka1.875Recetas italianas

Podemos ver en los resultados que para la consulta "recetas italianas":

  • La receta de risotto es sin duda el mejor resultado para la consulta, recibiendo 10 veces más clics de lo esperado
  • Pizza Margherita también es un gran resultado.
  • La mousaka griega (sorprendentemente) también es un buen resultado y rinde mejor de lo que su posición en los resultados sugeriría. Esto significa que algunos usuarios que buscaban recetas italianas se interesaron por esta receta. Quizá estos usuarios estén interesados en platos mediterráneos en general. Al final, esto nos dice que podría ser un buen resultado para mostrar bajo los otros dos partidos 'mejores' que mencionamos antes.

Conclusión

Emplear datos de RBU nos permite automatizar el entrenamiento de modelos de LTR, creando listas de juicios de alta calidad de nuestros propios usuarios. Los datos de RBU proporcionan un gran conjunto de datos que refleja cómo se está empleando nuestro sistema de búsqueda. Al emplear el algoritmo de la COEC para generar las calificaciones, tenemos en cuenta el sesgo inherente y, al mismo tiempo, refleja lo que el usuario considera un mejor resultado. El método descrito aquí puede aplicar a casos de uso reales para ofrecer una mejor experiencia de búsqueda que evoluciona con las tendencias reales de uso.

Contenido relacionado

¿Estás listo para crear experiencias de búsqueda de última generación?

No se logra una búsqueda suficientemente avanzada con los esfuerzos de uno. Elasticsearch está impulsado por científicos de datos, operaciones de ML, ingenieros y muchos más que son tan apasionados por la búsqueda como tú. Conectemos y trabajemos juntos para crear la experiencia mágica de búsqueda que te dará los resultados que deseas.

Pruébalo tú mismo