Análisis de ventas de Starbucks — Parte 2 – Hacia la IA

Estás leyendo la publicación: Análisis de ventas de Starbucks — Parte 2 – Hacia la IA

Publicado originalmente en Hacia la IA, la empresa líder mundial en noticias y medios de IA y tecnología. Si está creando un producto o servicio relacionado con la IA, lo invitamos a considerar convertirse en patrocinador de la IA. En Hacia la IA, ayudamos a escalar las empresas emergentes de IA y tecnología. Permítanos ayudarlo a dar rienda suelta a su tecnología a las masas.

Aprendizaje automático

Análisis de ventas de Starbucks — Parte 2

¡Una mirada en profundidad a los datos de ventas de Starbucks!

Si no ha leído la Parte 1 de este blog, aquí está la enlace. En la Parte 2, intentaré abordar las dos preguntas restantes:

  1. ¿Cómo recomendar cupones/ofertas a los clientes actuales según su patrón de gasto?
  2. ¿Cómo recomendar cupones/ofertas a nuevos clientes?

Te mostraré cómo construir un sistema de recomendación para recomendar usuarios ideales para cada oferta.

En otras palabras, mi objetivo es recomendar las mejores ofertas a los usuarios existentes. En este sistema, seleccionamos una oferta existente y recomendamos a los n usuarios principales para esa oferta. Pero esto se puede extender fácilmente a futuras ofertas similares.

Necesitamos recordar algunas cosas antes de hacer eso.

  • Necesitamos identificar a los usuarios que completaron ofertas sin abrirlas. No necesitamos enviar ofertas a estos usuarios, ya que lo más probable es que no les interesen las ofertas.
  • Si un usuario gasta un promedio de más de $20, lo más probable es que no confíe en las ofertas.
  • Dado que tenemos valores de oferta de $5, $7, $10 y $20, podemos proponer una regla general: si un usuario gasta un promedio de $15, podemos recomendarle una oferta de $20 para gastar un poco más.
  • Finalmente, también nos gustaría hacer recomendaciones para los nuevos usuarios. Para eso, podemos entrenar un modelo ML basado en datos demográficos y otras características para predecir la cantidad que gastará el usuario. ¡Y dependiendo del valor, podemos recomendarles una oferta o no! (por ejemplo, si se espera que el usuario gaste más de $20 o muy menos de $5, no enviamos ofertas).
  1. ¿Cómo recomendar cupones/ofertas a los clientes actuales según su patrón de gasto?

Puede haber dos posibilidades para BOGO y ofertas de descuento,

  • Podemos establecer una relación umbral de oferta vista/oferta recibida y diga si el valor es mayor que el porcentaje de umbral, tienen más posibilidades de abrir una oferta.
  • Del mismo modo, podemos establecer una relación umbral de oferta completada/oferta vista y diga si el valor es mayor que el porcentaje de umbral, tienen más posibilidades de completar una oferta.

¡Pero hay una trampa! Podemos tener personas que completaron una oferta sin siquiera abrir la oferta. En ese caso, la proporción de oferta completada/oferta vista será mayor que 1. No es necesario que les enviemos ofertas, ya que lo más probable es que compren productos de todos modos. Entonces, ¡también debemos establecer un límite superior!

Finalmente, podemos usar los datos de la oferta informativa y crear un sistema de recomendación separado de la oferta BOGO y de descuento, ya que no es necesario gastar nada para este tipo de oferta.

¿Cómo construir el sistema de recomendación?

Para datos de ofertas de BOGO y descuento,

  • Usaremos recomendación basada en rango
  • Habrá basado en usuario-usuario Filtración colaborativaen el que recomendaremos los mejores n usuarios para cada oferta.
  • Usaremos ML para hacer un recomendación basada en el contenido para nuevos usuarios. Entrenaremos un modelo basado en datos demográficos para predecir el gasto medio. Dependiendo de ese valor, recomendaremos ofertas.

Para ofertas informativas,

  • Usaremos recomendaciones basadas en rangos. Dado que solo hay dos ofertas en esta categoría, solo pronosticaremos los primeros n usuarios para nuevas ofertas similares.

Echemos un vistazo a los datos de ofertas informativas y los datos de ofertas de BOGO/descuento.

