存路徑優(yōu)化實(shí)戰(zhàn):分位數(shù)預(yù)測(cè)與多場(chǎng)景隨機(jī)規(guī)劃)
1. 項(xiàng)目背景與核心痛點(diǎn)1.1 庫(kù)存路徑優(yōu)化到底在解決什么問(wèn)題做供應(yīng)鏈優(yōu)化的人對(duì)IRPInventory Routing Problem庫(kù)存路徑問(wèn)題一定不陌生。它把兩個(gè)原本分開(kāi)管的決策捏在了一起給誰(shuí)補(bǔ)貨、補(bǔ)多少以及用什么順序送。傳統(tǒng)做法是銷售預(yù)測(cè)團(tuán)隊(duì)先給一版需求量計(jì)劃團(tuán)隊(duì)照著預(yù)測(cè)做配送計(jì)劃倉(cāng)儲(chǔ)團(tuán)隊(duì)按計(jì)劃備貨三個(gè)環(huán)節(jié)各管一段鏈條一長(zhǎng)就容易失真。我這次要分享的項(xiàng)目核心是給某零售企業(yè)的區(qū)域配送網(wǎng)絡(luò)做一套在線庫(kù)存路徑優(yōu)化方案發(fā)表在Transportation Science這個(gè)方向上的一次完整落地實(shí)踐。場(chǎng)景本身不復(fù)雜一個(gè)配送中心服務(wù)幾十家門店每家門店有獨(dú)立的庫(kù)存容量和消耗速率配送中心有車輛資源限制每天要在銷量預(yù)測(cè)的基礎(chǔ)上決定給各家門店送多少貨、走什么路線。難點(diǎn)在于門店的需求是隨機(jī)的節(jié)假日、天氣、促銷活動(dòng)都會(huì)造成需求波動(dòng)。如果你用固定的預(yù)測(cè)值去排補(bǔ)貨計(jì)劃預(yù)測(cè)偏差大的門店要么庫(kù)存積壓要么直接斷貨。斷貨是零售的大忌損失的不只是當(dāng)天銷量還有顧客信任。積壓也不好看占用資金還增加倉(cāng)儲(chǔ)成本。所以在真實(shí)場(chǎng)景里大家真正想要的是一套能“看得到不確定性”的決策系統(tǒng)而不是只輸出一個(gè)平均數(shù)的預(yù)測(cè)模型。1.2 傳統(tǒng)兩段式方案的三個(gè)硬傷先說(shuō)傳統(tǒng)做法先預(yù)測(cè)后優(yōu)化Predict-then-Optimize這也是大多數(shù)企業(yè)已經(jīng)在用的框架。第一步用時(shí)間序列模型或機(jī)器學(xué)習(xí)模型預(yù)測(cè)每個(gè)門店未來(lái)幾天的需求第二步把這些預(yù)測(cè)值當(dāng)成真實(shí)需求輸入到車輛路徑和補(bǔ)貨量的優(yōu)化模型里求解。聽(tīng)起來(lái)很順但實(shí)際跑起來(lái)有三個(gè)硬傷。第一個(gè)硬傷是預(yù)測(cè)誤差被靜默放大。優(yōu)化模型是確定性的它默認(rèn)預(yù)測(cè)值就是真值于是會(huì)把最敏感的約束條件卡在預(yù)測(cè)值的邊界上。比如預(yù)測(cè)某門店明天賣100件實(shí)際可能賣120件車輛調(diào)度的時(shí)候剛好少裝了幾件結(jié)果就是斷貨。因?yàn)閮?yōu)化器不會(huì)主動(dòng)給你留安全余量除非你在模型里顯式地加。第二個(gè)硬傷是預(yù)測(cè)模型和優(yōu)化目標(biāo)錯(cuò)位。預(yù)測(cè)模型訓(xùn)練時(shí)用的是均方誤差或平均絕對(duì)誤差衡量的是“預(yù)測(cè)值離真實(shí)值有多近”。但下游決策真正關(guān)心的不是預(yù)測(cè)準(zhǔn)不準(zhǔn)而是“決策損失”大不大。有時(shí)候預(yù)測(cè)偏了10%因?yàn)榕銮刹挥|發(fā)補(bǔ)貨閾值決策損失是零有時(shí)候預(yù)測(cè)只偏了2%正好卡在閾值附近就會(huì)導(dǎo)致漏補(bǔ)一批貨損失很大。預(yù)測(cè)誤差和決策損失之間不是線性關(guān)系這導(dǎo)致預(yù)測(cè)階段的優(yōu)化目標(biāo)跟決策目標(biāo)根本不在一個(gè)頻道上。第三個(gè)硬傷是缺少場(chǎng)景概念。傳統(tǒng)預(yù)測(cè)輸出的是一個(gè)點(diǎn)估計(jì)最多再加個(gè)置信區(qū)間但優(yōu)化模型需要的是一組“可能會(huì)發(fā)生的需求樣本”而不是一個(gè)均值。均值只能代表最可能的情況恰恰忽略了尾部的風(fēng)險(xiǎn)場(chǎng)景。這個(gè)項(xiàng)目的核心思路就是把這三點(diǎn)一起解決在預(yù)測(cè)階段就面向下游決策去建模用多個(gè)場(chǎng)景表達(dá)不確定性再把場(chǎng)景遞交給優(yōu)化器做魯棒決策。下面我會(huì)把這套架構(gòu)的設(shè)計(jì)邏輯和實(shí)操細(xì)節(jié)完整拆開(kāi)來(lái)講。2. 預(yù)測(cè)后優(yōu)化的整體設(shè)計(jì)思路2.1 為什么還要用“預(yù)測(cè)后優(yōu)化”而不是端到端聯(lián)合訓(xùn)練先解釋一個(gè)很多人會(huì)問(wèn)的問(wèn)題現(xiàn)在深度學(xué)習(xí)這么流行為什么不直接做端到端的聯(lián)合優(yōu)化把預(yù)測(cè)模型和優(yōu)化模型糅在一起訓(xùn)練聯(lián)合優(yōu)化Decision-focused Learning確實(shí)是學(xué)術(shù)熱點(diǎn)思路也很誘人將決策損失直接作為預(yù)測(cè)模型的訓(xùn)練損失讓預(yù)測(cè)模型知道下游要什么從而反向修正自己的輸出。但落地時(shí)有個(gè)現(xiàn)實(shí)障礙——最優(yōu)化求解器是不可導(dǎo)的。庫(kù)存路徑問(wèn)題在數(shù)學(xué)上是個(gè)混合整數(shù)規(guī)劃MIP內(nèi)部還有車輛路徑選擇解空間非常大。你要把不可導(dǎo)的求解器嵌入神經(jīng)網(wǎng)絡(luò)反向傳播需要引入凸近似、解析梯度或者黑盒梯度估計(jì)每種方法都伴隨額外的計(jì)算開(kāi)銷和實(shí)現(xiàn)復(fù)雜度。在工業(yè)項(xiàng)目里我更看重可解釋性和可迭代性。預(yù)測(cè)后優(yōu)化是一種模塊化設(shè)計(jì)預(yù)測(cè)模塊壞了可以單獨(dú)換優(yōu)化模塊升級(jí)了不影響預(yù)測(cè)。業(yè)務(wù)團(tuán)隊(duì)也能理解這套邏輯——先預(yù)測(cè)需求再算補(bǔ)貨方案鏈條透明。聯(lián)合訓(xùn)練的黑盒感太強(qiáng)出了問(wèn)題很難排查是哪一側(cè)的責(zé)任。不過(guò)這也意味著我們必須主動(dòng)去彌合“預(yù)測(cè)”和“優(yōu)化”之間的縫隙。前面的三個(gè)硬傷不解決模塊化反而是放任問(wèn)題存在。所以我在這套方案里做了一個(gè)折中保持模塊化的預(yù)測(cè)后優(yōu)化框架但在預(yù)測(cè)端引入決策感知的損失修正在優(yōu)化端引入多場(chǎng)景隨機(jī)規(guī)劃。這樣既兼顧了模塊之間的清晰邊界又讓兩個(gè)模塊在“信息”層面實(shí)現(xiàn)了協(xié)同而不是在“梯度”層面硬耦合。2.2 整體架構(gòu)從數(shù)據(jù)流看系統(tǒng)的四層結(jié)構(gòu)整個(gè)系統(tǒng)我把它分成四層數(shù)據(jù)層、預(yù)測(cè)層、場(chǎng)景層、決策層。數(shù)據(jù)層負(fù)責(zé)匯總門店的歷史銷售流水、促銷日歷、天氣數(shù)據(jù)、庫(kù)存水位和配送履歷。這塊的基建很重要因?yàn)楹竺嫠心P偷男Ч舷薅既Q于數(shù)據(jù)的質(zhì)量和粒度。我們做的時(shí)候發(fā)現(xiàn)很多門店的銷售數(shù)據(jù)存在漏傳、重復(fù)記賬的問(wèn)題清洗口徑不統(tǒng)一這件事花了整整兩周才理順。預(yù)測(cè)層是核心模塊之一用了多個(gè)模型組成的預(yù)測(cè)引擎以梯度提升樹(shù)模型為主力輔以季節(jié)性時(shí)間序列模型做交叉驗(yàn)證。預(yù)測(cè)目標(biāo)是每個(gè)門店未來(lái)7天逐日的需求分布不只是均值還要給出分位數(shù)。這樣后面生成場(chǎng)景時(shí)才有概率信息可用。場(chǎng)景層負(fù)責(zé)把預(yù)測(cè)分布轉(zhuǎn)成優(yōu)化器能吃的場(chǎng)景集合。這里用到了分位數(shù)采樣的思想把每天的預(yù)測(cè)分成多個(gè)分位數(shù)段每段代表一種可能的行情組合起來(lái)生成數(shù)百個(gè)需求場(chǎng)景。場(chǎng)景之間的一致性約束很重要——同一個(gè)門店前后兩天的需求量不能出現(xiàn)荒謬的跳躍否則優(yōu)化器會(huì)鉆空子。決策層是一個(gè)兩階段隨機(jī)規(guī)劃模型。第一階段決定車輛的出車路線和整體裝載計(jì)劃第二階段根據(jù)場(chǎng)景實(shí)現(xiàn)情況進(jìn)行補(bǔ)貨量的調(diào)整。求解用的是商業(yè)求解器加啟發(fā)式算法混合的框架在可接受的幾分鐘內(nèi)給出可用方案。這四層結(jié)構(gòu)看著并不花哨難點(diǎn)全部藏在細(xì)節(jié)里。下面我逐個(gè)模塊說(shuō)明重點(diǎn)講清楚每一步的選型理由和踩坑經(jīng)過(guò)。3. 核心模塊拆解與關(guān)鍵實(shí)現(xiàn)3.1 需求預(yù)測(cè)引擎分位數(shù)預(yù)測(cè)比點(diǎn)預(yù)測(cè)重要得多我在這類項(xiàng)目里反復(fù)驗(yàn)證過(guò)一件事對(duì)下游優(yōu)化而言預(yù)測(cè)分布比分均值重要得多。如果你只給優(yōu)化器一個(gè)點(diǎn)預(yù)測(cè)值它必然會(huì)輸出一個(gè)緊貼這個(gè)值的補(bǔ)貨量和路線方案完全沒(méi)有緩沖空間。而如果你給的是一個(gè)分位數(shù)區(qū)間優(yōu)化器在做約束規(guī)劃時(shí)就能自動(dòng)權(quán)衡“少送導(dǎo)致缺貨”和“多送導(dǎo)致積壓”兩種風(fēng)險(xiǎn)的代價(jià)。具體實(shí)現(xiàn)上我用LightGBM做了分位數(shù)回歸設(shè)置三個(gè)目標(biāo)分位10%、50%、90%。特征工程是重頭戲包括門店維度歷史平均銷量、銷量方差、門店類型、倉(cāng)儲(chǔ)容量時(shí)間維度星期幾、是否節(jié)假日、月份外部變量天氣溫度、降雨概率、促銷事件標(biāo)記。這里有個(gè)容易踩的坑促銷事件的標(biāo)記一定要做成“促銷前/中/后”三段而不是只打一個(gè)促銷日標(biāo)記。因?yàn)榱闶鄞黉N有很強(qiáng)的透支效應(yīng)和回補(bǔ)效應(yīng)促銷當(dāng)天銷量暴漲促銷后一兩天銷量往往低于基線。如果不處理這個(gè)效應(yīng)預(yù)測(cè)模型會(huì)把促銷前的低值學(xué)成常態(tài)導(dǎo)致促銷前備貨不足促銷后庫(kù)存積壓。時(shí)序交叉驗(yàn)證是另一個(gè)必須做對(duì)的事。常規(guī)的K折隨機(jī)交叉驗(yàn)證在時(shí)序數(shù)據(jù)上會(huì)泄露未來(lái)信息必須用滾動(dòng)窗口的方式訓(xùn)練集是過(guò)去12個(gè)月驗(yàn)證集是緊接著的4周然后窗口逐步向前滾動(dòng)。我習(xí)慣的做法是至少驗(yàn)證4個(gè)滾動(dòng)窗口覆蓋不同的季節(jié)段避免模型只在某個(gè)月份表現(xiàn)好。最后輸出的不只是分位數(shù)還要做一次后校準(zhǔn)。用預(yù)測(cè)區(qū)間覆蓋率的指標(biāo)來(lái)檢查比如10%分位對(duì)應(yīng)的實(shí)際覆蓋率應(yīng)該接近10%如果覆蓋率偏差太大說(shuō)明模型有系統(tǒng)性偏差需要調(diào)整。這個(gè)校準(zhǔn)步驟經(jīng)常被忽略但對(duì)下游場(chǎng)景生成的影響非常大。3.2 場(chǎng)景生成從分位數(shù)到多階段需求路徑的橋場(chǎng)景層是整個(gè)方案里最考驗(yàn)工程判斷的部分。預(yù)測(cè)模型輸出每天每個(gè)門店的三個(gè)分位數(shù)但優(yōu)化器不想要“分位數(shù)”它想要的是“一組完整的需求場(chǎng)景”。我的做法是采用分位數(shù)分段抽樣。具體來(lái)說(shuō)把0到1的累計(jì)概率區(qū)間切成L層每一層是一個(gè)等概率的分段。比如L10每層覆蓋10%的概率質(zhì)量。然后對(duì)每一層取該分段的條件中位數(shù)作為這一層的代表需求量。這樣每個(gè)門店每天能抽出10個(gè)代表值每個(gè)代表值對(duì)應(yīng)一種“行情強(qiáng)度”。接下來(lái)要做跨時(shí)間的場(chǎng)景拼接。門店第1天的行情弱、第2天的行情強(qiáng)這種組合必須控制在一個(gè)合理的聯(lián)合概率范圍內(nèi)不能隨機(jī)亂拼。解決方案是為每個(gè)門店構(gòu)造一個(gè)馬爾可夫鏈行情狀態(tài)之間的轉(zhuǎn)移概率從歷史數(shù)據(jù)里估計(jì)。比如“昨天弱、今天強(qiáng)”的概率是多少直接統(tǒng)計(jì)歷史天數(shù)就能得到。場(chǎng)景生成時(shí)先按初始狀態(tài)分布采樣第1天的行情檔位然后根據(jù)轉(zhuǎn)移概率逐漸生成后面每一天的檔位。這樣生成的場(chǎng)景序列帶有時(shí)間自相關(guān)性更貼近真實(shí)需求波動(dòng)。場(chǎng)景數(shù)量怎么定我測(cè)試過(guò)50、100、200、500四檔。場(chǎng)景太少優(yōu)化結(jié)果方差大這次跑出來(lái)是這個(gè)方案下次同樣的輸入跑出另一個(gè)方案業(yè)務(wù)團(tuán)隊(duì)沒(méi)法接受。場(chǎng)景太多求解時(shí)間直線上升。最后我選了200個(gè)場(chǎng)景兼顧穩(wěn)定性和求解效率。這中間有個(gè)細(xì)節(jié)值得說(shuō)場(chǎng)景生成之后一定要做一次可視化檢查。把歷史真實(shí)的需求路徑和生成的需求路徑疊在一張圖上肉眼觀察兩者是否形態(tài)相似。我遇到過(guò)這樣的情況——模型在數(shù)值指標(biāo)上表現(xiàn)很好但生成的場(chǎng)景在高峰期過(guò)于平滑、把尖峰全磨平了導(dǎo)致優(yōu)化器嚴(yán)重低估峰值需求。這種問(wèn)題不看圖是發(fā)現(xiàn)不了的。3.3 優(yōu)化模型兩階段隨機(jī)規(guī)劃的數(shù)學(xué)表達(dá)與求解決策層的核心模型我采用了兩階段隨機(jī)整數(shù)規(guī)劃的框架。先看一個(gè)簡(jiǎn)化的數(shù)學(xué)表達(dá)第一階段變量是車輛的路徑?jīng)Q策。設(shè)車輛集合為V門店集合為C配送中心為0定義變量 x_{ij}^v 表示車輛v是否從點(diǎn)i行駛到點(diǎn)j。目標(biāo)函數(shù)包含固定出車成本、行駛距離成本。第二階段變量是每個(gè)場(chǎng)景下的補(bǔ)貨量和對(duì)庫(kù)存的懲罰。設(shè)場(chǎng)景s下門店i在t天的需求為 d_{i,t}^s補(bǔ)貨后庫(kù)存為 I_{i,t}^s那么第二階段會(huì)對(duì)缺貨和超容計(jì)算懲罰成本。完整的模型表達(dá)式實(shí)際上是[ \min \sum_{v \in V} \sum_{(i,j) \in A} c_{ij} x_{ij}^v \frac{1}{S} \sum_{s1}^{S} \sum_{i,t} \big( p_{\text{stockout}} \cdot \max(0, d_{i,t}^s - I_{i,t}^s) p_{\text{overflow}} \cdot \max(0, I_{i,t}^s - C_i) \big) ]這里有幾個(gè)業(yè)務(wù)上需要仔細(xì)斟酌的參數(shù)缺貨懲罰 p_stockout應(yīng)該等于單位商品的毛利損失加上品牌損失折算。我們按商品平均毛利做了估算同時(shí)給了一個(gè)上調(diào)系數(shù)因?yàn)閿嘭涍€影響消費(fèi)者忠誠(chéng)度超容懲罰 p_overflow應(yīng)該等于臨時(shí)調(diào)撥成本或者倉(cāng)庫(kù)二次處理成本。這個(gè)值如果設(shè)得太低優(yōu)化器會(huì)讓門店庫(kù)存頂?shù)教旎ò瀣F(xiàn)場(chǎng)根本放不下設(shè)得太高又會(huì)導(dǎo)致車輛少裝貨、頻次變高運(yùn)輸成本失控車輛數(shù)上限設(shè)置時(shí)參考了現(xiàn)有車隊(duì)規(guī)模和高峰期運(yùn)力冗余不是拍腦袋定的而是統(tǒng)計(jì)了過(guò)去三個(gè)月的出車記錄取90分位數(shù)。路徑約束部分用的是標(biāo)準(zhǔn)的車輛路徑問(wèn)題約束加上了每個(gè)車輛的最大行駛時(shí)長(zhǎng)限制。這里要特別提一個(gè)工程問(wèn)題門店數(shù)量六七十家時(shí)精確求解已經(jīng)非常吃力。我嘗試過(guò)直接調(diào)用求解器跑完整MIP兩小時(shí)內(nèi)給不出穩(wěn)定解。后來(lái)?yè)Q成了“列生成局部搜索”的混合策略先構(gòu)造初始可行解再用鄰域搜索做改進(jìn)最后用求解器對(duì)剩余的小規(guī)模子問(wèn)題做精確優(yōu)化。效果是在5到8分鐘內(nèi)能給出一版穩(wěn)定方案滿足調(diào)度時(shí)效。3.4 決策感知修正在預(yù)測(cè)階段注入優(yōu)化目標(biāo)的信息這一節(jié)是方案里最有意思的部分也是我認(rèn)為整個(gè)系統(tǒng)真正值錢的地方。既然聯(lián)合訓(xùn)練不劃算那有沒(méi)有辦法在保持模塊化設(shè)計(jì)的前提下讓預(yù)測(cè)模型“知道”下游優(yōu)化器關(guān)心什么我的做法是構(gòu)造一個(gè)決策損失代理函數(shù)。庫(kù)存路徑問(wèn)題里真正讓優(yōu)化器敏感的不是預(yù)測(cè)均值偏差而是補(bǔ)貨閾值附近的需求跨越。如果一個(gè)門店當(dāng)前庫(kù)存只夠賣兩天而預(yù)測(cè)明天需求剛好超過(guò)某個(gè)臨界值那么優(yōu)化器就會(huì)決定派車。預(yù)測(cè)值在這個(gè)臨界值上下微小的移動(dòng)會(huì)完全改變決策結(jié)果。所以預(yù)測(cè)模型應(yīng)當(dāng)在臨界值附近的區(qū)段付出更大的擬合代價(jià)。具體實(shí)現(xiàn)是在原有回歸損失的基礎(chǔ)上加了一個(gè)權(quán)重函數(shù)[ L \frac{1}{N} \sum_{n1}^{N} w(y_n) \cdot (q_{\theta}(x_n) - y_n)^2 ]權(quán)重 w(y_n) 由庫(kù)存狀態(tài)決定當(dāng)預(yù)測(cè)值接近補(bǔ)貨觸發(fā)閾值時(shí)權(quán)重提高遠(yuǎn)離閾值時(shí)權(quán)重保持基準(zhǔn)值。這個(gè)權(quán)重的形狀經(jīng)過(guò)了好幾輪迭代。第一版用的是階躍函數(shù)效果不好因?yàn)殚撝蹈浇奶荻韧蛔儠?huì)讓訓(xùn)練不穩(wěn)定。后來(lái)改成了以閾值為中心的高斯凸起寬度取歷史需求標(biāo)準(zhǔn)差的一半訓(xùn)練穩(wěn)定性明顯改善。這個(gè)方法說(shuō)起來(lái)簡(jiǎn)單但它的效果立竿見(jiàn)影。對(duì)比同一個(gè)小區(qū)的模型加了決策感知修正之后優(yōu)化層的平均決策損失下降了大約6%而預(yù)測(cè)的均方誤差幾乎沒(méi)變。這說(shuō)明什么說(shuō)明我們?cè)诓粻奚A(yù)測(cè)精度的前提下用很少的額外計(jì)算量讓預(yù)測(cè)分布的位置更貼合決策需求。坦白講這個(gè)6%在學(xué)術(shù)實(shí)驗(yàn)里不算大數(shù)字但在真實(shí)配送網(wǎng)絡(luò)中它意味著每個(gè)月能少幾十次缺貨事件收益非??捎^。4. 實(shí)操過(guò)程與效果復(fù)盤(pán)4.1 數(shù)據(jù)工程清洗口徑是繞不過(guò)去的硬骨頭進(jìn)入訓(xùn)練和調(diào)優(yōu)之前我先說(shuō)數(shù)據(jù)清洗。這個(gè)環(huán)節(jié)不性感但在這類項(xiàng)目中它決定成敗。我們處理的是某區(qū)域連鎖零售企業(yè)過(guò)去18個(gè)月的配送數(shù)據(jù)涉及幾十家門店、上千個(gè)SKU原始數(shù)據(jù)分散在三個(gè)系統(tǒng)里POS銷售系統(tǒng)、倉(cāng)庫(kù)管理系統(tǒng)、運(yùn)輸管理系統(tǒng)。第一道坎是銷售數(shù)據(jù)的口徑問(wèn)題。POS系統(tǒng)里記錄的是“銷售時(shí)間”倉(cāng)庫(kù)配送記錄的是“到達(dá)時(shí)間”兩個(gè)時(shí)間口徑相差一兩天在做庫(kù)存推演時(shí)需要對(duì)齊。我們選擇以“門店?duì)I業(yè)日”作為統(tǒng)一的時(shí)間粒度把跨日銷售按照營(yíng)業(yè)時(shí)段進(jìn)行劃分。這塊沒(méi)有標(biāo)準(zhǔn)答案但一定要在項(xiàng)目初期定出口徑文檔否則后續(xù)所有分析都是空中樓閣。第二道坎是SKU聚合。每家門店上千個(gè)SKU不可能逐個(gè)建模。我按商品的補(bǔ)貨周期、體積、冷鏈要求、銷量波動(dòng)特征把SKU聚合成幾個(gè)大類。大類內(nèi)部的需求相關(guān)性較高用加權(quán)的總銷量作為模型輸入。這個(gè)聚合粒度直接影響優(yōu)化器輸出的顆粒度——太粗方案沒(méi)法落地太細(xì)優(yōu)化規(guī)模爆炸。最后選了中等粒度常溫標(biāo)品、低溫乳品、生鮮果蔬、日配面包四大類。第三道坎是異常值處理。門店盤(pán)點(diǎn)錯(cuò)誤、臨時(shí)促銷、系統(tǒng)故障都會(huì)產(chǎn)生異常銷售記錄。我的處理方式是做兩輪過(guò)濾第一輪用統(tǒng)計(jì)閾值剔除超出歷史均值5倍標(biāo)準(zhǔn)差的極端值第二輪靠人工抽檢重點(diǎn)檢查節(jié)假日前后的大額訂單記錄確認(rèn)是真實(shí)需求還是重復(fù)記賬。這兩輪過(guò)濾下來(lái)數(shù)據(jù)質(zhì)量才勉強(qiáng)夠資格進(jìn)模型。4.2 實(shí)驗(yàn)設(shè)計(jì)與消融對(duì)比整套系統(tǒng)做完之后我做了一組嚴(yán)格的消融實(shí)驗(yàn)?zāi)康氖腔卮鹑齻€(gè)問(wèn)題多場(chǎng)景優(yōu)化到底比點(diǎn)預(yù)測(cè)優(yōu)化強(qiáng)多少?zèng)Q策感知修正的價(jià)值有多大整套方案相比企業(yè)原來(lái)的手工計(jì)劃提高了什么實(shí)驗(yàn)設(shè)計(jì)如下方案編號(hào)預(yù)測(cè)端優(yōu)化端說(shuō)明A點(diǎn)預(yù)測(cè)確定優(yōu)化模擬傳統(tǒng)方案B分位數(shù)預(yù)測(cè)確定優(yōu)化只用預(yù)測(cè)分布均值做輸入C分位數(shù)預(yù)測(cè)多場(chǎng)景隨機(jī)規(guī)劃不加決策感知修正D分位數(shù)預(yù)測(cè)多場(chǎng)景隨機(jī)規(guī)劃 決策感知修正完整方案評(píng)價(jià)指標(biāo)用三個(gè)月度缺貨次數(shù)、庫(kù)存周轉(zhuǎn)天數(shù)、每單配送成本。結(jié)果比預(yù)想的更有說(shuō)服力。方案A的月度缺貨次數(shù)是完整方案D的2.3倍庫(kù)存周轉(zhuǎn)天數(shù)多出1.4天。方案B和方案A的差異不大說(shuō)明只改進(jìn)預(yù)測(cè)端的輸出形式而不改優(yōu)化端收益有限。方案C到方案D的提升主要體現(xiàn)在缺貨次數(shù)上減少了約15%而庫(kù)存和運(yùn)輸成本幾乎不變——決策感知修正帶來(lái)的是一種零成本的“白撿”收益。這個(gè)對(duì)比說(shuō)明一個(gè)很重要的道理系統(tǒng)的性能瓶頸往往不在某一個(gè)單獨(dú)模塊而在模塊之間的信息傳遞方式。預(yù)測(cè)端輸出更豐富的不確定性信息、優(yōu)化端利用這些信息做權(quán)衡決策兩端一起改效果才會(huì)指數(shù)級(jí)放大。4.3 上線驗(yàn)證從離線回測(cè)到小范圍試運(yùn)行離線實(shí)驗(yàn)做完緊接著是回測(cè)驗(yàn)證。我用的是歷史回放的方式拿到3個(gè)月的原始數(shù)據(jù)每天按照系統(tǒng)的輸入輸出做模擬把系統(tǒng)推薦的補(bǔ)貨和配送方案應(yīng)用到當(dāng)天的庫(kù)存狀態(tài)上逐日推演最后統(tǒng)計(jì)缺貨、庫(kù)存、運(yùn)力使用的累計(jì)指標(biāo)?;販y(cè)階段最大的意義是能在不驚動(dòng)業(yè)務(wù)的前提下暴露問(wèn)題比如某些門店的容量約束被頻繁打破或者某些路線的配送時(shí)長(zhǎng)超過(guò)司機(jī)工作時(shí)長(zhǎng)?;販y(cè)跑通后我建議運(yùn)營(yíng)團(tuán)隊(duì)先選一個(gè)中等規(guī)模的門店簇做兩周的試運(yùn)行。試運(yùn)行期間系統(tǒng)輸出只作為建議方案每天由調(diào)度員進(jìn)行人工確認(rèn)。這里有一個(gè)經(jīng)驗(yàn)一定要記錄人工修改了哪些地方以及修改的原因。第一周人工修改率高達(dá)30%主要集中在對(duì)促銷臨時(shí)加量的調(diào)整上第二周隨著調(diào)度員對(duì)系統(tǒng)輸出風(fēng)格的熟悉修改率降到10%以下。這個(gè)“人機(jī)磨合”的過(guò)程必不可少直接跳過(guò)的話業(yè)務(wù)團(tuán)隊(duì)很難建立起對(duì)系統(tǒng)的信任。5. 常見(jiàn)問(wèn)題與排查實(shí)錄5.1 預(yù)測(cè)分布過(guò)窄導(dǎo)致場(chǎng)景多樣性不足第一個(gè)遇到的問(wèn)題是場(chǎng)景生成的需求路徑多樣性不足。癥狀很典型系統(tǒng)跑出來(lái)的方案總是傾向于少出車、小裝載量對(duì)峰值需求的準(zhǔn)備不足。排查后發(fā)現(xiàn)根因在預(yù)測(cè)模型輸出的分位數(shù)間距太小——模型對(duì)需求波動(dòng)估計(jì)不足把分布收窄了。這經(jīng)常發(fā)生在訓(xùn)練數(shù)據(jù)里方差被低估的情況下特別是我們用了梯度提升樹(shù)做分位數(shù)回歸如果葉節(jié)點(diǎn)最小樣本數(shù)設(shè)置得過(guò)大模型就會(huì)傾向于輸出比較保守、平滑的分位數(shù)尾部信息被抹掉。我的解決辦法是調(diào)低葉子節(jié)點(diǎn)最小樣本數(shù)提高分位數(shù)的靈敏度同時(shí)在損失函數(shù)里對(duì)尾部預(yù)測(cè)誤差加了額外權(quán)重讓模型更關(guān)注10%和90%分位數(shù)的擬合。5.2 優(yōu)化求解時(shí)間不穩(wěn)定多場(chǎng)景模型加上全量門店最怕的是求解時(shí)間爆炸。我遇到過(guò)幾次平時(shí)5分鐘出解某天突然跑了40分鐘還不停直接導(dǎo)致調(diào)度延誤。定位后發(fā)現(xiàn)問(wèn)題出在“壞場(chǎng)景”上——某些生成場(chǎng)景中需求極端偏高使得對(duì)應(yīng)的約束特別緊分支定界樹(shù)膨脹得厲害。解決思路有兩個(gè)層面。第一是在場(chǎng)景生成時(shí)做截尾把需求超過(guò)歷史最大值1.5倍的場(chǎng)景樣本直接裁剪到上限避免極端值拖慢求解。第二是在求解器參數(shù)上做調(diào)節(jié)設(shè)置MIP的節(jié)點(diǎn)數(shù)上限和求解時(shí)間上限到時(shí)間就返回當(dāng)前最優(yōu)可行解。實(shí)踐中第二個(gè)方案更可靠因?yàn)樗WC求解時(shí)間的上界。5.3 業(yè)務(wù)團(tuán)隊(duì)對(duì)“概率方案”的不信任技術(shù)問(wèn)題都好解決人心的問(wèn)題最難。業(yè)務(wù)調(diào)度員習(xí)慣了“今天送50件”這種明確的指令拿到“我應(yīng)該送40到70件取決于后續(xù)天氣和銷售走勢(shì)”這種帶區(qū)間的建議第一反應(yīng)往往是不信任。我的處理辦法很笨但有效做一次詳細(xì)的Case復(fù)盤(pán)。找兩個(gè)真實(shí)門店把系統(tǒng)輸出的場(chǎng)景集合和決策依據(jù)攤開(kāi)在桌面上講解釋為什么系統(tǒng)建議給A店多留庫(kù)存而給B店少送一些。當(dāng)業(yè)務(wù)人員看到系統(tǒng)在面對(duì)不確定需求時(shí)做的權(quán)衡邏輯跟老練調(diào)度員的思路一致時(shí)信任感就建立起來(lái)了。技術(shù)方案再先進(jìn)最終還是要靠人來(lái)用。交付一個(gè)“好用的系統(tǒng)”不只是交付模型和代碼還包括教會(huì)業(yè)務(wù)團(tuán)隊(duì)用概率思維做決策。5.4 模型再訓(xùn)練頻率與概念漂移零售需求的特征會(huì)隨時(shí)間緩慢變化季節(jié)性、新品引入、周邊商圈變遷都會(huì)導(dǎo)致需求分布漂移。如果模型長(zhǎng)期不更新預(yù)測(cè)分位數(shù)會(huì)越來(lái)越失真。我們?cè)O(shè)定的是每周增量訓(xùn)練一次每月做一次全量重訓(xùn)。增量訓(xùn)練用的是最近4周的新數(shù)據(jù)配合舊數(shù)據(jù)加權(quán)衰減讓模型既能捕捉近期趨勢(shì)又不會(huì)忘記歷史模式。這個(gè)頻率是我在幾次測(cè)試后確定的。兩周更新一次新品上市時(shí)的需求變化跟不上每天都更新訓(xùn)練資源和模型穩(wěn)定性又扛不住。以周為周期是比較折中的選擇也方便跟業(yè)務(wù)周會(huì)節(jié)奏對(duì)齊。6. 最后分享一點(diǎn)個(gè)人體會(huì)這套方案解決了一個(gè)我入行以來(lái)一直很糾結(jié)的問(wèn)題預(yù)測(cè)模型和優(yōu)化模型到底應(yīng)該怎么配合。過(guò)去做純預(yù)測(cè)項(xiàng)目模型再準(zhǔn)落到業(yè)務(wù)上總覺(jué)得使不上勁做純優(yōu)化項(xiàng)目模型再精巧輸入的需求數(shù)據(jù)一塌糊涂解出來(lái)的方案也只是紙上談兵。預(yù)測(cè)后優(yōu)化這類系統(tǒng)真正把兩個(gè)領(lǐng)域串在了一起。如果你也想在自己的供應(yīng)鏈場(chǎng)景里做類似的嘗試我的建議是先別追求復(fù)雜的聯(lián)合訓(xùn)練把基礎(chǔ)的分位數(shù)預(yù)測(cè)和多場(chǎng)景優(yōu)化做好就已經(jīng)能超過(guò)多數(shù)傳統(tǒng)方案。等到你對(duì)場(chǎng)景生成、求解穩(wěn)定性都有了手感再去探索更進(jìn)階的方向也不遲。我們目前還在做兩個(gè)后續(xù)擴(kuò)展一個(gè)是把門店的實(shí)時(shí)庫(kù)存數(shù)據(jù)接入場(chǎng)景生成讓優(yōu)化決策能響應(yīng)當(dāng)天的突發(fā)情況另一個(gè)是在場(chǎng)景層引入季節(jié)性外部變量比如節(jié)假日零售指數(shù)讓預(yù)測(cè)分布隨宏觀節(jié)奏動(dòng)態(tài)調(diào)整。這個(gè)方向可以延伸的東西還很多后面有新進(jìn)展再繼續(xù)更新。