Abstract: prevedere una media e decidere una quantità sono problemi diversi
Una rete che minimizza l’errore quadratico può stimare perfettamente la domanda media e suggerire comunque un ordine economicamente sfavorevole. Il motivo non è necessariamente il modello: mancanze ed eccedenze possono avere costi diversi. In un esempio sintetico la media ottima per MSE è 78 unità, con costo atteso 190 euro; il quantile economicamente pertinente porta a 200 unità e costo 122 euro, pur peggiorando molto l’MSE. Deriviamo la soglia decisionale, confrontiamo le alternative e mostriamo come vendite limitate dallo stock possano falsare il bersaglio di addestramento.
Il contesto è un singolo periodo di approvvigionamento di prodotto deperibile, senza riordini intermedi, sostituzioni o costi fissi. Quantità in unità, costi in euro per unità, domanda non negativa. Tutti i numeri sono ipotetici dichiarati e calcolati con Python, non risparmi ottenuti da EL-AI. Sono richiesti valore atteso, funzione cumulativa e nozioni di funzione convessa. Il risultato riguarda un modello decisionale circoscritto, non una politica completa di magazzino.
1. Scrivere la perdita prima di scegliere il modello
Siano D la domanda e Q la quantità disponibile. Una mancanza costa c_u per unità e un’eccedenza c_o. La perdita è c_u(D−Q)_+ + c_o(Q−D)_+, dove z_+=max(z,0). I costi sono incrementali: possono incorporare margine perso e costo netto dell’invenduto. Non bisogna aggiungere una seconda volta acquisto o ricavi già inclusi nei coefficienti. Qui fissiamo direttamente c_u=9 e c_o=1; l’obiettivo è minimizzare il valore atteso di questa perdita.
Per domanda continua, aumentare Q di una piccola quantità genera costo c_o quando D<Q e risparmia c_u quando D>Q. La derivata del rischio è (c_u+c_o)F(Q)−c_u. Si annulla a F(Q)=τ. Per domanda discreta la derivata può non esistere nei salti: la condizione corretta è F(Q−)≤τ≤F(Q). Il più piccolo quantile che raggiunge τ è un ottimo, ma possono esserci più ottimi se la cumulativa resta piatta al livello esatto. Non serve assumere normalità della domanda.
2. Un esempio discreto completamente calcolabile
Poniamo P(D=40)=0,50, P(D=80)=0,35 e P(D=200)=0,15. La media è 40·0,50+80·0,35+200·0,15=78. La cumulativa vale 0,50 a 40 e 0,85 a 80, quindi il quantile 0,90 è 200. Ordinando 80 unità, l’eccedenza media è 0,50·40=20 e la mancanza media è 0,15·120=18: costo 20+9·18=182. Ordinandone 200 non ci sono mancanze, ma eccedenza media 0,50·160+0,35·120=122. Il confronto è sul costo definito, non sul numero di unità rimaste.
| Q | Costo EUR | MSE unitಠ| Mancanza media |
|---|---|---|---|
| 40 | 342.0 | 4400.0 | 38.0 |
| 78 | 190.0 | 2956.0 | 19.0 |
| 80 | 182.0 | 2960.0 | 18.0 |
| 120 | 162.0 | 4720.0 | 12.0 |
| 200 | 122.0 | 17840.0 | 0.0 |
Lo script enumera Q da 0 a 240 e verifica due minimi diversi: MSE a 78, costo a 200. Controlla anche ogni differenza intera R(Q+1)−R(Q)=10F(Q)−9. Tra 80 e 199 la differenza è −0,5 euro: ogni unità aggiuntiva riduce il costo atteso. Da 200 in poi diventa +1 euro. Questo controllo indipendente dell’enumerazione rende visibile la forma convessa del problema e la ragione del punto di minimo.