Ahora, de la tabla anterior si miramos el completado/visto y visto/recibido columna de datos en ‘no_info_data’ y mira visto/recibido columna de datos en ‘info_data’ podemos tener una estimación del valor de umbral a utilizar.

  • no_info_data: completado/visto tiene un media de 0.74 y 1.5 es el percentil 90 de los datos visto/recibido tiene un media de 0.77 y 1 es el percentil 90 de los datos
  • info_data: visto/recibido tiene un media de 0.71 y 1 es el percentil 75 de los datos
🔥 Recomendado:  Tutorial completo de Git para principiantes con ejemplos: hacia la IA

Recomendación basada en rango:

En este método, devolveremos n top person para ofertas BOGO/descuento y n top person para ofertas informativas. Serán calificados para futuras ofertas similares.

Para obtener los n principales usuarios sin información primero, filtraremos a los usuarios de acuerdo con ciertos valores de umbral en las columnas ‘visto/recibido’ y ‘completado/visto’. Luego veremos su valor medio de transacción. Si el valor es superior a 20, descartaremos a ese usuario, ya que la mayor oferta es un descuento de $5 en una compra de $20. Así que al usuario no le importan las ofertas.

Para BOGO/oferta de descuento:

get_n_top_info_user(topn = 5) >>> array([’23d67a23296a485781e69c109a10a1cf’,
‘6dba14f698ae4030ab7354cd5cfe7119’,
‘eece6a9a7bdd4ea1b0f812f34fc619d6’,
’05bbe7decb6d43b684221df448979612′,
‘116b28e2983c44039eb8b20292742c94’]dtipo=objeto)

Para oferta informativa:

get_n_top_non_info_user(topn = 5) >>> array([‘d167940f7af04f4681daaa6d1bfd80a1’,
‘a2633655a62e4287a3b651d926a774a6’,
‘4d4216b868fe43ddb9c9f0b77212c0cb’,
‘bb465e90882143b6a49f99d9d810dc3f’,
’17b29dcb0f924294a0d1de2ca59c763f’]dtipo=objeto)

Filtrado colaborativo basado en usuario-usuario para datos BOGO/Descuento

Ahora que hemos creado una recomendación basada en la clasificación para nuevas ofertas, ¿Qué pasa si queremos enviar las ofertas existentes a nuestros usuarios existentes que aún no han recibido algunas ofertas?

Intentaremos encontrar los n usuarios principales para cada oferta existente. Para ello crearemos una matriz user_item.

  • Volveremos a formatear el marco de datos offer_data para que se le dé forma con los usuarios como columnas y las ofertas como filas.
  • Cada usuario solo debe aparecer en cada columna una vez.
  • Cada oferta solo debe aparecer en una fila.
  • Si un usuario ha interactuado con una oferta, coloque un 1 donde se encuentra la columna de usuario para esa fila de oferta. No importa cuántas veces un usuario haya interactuado con la oferta, todas las entradas en las que un usuario haya interactuado con una oferta deben ser un 1.
  • Si un usuario no ha interactuado con una oferta, coloque un cero donde se encuentra la columna de usuario para esa fila de oferta.

Escribiremos una función, que debe tomar a una persona y proporcionar una lista ordenada de los usuarios más similares a ese usuario (desde el más similar hasta el menos similar). El resultado devuelto no debe contener la persona proporcionada, ya que sabemos que cada usuario es similar a ellos. Debido a que los resultados para cada usuario aquí son binarios, (quizás) tenga sentido calcular la similitud como el producto escalar de dos usuarios.

encontrar_ofertas_similares(‘9b98b8c7a33c4b65b9aebfe6a799e6d9’)[:5]
>>> [‘3f207df678b143eea3cee63160fa8bed’,
‘5a8bc65990b245e5a138643cd4eb9837’,
‘ae264e3637204a6fb9bb56bc8210ddfd’,
‘4d5c57ea9a6940dd891ad53e9dbe8da0’,
‘fafdcd668e3743c1bb461111dcafc2a4’]

Finalmente, para hacer una recomendación, usaremos el siguiente código:

oferta_oferta_recs(‘3f207df678b143eea3cee63160fa8bed’, m=10) >>> [‘0020ccbbb6d84e358d3414a3ff76cffd’,
‘005500a7188546ff8a767329a2f7c76a’,
‘0063def0f9c14bc4805322a488839b32’,
‘00857b24b13f4fe0ad17b605f00357f5’,
‘0092a132ead946ceb30d11a1ed513d20’,
’00ad4c2cace94f67a6354ec90d6c6f45′,
’00b5fb9d842d437e83033ad9e36f7148′,
’00b901d68f8f4fd68075184cd0f772d2′,
’00bbce6533f44ddeaf4dd32bcab55441′,
’00bc983061d3471e8c8e74d31b7c8b6f’]

