En el sector de Retail es muy importante poder entender y prever la evolución temporal de variables como, ventas, stock, visitas…

En este artículo vamos a ver cómo podemos describir este tipo de variables como series temporales y, por medio de librerías como Prophet, poder predecir y entender su evolución temporal en base a tendencias y comportamientos estacionales.

Introducción

En estadística se denomina serie temporal a una secuencia de datos ordenada de manera cronológica, donde cada dato lleva asociado un registro de tiempo (año, día, hora, minuto...) del momento en el que se produjo. Esto permite usar las series temporales para representar y analizar variables que por su naturaleza van evolucionando en el tiempo.

Los casos de uso donde se utiliza este tipo de representación de datos van desde monitorización de dispositivos IoT, evolución temporal de variables demográficas, gestión de cadenas de producción… pero un caso de uso especialmente interesante es el e-commerce y el sector de retail.

¿Cómo se pueden aplicar las series temporales para la predicción de ventas en un e-commerce así como para la caracterización del comportamiento de usuarios? Os lo contamos a continuación.

Caso de uso: Retail Sales

Además de la ventaja de la digitalización y automatización de los e-commerce frente al comercio tradicional, otra importante ventaja diferencial es también el aumento de la cantidad de información que se recoge de los clientes durante el proceso de compra. Esto permite obtener información, no solo de las ventas, sino también de su navegación por la página web y registrar la frecuencia de visitas y compras a lo largo del tiempo.

Esta información nos permite no solo poder entender la dependencia de las ventas de un negocio en función de factores temporales, como pueden ser los días de la semana, la estación del año, el período vacacional, sino que también permite predecir cómo va a evolucionar a futuro, pudiendo así prever el stock necesario para suplir las necesidades en períodos de picos de venta.

En base a esto podemos responder a preguntas como por ejemplo ¿Estoy creciendo realmente o solo es un crecimiento estacional?¿Qué impacto tienen las vacaciones en mi negocio?¿Cuando compran más mis clientes?...

Predicción con series temporales

Tradicionalmente, la predicción de datos con series temporales se diferencia de otros modelos predictivos en que sigue un procedimiento autorregresivo (ARIMA). Este tipo de modelos tratan de descomponer la serie temporal en componentes (tendencia, estacionalidad...) y predecir su evolución futura en función de relaciones lineales con los datos pasados. El problema de estos modelos es que no son capaces de predecir bien cuando el carácter de los datos no se ajusta a un comportamiento lineal.

Otros modelos como las Redes Neuronales Recurrentes (RNN) tratan, por medio de fuerza bruta, optimizar gran cantidad de parámetros para aprender patrones complejos y realizar predicciones de gran precisión. No obstante, generalmente no se aprovechan de la naturaleza de los propios datos para descomponer la serie temporal en cada uno de los factores de los que depende (tendencia, estacionalidad mensual, estacionalidad semanal, días de fiesta…).

Descomponer la serie temporal en diferentes componentes es de especial interés, no solo porque permite hacer buenas predicciones, sino porque además nos permite entender mejor el comportamiento de las ventas y extraer conclusiones viendo la evolución de cada uno de sus componentes.

Los modelos predictivos tienen diferentes formas de agregar la información de la tendencia estacionalidad y las fiestas, y según cómo lo hagan existen dos tipos de modelos:

Los dos tipos de modelos sirven para predecir a futuro cualquier tipo de serie temporal. No obstante, según la naturaleza que tenga nuestro negocio, nos puede interesar más uno u otro. Por ejemplo, en un negocio con un carácter más estacional, nos interesaría más un modelo aditivo para separar de manera clara las ventas que vienen de los diferentes periodos de vacaciones. Por otro lado, en un tipo de negocio con una tendencia bastante fuerte, seguramente la contribución de la estacionalidad afecte de manera porcentual a la tendencia y, por tanto, nos interesaría más un modelo multiplicativo.

¿Qué es Prophet?

Prophet es una librería desarrollada por Facebook con su propio modelo de predicción de series temporales. Este modelo de predicción de series temporales permite obtener la componentes de tendencia, múltiples estacionalidades (diaria, semanal, mensual, customizada…) y la contribución de los festivos tanto por medio de un modelo aditivo como multiplicativo.

Al igual que modelos como ARIMA descompone la serie temporal en diferentes contribuciones, obteniendo una componente estacional. No obstante, Prophet es especialmente bueno obteniendo la componente estacional. Para ello hace una descomposición de la contribución no explicable por la tendencia por medio de series de Fourier de diferentes órdenes. Esto permite a Prophet responder a preguntas más complejas que: “¿Qué día de la semana hay más ventas?” o “¿Qué mes del año?”; como por ejemplo, “el primer lunes de cada mes hay un incremento de ventas”.

Además, otro factor diferencial de Prophet es que la información de parametrización que necesita, así como su interfaz de uso, está directamente relacionado con variables propias del conocimiento de negocio. Además, estas variables de parametrización no son necesarias, permiten añadir información al modelo en el caso de que se conozcan, pero si no es así, Prophet es capaz de inferirlas de manera automática.

Para configurar estas variables de parametrización, no es necesario un conocimiento matemático del modelo internamente, sino que se puede responder por medio de información como: días con sucesos anómalos (por ejemplo, promociones), días potenciales de cambio de tendencia (por ejemplo, un rediseño de la web), frecuencias de estacionalidad conocidas...

