Pronóstico de la demanda integrada

Pronóstico de la demanda integrada











Inicio » Recursos » Aquí

Los pronósticos de demanda probabilísticos son prácticamente obligados cuando se trata de la optimización del inventario. Se dice que los pronósticos de demanda son integrados con respecto al tiempo de entrega cuando los valores del pronóstico coinciden con la demanda total a lo largo del tiempo de entrega, a diferencia de la perspectiva de pronóstico clásico, en la que los pronósticos son periódicos (generalmente por día, por semana o por mes) e ignoran los tiempos de entrega. El motor de pronóstico de Lokad entrega pronósticos de demanda probabilísticos integrados que toman los tiempos de entrega pronósticos probabilísticos como dato de entrada. El motor de pronóstico de Lokad respalda de modo nativo los diferentes patrones estadísticos que se encuentran en los datos de negocios, como la estacionalidad, las tendencias y los ciclos de vida de los productos. También se tienen en cuenta las distorsiones de la demanda, como los desabastecimientos o las promociones. Los pronósticos de Lokad representan las probabilidades esperadas de demanda futura para cada unidad individual. En esta página, explicamos en detalle la sintaxis utilizada para calcular los pronósticos de demanda integrada de Lokad.

Sintaxis general

El motor de pronóstico tiene una función especial, una función llamada, como se la conoce en la terminología de Envision. La sintaxis es la siguiente:

Demand = forecast.demand(
category: C1, C2, C3, C4
hierarchy: H1, H2, H3, H4
location: Store
demandStartDate: LaunchDate
demandEndDate: EndDate
horizon: Leadtime
offset: 0
present: (max(Orders.Date) by 1) + 1
demandDate: Orders.Date
demandValue: Orders.Quantity
censoredDemandDate: Stockouts.StartDate, Stockouts.EndDate
inflatedDemandDate: TVAds.StartDate, TVAds.EndDate
promotionDate: Promotions.StartDate, Promotions.EndDate
promotionDiscount: Promotions.Discount
promotionCategory: Promotions.Type
covariable: Campaign
covariableObserved: false
covariableName: Ads.Campaign
covariableDate: Ads.Date
covariableValue: Ads.Volume)

A diferencia de las funciones habituales, las funciones llamada tienen argumentos con nombre en lugar de posicionales. Estos argumentos con nombre son más adecuados para funciones complejas, porque hacen que el código fuente sea mucho más legible, a cambio de un poco más de detalle. Estos argumentos se comportan como los argumentos de función habituales; por lo tanto, admiten las expresiones de Envision.

La función devuelve un vector Demand que es del tipo distribución (vea también el artículo sobre el álgebra de distribuciones). Las distribuciones son un tipo de datos avanzado que representan funciones $p: \mathbb{Z} \to \mathbb{R}$. Más específicamente, el motor de pronóstico devuelve variables aleatorias, es decir, distribuciones que son positivas y tienen una masa igual a 1. En el caso actual, $p(k)$ representa la probabilidad asociada con la demanda de $k$ unidades. Cada artículo —en el sentido utilizado en Envision— se asocia con su propia distribución de demanda.

La sintaxis completa de forecast.integral incluye muchos argumentos; sin embargo, solo cuatro de ellos son obligatorios:

  • present: un valor de fecha escalar
  • demandDate: un vector de fecha con una afinidad de artículo
  • demandValue: un vector numérico con una afinidad de artículo
  • horizon: un vector de distribución

El valor present es la fecha equivalente al primer día por pronosticar, suponiendo que existen datos completos hasta el día anterior. De hecho, algunos negocios pueden, por ejemplo, estar cerrados los domingos, y si la fecha más reciente encontrada en el conjunto de datos es un sábado, se presenta el dilema de si el pronóstico debería comenzar el domingo o el lunes. En la sintaxis ilustrativa a continuación, utilizamos max(Orders.Date) + 1, suponiendo que los pedidos se observan todos los días y que los datos de entrada son recientes del día anterior.