oferta_oferta_recs nos dará n número de usuarios que no han recibido una oferta en particular.

Podemos mejorar la recomendación en combinación con la recomendación basada en clasificaciones.

  • En lugar de elegir arbitrariamente cuándo obtenemos ofertas que tienen la misma cercanía con una oferta determinada, elija las ofertas que tengan la mayor cantidad de interacciones de personas antes de elegir aquellas con menos interacciones de personas.
  • En lugar de elegir arbitrariamente a los usuarios de la oferta en la que el número de personas recomendadas comienza por debajo de m y termina superando m, elija personas con la mayor cantidad de interacciones totales antes de elegir aquellas con menos interacciones totales.

oferta_oferta_recs_improved(‘3f207df678b143eea3cee63160fa8bed’) >>> [‘0020c2b971eb4e9188eac86d93036a77’,
‘00426fe3ffde4c6b9cb9ad6d077a13ea’,
‘004c5799adbf42868b9cff0396190900’,
‘0099bf30e4cb4265875266eb3eb25eab’,
’00b18b535d6d4f779dea4dc9ac451478′,
’00b5fb9d842d437e83033ad9e36f7148′,
’00b901d68f8f4fd68075184cd0f772d2′,
’00bbce6533f44ddeaf4dd32bcab55441′,
’00bc42a62f884b41a13cc595856cf7c3′,
’00c2f812f4604c8893152a5c6572030e’]

Ahora, dado que hemos creado un sistema de recomendación que recomienda n personas para cada oferta, podemos mejorarlo aún más en combinación con una recomendación basada en la clasificación. Utilizamos algunos filtros para obtener las n personas principales para la oferta informativa y la oferta de BOGO/descuento. En get_n_top_non_info_user, get_n_top_info_user funciones, si establecemos topn = ‘max’ obtendremos todos los usuarios posibles.

Finalmente, combine la función offer_offer_recs_improved para obtener n personas principales dentro de la base de datos creada por las funciones mencionadas anteriormente.

make_recs(‘4d5c57ea9a6940dd891ad53e9dbe8da0’) >>> matriz([‘0009655768c64bdeb2e877511632db8f’,
‘0011e0d4e6b944f998e987f904e8c1e5’,
‘003d66b6608740288d6cc97a6903f4f0’,
‘004b041fbfe44859945daa2c7f79ee64’,
‘0056df74b63b4298809f0b375a304cf4’,
‘0082fd87c18f45f2be70dbcbb0fb8aad’,
’00c6035df45840038a72766c6d27a0db’,
‘0009655768c64bdeb2e877511632db8f’,
‘0011e0d4e6b944f998e987f904e8c1e5’,
‘003d66b6608740288d6cc97a6903f4f0’]dtipo=objeto)

hacer_recs función anterior que devuelve los 10 usuarios recomendados principales para el cupón: ‘4d5c57ea9a6940dd891ad53e9dbe8da0’

2. ¿Cómo recomendar cupones/ofertas a nuevos clientes?

Use ML para hacer una recomendación basada en contenido para nuevos usuarios.

Para entrenar un modelo ML usaremos “transaction_data”.

  • Queremos predecir la columna de valor, dada la información demográfica.
  • En estos datos, las columnas ‘persona’, ‘evento’, ‘hora’ y ‘fecha’ no son necesarias.
  • agruparemos los datos por ‘persona’ e intentaremos predecir el valor medio. Dado que una persona puede gastar ocasionalmente más o menos de la cantidad habitual, estamos eliminando esos valores atípicos tomando la mediana.
🔥 Recomendado:  Cómo evaluar la calidad de los chatbots basados ​​en LLM: hacia la IA

Preprocesamiento de datos:

¿Cómo manejé los valores de NaN? Del análisis realizado hasta ahora, sabemos que hay algunas filas sin información demográfica. Estas filas tienen edad = 118, sexo = Desconocido e ingresos = NaN.