Demo

Como ejemplo vamos a ver cómo podría utilizarse sobre un dataset real de ventas diarias el sector de retail. Para ello vamos a usar el dataset de online retail del repositorio de UCI. Este dataset contiene información de ventas de una empresa de retail online localizada en UK. El negocio consiste en la venta de regalos, siendo sus clientes principalmente mayoristas.

import pandas as pd
from prophet import Prophet

df=pd.read_excel('https://archive.ics.uci.edu/ml/machine-learning-databases/00352/Online%20Retail.xlsx')
df

Las series temporales permiten analizar la evolución temporal de diferentes indicadores importantes para el sector de retail (stock, número de visitas, comportamiento de cliente…). Para este ejemplo vamos a centrarnos en analizar la evolución temporal de la facturación en United Kingdom. Para ello hacemos el siguiente preprocesamiento.

df['y'] = df['Quantity']*df['UnitPrice']
df['ds'] = pd.to_datetime(pd.to_datetime(df['InvoiceDate']).dt.date)
ts = df[['ds','y']].loc[df.Country=='United Kingdom']
ts = ts.groupby('ds', as_index=False)['y'].sum()
ts = ts[ts.ds.dt.year>2010]
ts

Vemos que no están todos los días del año, pero no importa, Prophet sabe gestionarlo. Ahora vamos a ajustar el algoritmo con estos datos para hacer una predicción de cómo va a ser el año siguiente.

model = Prophet(
   yearly_seasonality=True,
   weekly_seasonality=True,
   seasonality_mode=['additive','multiplicative'][1]
   ).add_seasonality('quarterly',
                     period = 91.5,
                     fourier_order = 8,
                     mode = 'multiplicative'
   ).add_country_holidays(country_name='UK'
   ).fit(ts)

future = model.make_future_dataframe(periods=365)
forecast = model.predict(future)
fig1 = model.plot(forecast)
Predecir las ventas 1

Hemos elegido una estacionalidad multiplicativa ya que observando los datos originales, parece que la varianza de los datos es mayor según va creciendo la tendencia. Esto nos da que pensar que la estacionalidad tiene un efecto porcentual sobre la serie temporal y no aditivo. Además hemos tenido en cuenta la estacionalidad semanal y las vacaciones de UK.

Además podemos observar la contribución de cada una de las componentes de la serie temporal.

fig2 = model.plot_components(forecast)
Predecir las ventas 2
Predecir las ventas 3
Predecir las ventas 4
Predecir las ventas 5

Como vemos vemos en las gráficas de las componentes, a pesar del descenso de ventas en los últimos registros del dataset (esto se debe a la contribución estacional) la tendencia es positiva. Parece que las ventas están más o menos uniformemente distribuídas, salvo los sábados que hay un descenso importante. Además parece que los meses de verano son en los que menos ventas se hacen.

Productificación

El hecho de que este tipo de modelos presuponen que la serie temporal está compuesta por una tendencia, estacionalidad y festividades ajustables, en lugar de aprender patrones complejos por medio de fuerza bruta sin ninguna asunción, hace que sean bastante rápidos de entrenar.

En cuestión de segundos, se puede ajustar una serie temporal diaria de un par de años y hacer una predicción para los valores de la serie temporal de los próximos meses. El hecho de que tengan un entrenamiento e inferencia tan ligeros permite que se puedan ejecutar todos por medio de funciones Lambda.

Para poder crear una función lambda debemos construir una imagen Docker que contenga la aplicación de inferencia y lo sirva como un servicio web.

FROM python:3.8

RUN pip install flask
RUN pip install pandas
RUN pip install prophet

COPY main.py ./
CMD python main.py

La aplicación web puede tener un formato similar a este. Este script crea un servicio web con un endpoint post que recibe los datos y realiza una inferencia.

import json
import logging
import pandas as pd
from prophet import Prophet
from flask import Flask, request

log = logging.getLogger()

app = Flask(__name__)

@app.route("/", methods=["POST"])
def index():
   payload = request.get_json()
   df = pd.DataFrame(json.loads(payload)["data"])

   model = Prophet().fit(df)
   future = model.make_future_dataframe(periods=365,
                                        include_history=False)
   forecast = model.predict(future)[[‘ds’,’yhat’]]

   return json.dumps(forecast.to_dict((orient='list')))

if __name__ == "__main__":
   app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

Con esto podríamos construir una función Lambda para la predicción online de la serie temporal. Esto permite que cada predicción use la última versión de los datos y que además, al estar en una función Lambda, pueda ser llamada desde múltiples aplicaciones o configurando triggers.

Conclusiones

En este post hemos visto cómo las series temporales pueden servir para modelar datos que evolucionan en el tiempo. Esto puede ser bastante útil en sectores como el comercio online, en el que la planificación de stock según las ventas que se vayan a producir es bastante importante.

De los algoritmos que hay de predicción de series temporales, Prophet es especialmente bueno modelando diferentes componentes estacionales de manera simultánea, y estacionalidad condicionada. Además su parametrización no depende de variables matemáticas, sino de variables propias de conocimiento de negocio.

Hemos visto un ejemplo de su aplicación y la información que se puede obtener de él. Además hemos visto que, a diferencia de otros modelos de Machine Learning es posible hacer una productificación con entrenamientos online, donde, según la predicción que se quiera hacer, se puede configurar los datos de entrenamiento de una forma o de otra.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.