Se espera que los valores demandDate y demandValue correspondan a la misma tabla que exhibe una afinidad de artículo, es decir [Id, *] en terminología de Envision. Las fechas muestran el momento en que se observó la demanda en el pasado. Los valores representan la escala de la demanda, que generalmente se cuenta en unidades o elementos. No se admiten valores de demanda fraccionarios. Esta tabla contiene el historial de la demanda pronosticado por el motor de pronóstico. Idealmente, el historial debería ser lo más extenso posible, si bien en la práctica los beneficios de superar los 5 años de demanda son limitados. El motor de pronóstico se adapta tanto a un historial de demanda breve como extenso: cuando el historial es extenso, los puntos de datos más antiguos simplemente se vuelven estadísticamente irrelevantes.

El horizon representa el tiempo de entrega probabilístico que debe utilizarse cuando se pronostica la demanda. Y si bien tiempo de entrega se trata como un dato de entrada cuando se calcula un pronóstico de demanda integrado, el tiempo de entrega generalmente es también un pronóstico en sí mismo. El motor de pronóstico ofrece la posibilidad de pronosticar tiempos de entrega. El pronóstico de tiempo de entrega se desacopla del pronóstico de la demanda mismo, porque esto ofrece la posibilidad de realizar ajustes ad hoc en las distribuciones de tiempo de entrega antes de introducirlas en el motor de pronóstico.

Además de estos argumentos obligatorios, la precisión de los pronósticos puede mejorarse significativamente proporcionando más datos al motor de pronóstico. Las secciones a continuación explican este concepto en más detalle.

Definición formal

En esta sección, detallamos brevemente la definición formal de la operación estadística realizada por el motor de pronóstico al calcular el pronóstico de demanda integrada.

Supongamos que $y(t)$ es la función de la demanda, y que $t$ es el tiempo. Supongamos que la demanda integrada $D$ asociada a la variable aleatoria $\Lambda$ que representa los tiempos de entrega se define del siguiente modo:

$$\text{D} : (y,\Lambda,t_0) \to \int_0^{\infty} \mathbf{P}[\Lambda=\lambda] \left( \int_{t_0}^{t_0+\lambda} y(t) dt \right) d\lambda$$ donde $\mathbf{P}[\Lambda=\lambda]$ representa la probabilidad de que la variable aleatoria de tiempo de entrega $\Lambda$ sea igual a $\lambda$. La demanda se califica como integrada, porque es una integración sobre un tiempo de entrega probabilístico.

Si $t_0$ representa la fecha actual, la demanda es conocida —porque se observa— hasta el momento $t_0$, pero desconocida después. La finalidad del motor de pronóstico es calcular $\hat{D}(y, \Lambda)$, un cálculo probabilístico de esta demanda futura expresada como una variable aleatoria.

Categorías y jerarquía

Las categorías y la jerarquía desempeñan una función similar desde el punto de vista del motor de pronóstico: ayudan a este último a gestionar la demanda dispersa.

Consulte la página sobre pronóstico con categorías y una jerarquía.

Pronóstico de producto nuevo

Desde una perspectiva de pronóstico, un producto nuevo es un producto que aún no ha sido vendido. Esto representa un desafío de pronóstico bastante específico, porque, por definición, no existen datos históricos asociados a ese nuevo producto. Nuestro motor de pronóstico respalda el pronóstico de nuevos productos a través del argumento demandStartDate. Cuando se conoce la fecha de inicio histórica, se recomienda proporcionar esta información al motor de pronóstico, ya que esto contribuye a mejorar la precisión del pronóstico, tanto para los productos nuevos como para los existentes.

El argumento demandStartDate espera que se proporcione una fecha para cada artículo, que representará el primer día en el que la demanda se vuelve efectiva para ese artículo. Esta fecha se encuentra en el pasado para artículos que ya se han vendido, y se ubica en el futuro para los artículos que aún no han sido lanzados.

Existen dos ventajas diferentes de proporcionar el argumento demandStartDate. Claramente, la primera ventaja reside en el pronóstico de artículos nuevos. En este caso, generalmente también es importante especificar el argumento offset. De hecho, si el desfase se mantiene en cero —su valor predeterminado—, el período cubierto por el pronóstico probablemente no se superponga con el período activo del artículo.