Como sabemos, estos valores de NaN están correlacionados sin información. Entonces podemos tratarlos como valores atípicos, simplemente podemos filtrar el valor y calcular el gasto medio y usar ese valor si un nuevo cliente no proporciona ningún dato demográfico.

Un vistazo a los datos:

X_data.head(10) # variable objetivo >>>
género ingreso edad
0 M 72000.0 33
1 O 57000.0 40
2 F 90000.0 59
3 F 60000.0 24
4 F 73000.0 26
5 F 65000.0 19
6 F 74000.0 55
7 M 99000.0 54
8 M 47000.0 56
9 M 91000.0 54

Aquí ‘género’ es una variable categórica con categorías F (femenino), M (masculino), O (otro). ‘ingresos’ y ‘edad’ son datos numéricos.

De las gráficas de las columnas numéricas, vemos que las columnas ‘edad’ e ‘ingresos’ están sesgadas a la derecha. Para hacerlo gaussiano, haremos una transformación logarítmica seguida de la estandarización de los datos para que tengan un valor medio de 0.

Para la columna categórica, ‘género’, usaremos una codificación one-hot.

Usé la tubería scikit-learn para realizar el preprocesamiento de datos.

Como solo teníamos tres funciones, usé PolynomialFeatures de scikit-learn para agregar más funciones. Se pueden encontrar detalles sobre cómo funciona esto aquí.

Para la variable objetivo, recorté el valor superior a 25. Ya que, si una persona gasta más de $25, no le enviaremos ninguna oferta.

Entrenar un modelo de ML

Dado que este es un problema de regresión, podemos usar varios métodos de regresión para encontrar el mejor modelo.

Solía:

Después de usar estos 4 métodos, XGBoost me dio un mejor resultado, así que decidí usarlo como mi modelo final.

Matrices:

No podemos calcular la precisión de un modelo de regresión. Solo podemos medir el rendimiento en términos del error de predicción. En nuestro caso, no queremos predecir la cantidad exacta en dólares, pero queremos ver qué tan cerca están nuestras predicciones del valor real. Usaré 3 matrices para evaluar mi modelo.

  • R cuadrado: una medida de cuánto se ajusta la variable dependiente al modelo.
  • Raíz del error cuadrático medio (RMSE): la suma del error cuadrático ayuda a elegir el mejor modelo de regresión. MSE da mayor penalización a gran desviación.
  • Error absoluto medio (MAE): similar a MSE/RMSE, pero en lugar de tomar el error cuadrático, calculó el error absoluto. MAE trata todos los errores de la misma manera.

La puntuación R cuadrada de XGBoost es del 72 % al 70 %, lo que significa que el modelo es bastante robusto.

Ajuste de hiperparámetros:

Como paso final, debemos ajustar los hiperparámetros para obtener los mejores valores de parámetros.

Usé RandomizedSearchCV de scikit-learn para encontrar los mejores valores de parámetros.

Los hiperparámetros ajustados para este problema son:

Evaluación y validación del modelo:

Los mejores parámetros son:

random_cv.best_estimator_ >>> XGBRegressor(base_score=0.5, booster=’gbtree’, colsample_bylevel=1,
colsample_bynode=1, colsample_bytree=1, gamma=0, gpu_id=-1,
tipo_importancia=’ganancia’, restricciones_interacción=”,
tasa_de_aprendizaje=0,2, paso_delta_máximo=0, profundidad_máxima=3,
min_child_weight=3, perdido=nan, monotone_constraints='()’,
n_estimadores=100, n_trabajos=8, num_parallel_tree=1, estado_aleatorio=0,
reg_alpha=0, reg_lambda=1, scale_pos_weight=1, submuestra=1,
tree_method=’exacta’, validar_parámetros=1, verbosidad=Ninguna)

Para evaluar si el modelo XGBoost es estable sobre todos los datos o no, podemos usar K-FOLD CROSS VALIDATION.

Como vemos, el modelo es bastante estable en todo el conjunto de datos con una desviación estándar de 0,1.

Finalmente, podemos establecer una regla para enviar cupones a nuevos usuarios.

  • Se espera que una persona sin datos demográficos gaste $1,71, por lo que podemos enviar un Oferta informativa o ¡Sin oferta!
  • Si se espera que un usuario gaste < $ 3 o > $ 22, envíe un Oferta informativa o ¡Sin oferta!
  • Si se espera que un usuario gaste ≥ $3 y <$5, envíe el Ofertas de cupones de $5.
  • Si se espera que un usuario gaste ≥ $5 y < $7, envíe el Oferta de cupón de $7.
  • Si se espera que un usuario gaste ≥ $7 y < $10, envíe el Cupones de $10.
  • Por último, si se espera que un usuario gaste ≥$10 y <$20, envíe el Cupón de $20.