3. Collegare il quantile alla funzione obiettivo dell’AI
La pinball loss ρ_τ(D−Q) assegna peso τ alla sottostima e 1−τ alla sovrastima. La nostra perdita economica è esattamente (c_u+c_o)ρ_τ(D−Q). Un modello condizionato su x può quindi apprendere il quantile pertinente usando questa perdita, se dati, rappresentazione e ottimizzazione lo consentono. Cambiare soltanto l’architettura mantenendo MSE continua invece a puntare alla media condizionata. Nel nostro esempio anche la MAE è incapace di scegliere: tutti i Q fra 40 e 80 hanno MAE=38, ma costi economici diversi.
Se il costo di mancanza scende a 4 con c_o=1, τ diventa 0,80 e il primo ottimo è 80. Con costi uguali τ=0,50 e l’intero intervallo [40,80] è ottimo. Se il magazzino ammette al massimo 120 unità, nel caso iniziale l’ottimo vincolato è 120 e costa 162 euro. Non si possono ordinare 200 unità ignorando il vincolo. Con lotti, budget condivisi fra prodotti o costi fissi, il semplice quantile per articolo può non risolvere il problema complessivo.
4. Livello di servizio e domanda invisibile
τ=0,90 non significa che la decisione avrà esattamente il 90% di periodi senza mancanze. La distribuzione discreta salta da F(80)=0,85 a F(200)=1. Inoltre il cycle service level P(D≤Q) è diverso dal fill rate 1−E[(D−Q)_+]/E[D]. A Q=80 il primo è 85%, il secondo 76,9231%: il regime raro contiene molte unità mancanti. Anche due indicatori denominati “servizio” possono guidare scelte differenti se non se ne esplicita il denominatore.
Supponiamo che lo storico abbia sempre stock massimo 80. Il sistema registra vendite S=min(D,80): osserva 40 nel 50% dei casi e 80 nel restante 50%, perdendo la distinzione fra domanda 80 e 200. Il quantile 90% delle vendite è 80; il suo costo apparente è appena 20 euro, contro il costo reale 182 sulla domanda latente. Non è un errore risolto da più epoche di training: il bersaglio osservato è censurato. Una domanda di 1000 nei periodi di esaurimento genererebbe lo stesso storico di vendite, quindi lo storico da solo non identifica quella coda.
Per un’applicazione reale servono disponibilità nel tempo, segnalazioni di stockout e una strategia esplicita per la domanda non osservata. La valutazione deve usare separazioni temporali coerenti con la decisione, costi dichiarati e confronti con politiche semplici; dati futuri o vendite censurate trattate come domanda piena possono rendere ingannevole un risultato offline. L’analisi presente non addestra un modello: stabilisce che cosa dovrebbe imparare e con quale funzione misurarne l’utilità.
5. Quanto è fragile il quantile imparato da pochi dati?
Finora conoscevamo la distribuzione. Con venti giorni indipendenti osservati, il quantile empirico 90% è la diciottesima domanda ordinata. Se i giorni con domanda 200 sono al massimo due, quel quantile non può superare 80. Il loro numero K segue una binomiale con n=20 e probabilità 0,15. La probabilità esatta P(K≤2), calcolata sommando tre termini binomiali, è 0,404896278. Quindi circa il 40,49% di questi piccoli campioni non suggerirebbe 200, anche senza censura e senza alcun errore nell’ottimizzatore. È incertezza campionaria sulla coda, distinta dal bias introdotto dalle vendite limitate.
Anche i coefficienti meritano una sensibilità esplicita. Tra 80 e 200, conviene aumentare Q solo se c_u>0,85/0,15=17/3 euro per unità. Il cambio di decisione è netto, pur essendo continuo il costo atteso: sotto questa soglia 80 è preferibile, sopra lo è 200, al valore esatto ogni quantità intermedia ha lo stesso costo. Stimare c_u=4 quando il costo effettivo è 9 porta a scegliere 80 e perdere 60 euro attesi per periodo rispetto all’ottimo del modello. Tale cifra è una differenza teorica fra politiche su questa popolazione, non un risparmio commerciale previsto.
Per un modello condizionato, stagionalità, promozioni e tempi di consegna devono essere disponibili prima dell’ordine. Il quantile da imparare è quello della domanda durante il periodo coperto dalla decisione, non necessariamente quello delle vendite del giorno seguente. Se il costo dipende dal contesto x, anche τ(x) può cambiare. Una singola uscita addestrata al quantile 90% non risponde automaticamente a un nuovo rapporto di costi: occorre stimare più quantili o una distribuzione, e valutarli senza scegliere il modello sullo stesso periodo usato per dichiararne il vantaggio.
6. Conclusione e fonte metodologica
Le note MIT sul problema newsvendor espongono la decisione marginale e il rapporto fra costi; sono stati consultati derivazione ed esempi discreti e continui. Il nostro caso numerico è autonomo. Il risultato non dice che ordinare di più sia sempre meglio: dice che il quantile giusto dipende dai costi e dai vincoli, mentre il dato giusto deve rappresentare domanda, non soltanto vendite disponibili. Prima di confrontare architetture AI, occorre verificare che la funzione obiettivo risponda alla decisione aziendale.
demand = [(40, .5), (80, .35), (200, .15)]
def cost(q):
return sum(p*(9*max(d-q,0)+max(q-d,0)) for d,p in demand)
print(sum(d*p for d,p in demand))
print(min(range(241), key=cost))
for q in [40,78,80,120,200]:
print(q,cost(q))
Codice, dati e istruzioni · JSON. Calcoli didattici eseguiti con Python 3.14.0; figure con Matplotlib 3.11.2. Analisi con assistenza AI, senza dichiarare peer review o revisione umana. Copertina originale ImageGen, illustrativa: non documenta persone, sedi o installazioni EL-AI. Fonti consultate il 24 settembre 2026.