Ejemplo: hoy es 1 de julio. El horizonte de pronóstico es una distribución de Dirac a 7 días, es decir, un tiempo de entrega constante de 7 días. El producto A se lanza el 15 de julio, su fecha de inicio. Si el pronóstico se realiza hoy, la distribución de pronóstico para el producto A es una Dirac en cero, porque el horizonte termina antes de la fecha de inicio del Producto A. Para pronosticar la primera semana de demanda del producto A, el desfase de ese producto debería establecerse en 14 días.

La segunda ventaja de especificar demandStartDate es que aumenta la precisión del pronóstico para todos los artículos, no solo para aquellos que aún no se han lanzado. De hecho, observar la primera unidad vendida en la fecha de inicio de un determinado artículo no es lo mismo que observar la primera unidad vendida seis meses después del lanzamiento. Mientras que el primer caso da a entender ventas futuras constantes, el último sugiere una demanda muy limitada de solo algunas unidades por año. El motor de pronóstico aprovecha el argumento demandStartDate para refinar los pronósticos de demanda de todos los artículos.

Demanda censurada y demanda exagerada

El objetivo es pronosticar la demanda. Sin embargo, a menudo los datos históricos solo aproximan la demanda real, por lo que crean distorsiones (adrede, o no). Por ejemplo, los datos históricos pueden estar representados por ventas históricas. Sin embargo, en el caso de desabastecimientos, los volúmenes de venta disminuyen, mientras que la demanda puede mantenerse estable. El motor de pronóstico de Lokad está diseñado de forma nativa para ocuparse de estas distorsiones, y esta es la finalidad misma tanto del argumento censoredDemandDate como del argumento inflatedDemandDate. Ambos argumentos esperan un vector de fecha con afinidad de artículo, es decir (Id, Date) en terminología de Envision.

Cuando una fecha de un determinado artículo está marcada como censored (censurada) a través de censoredDemandDate, el motor de pronóstico supondrá que la demanda es mayor o igual que el valor observado. El motor no hace suposiciones sobre cuán alta podría haber sido la demanda ese día específico, ya que este es un valor que nunca podremos conocer. Aún así, al identificar el sesgo, el motor puede implementar clases enteras de optimización adaptadas para este caso. En la práctica, la ocurrencia más común de demanda censurada son los desabastecimientos como se ve en los datos de ventas que no capturan información sobre las clientes potenciales que se van silenciosamente cuando los artículos están en faltante.

De modo similar, puede verse una demanda exagerada. El argumento inflatedDemandDate ofrece la posibilidad de identificar las fechas y los artículos en los que la demanda observada debería considerarse menor o igual que la demanda observada. También en este caso la demanda real es desconocida, pero la identificación del sesgo ya resulta muy útil para el motor de pronóstico. En la práctica, la demanda es exagerada cuando existen impulsos de mercado temporales no recurrentes: por ejemplo, el triunfo excepcional de un equipo deportivo local en un campeonato nacional puede tener un impacto muy favorable sobre las ventas de los supermercados locales durante algunos días.

Los dos argumentos, inflatedDemandDate y censoredDemandDate, pueden tomar uno o dos vectores como dato de entrada. Si se proporcionan dos vectores, los pares (inicio, fin) se tratan como segmentos inclusivos, siendo la primera fecha el comienzo del segmento y la segunda, el fin del segmento. Si se proporciona solo un vector, los segmentos se consideran de 1 día de duración; las fechas marcan los días exactos que deben considerarse como exagerados o censurados.

Si la censura o el exceso de la demanda son recurrentes —por año, por semana, etc.—, no hay necesidad de marcar la demanda como tal, ya que el motor de pronóstico gestiona esos patrones automáticamente.

Pronóstico de promociones

El motor de pronóstico ofrece respaldo nativo para las promociones. Los datos sobre las promociones, no obstante, son opcionales. Sin embargo, cuando se proporcionan, se espera que las promociones se especifiquen tanto en el pasado como en el futuro. Como mínimo, puede proporcionarse solo el argumento promotionDate. El argumento promotionDate sigue el mismo patrón de uso que censoredDemandDate: cuando se proporciona un solo vector de fecha, los períodos de promoción se consideran de un día de duración; si se proporcionan dos fechas, el primer vector representa las fechas de inicio inclusivas, mientras que el segundo vector representa las fechas de finalización inclusivas.