🔥 Recomendado:  Las mejores fuentes para blogueros: cómo elegir la tipografía adecuada para tu blog

Ejemplo:

person_demo = {
‘género’ : [‘M’,’F’,’O’],
‘ingreso’ : [60000.0,72000.0,80000.0],
‘edad’ : [36,26,30]
} predecir_gasto(persona_demostración, modelo_final) >>> matriz([ 3.78, 10.66, 22.26]tipod=float32)

  • Persona 1: género = Hombre, ingreso = 60000.00, edad = 36. Se espera que gaste $3.78, así que envíe un Cupón de $5.
  • Persona 2: sexo = Mujer, ingresos = 72000,00, edad = 26. Se espera que gaste $10,66, así que envíe un Cupón de $20.
  • Persona 3: género = Otro, ingreso = 80000.00, edad = 30. Se espera que gaste $22.26, así que envíe un ¡Cupón informativo/ningún cupón!

Resumen

En resumen,

  • creé un recomendación basada en rango sistema para filtrar a los principales usuarios potenciales que tienen una alta probabilidad de ver y canjear una oferta existente o futura.
  • usé un Filtrado colaborativo basado en usuario-usuario método para averiguar los principales usuarios potenciales específicos de una oferta.
  • Finalmente, usé el Aprendizaje automático acercarse para recomendar ofertas a nuevos usuarios.

Justificación del Proyecto

Traté de responder 3 preguntas a través de este proyecto.

Para la pregunta 1. ¿Cuáles son los tipos populares de ofertas?

De las gráficas en la parte 1, la posible respuesta es,

  • Hice una trama de un porcentaje de ofertas recibidas vs tipo de oferta para mostrar, aunque las ofertas BOGO se vieron más, las ofertas de descuento fueron más populares en términos de finalización.
  • Creé una trama de la distribución de ofertas entre géneros Para concluir, dada una oferta, ¡la posibilidad de canjear la oferta es mayor entre las mujeres y otros géneros!
  • Finalmente, hice parcelas de género, edad, ingreso vs gasto promedio y descubrió que las mujeres tienden a gastar más, y el gasto aumenta con la edad y los ingresos.

Para la pregunta 2. ¿Cómo recomendar cupones/ofertas a los clientes actuales según su patrón de gasto?

  • usé un recomendación basada en rango sistema para filtrar a los principales usuarios potenciales que tienen una alta probabilidad de ver y canjear una oferta existente o futura.
  • creé un Filtrado colaborativo basado en usuario-usuario método para averiguar los principales usuarios potenciales específicos de una oferta.

Para la pregunta 3. ¿Cómo recomendar cupones/ofertas a nuevos clientes?

  • Usé varias matrices (MAE/RMSE) para verificar la robustez del modelo. Encontré que el RMSE es ~ 4.5. Aunque no es suficiente diferenciar entre una oferta de $5 y una oferta de $7, o entre una oferta de $7 y una oferta de $10, pero solo hay una oferta de $7, dos ofertas de $5 y cuatro ofertas de $10. Por lo tanto, es más importante separar una oferta de $5 de una oferta de $10. Y para eso, la puntuación RMSE es suficiente.
  • Este método es útil para recomendar ofertas a nuevos usuarios.

Trabajo futuro

En el futuro,

  • Estoy planeando implementar el modelo y crear un tablero de datos en la web.
  • Intentaré mejorar el rendimiento del modelo realizando más ingeniería de funciones. Técnica de sobremuestreo de minorías sintéticas (SMOT) para aumentar los datos de entrenamiento.
  • Utilice los modelos CatBoost y LightGBM para probar y comprobar los resultados.
  • Utilice el apilamiento, ya que se utilizan varios modelos de aprendizaje supervisado.

El repositorio de GitHub de este proyecto se puede encontrar aquí.

Referencias:


Análisis de ventas de Starbucks: Parte 2 se publicó originalmente en Hacia la IA en Medium, donde las personas continúan la conversación destacando y respondiendo a esta historia.

Publicado a través de Hacia la IA