El argumento promotionDiscount es opcional, y puede proporcionarse para ayudar al motor de pronóstico a obtener información estratégica sobre la intensidad de una determinada promoción. Para este argumento se espera un vector de número, y el motor de pronóstico trata estos datos como valores ordinales: cuanto mayor es el descuento, mayor es el impacto promocional esperado. En la práctica, es el motor de pronóstico el que calcula el aumento de la demanda esperado de acuerdo con aumentos observados en promociones anteriores.

El argumento promotionCategory también es opcional, y puede proporcionarse como una clasificación de los eventos promocionales. Cuando se proporciona, el motor de pronóstico aprovecha este argumento para evaluar las afinidades entre los eventos promocionales y detectar si los eventos marcados dentro de la misma categoría obtienen aumentos de demanda similares. Este argumento es muy similar en esencia al argumento category, con la excepción de que se aplica a promociones en lugar de a artículos.

Advertencia. Las promociones son particularmente difíciles de pronosticar, incluso con datos históricos excelentes. La experiencia de Lokad indica que la mayoría de las empresas no cuentan con datos promocionales de alta precisión disponible. Dicho esto, esos datos pueden obtenerse a través de una preparación atenta en las últimas fases de un proyecto. Como regla general, la recopilación de datos promocionales que sean los suficientemente buenos como para mejorar la precisión de un pronóstico requiere una gran cantidad de esfuerzo. Darle al motor de pronóstico solo datos promocionales aproximados disminuye la precisión resultante.

Cuando se proporcionan los datos de promoción, generalmente no deberían marcarse los períodos relacionados con actividades promocionales medianteinflatedDemandDate. Marcar un período tanto a través de promotionDate como de inflatedDemand implica una semántica sutil: indica que el aumento promocional ha sido inflado más de lo que normalmente puede esperarse de una promoción y que la promoción misma se consideraría sesgada.

Covariables

Las covariables representan un mecanismo bastante avanzado para transmitir información al motor de pronóstico. En la práctica, no es recomendable utilizar covariables, porque generalmente resulta bastante complicado si se quieren obtener resultados resultados satisfactorios. Intuitivamente, las covariables están diseñadas para aprovechar los indicadores que anticipan la demanda de modo preciso y fiable. Para la mayoría de los negocios, no existen tales indicadores, y el historial de la demanda mismo sigue siendo el mejor indicador que existe para anticipar la demanda futura. Sin embargo, existen algunos sectores en los que presentan un indicador de este tipo.

Contoso Inc es una empresa de mantenimiento que se ocupa de turbinas eólicas. La empresa no construye turbinas, pero se adjudica licitaciones de contratos de mantenimiento importantes. Para poder realizar el mantenimiento de las turbinas, Contoso tiene que mantener su stock de piezas de recambio. La cantidad de piezas de recambio necesarias depende de modo muy lineal de la cantidad de turbinas que requieren mantenimiento. Debido a que los resultados de las licitaciones se conocen meses antes de la fecha de comienzo del contrato, Contoso utiliza la cantidad de turbinas como covariable para ayudarlo a adaptar sus necesidades de piezas de recambio.

Es posible asignar una covariable por artículo, como máximo, y esto se hace a través del argumento covariable. Luego, se espera que todas las covariables se definan dentro de una sola tabla de tres columnas:

  • covariableName que actúa como una clave externa en relación con el argumento covariable
  • covariableDate que representa la fecha asociada con la covariable, posiblemente en el futuro
  • covariableValue que representa el valor de la covariable en la fecha especificada

El último argumento es una marca booleana llamado covariableObserved, y en este caso se espera un escalar booleano. El valor predefinido es false. Cuando este argumento se establece como true, el motor de pronóstico supone que, desde un punto de vista histórico, los valores de la covariable no eran conocidos antes de su fecha, y, por lo tanto, los valores fueron observados. La configuración incorrecta de este campo confundiría al motor de pronóstico, haciéndolo suponer que los datos de la covariable están disponibles por adelantado, cuando esto puede no ser así.