時效準確率提升之承運商路由網絡挖掘 | 得物技術

語言: CN / TW / HK

1引子

履約時長是電商的生命線,直接關係到用户的消費體驗。新華網[5]2022年雙十一的報告顯示,37.4%的受訪者希望次日達,29.91%希望當日達。相較於其他物品,受訪者對手機、電腦、數碼產品的物流時效要求更高,更希望當日或1-2天內能收到貨。
得物履約場景中,主要的階段包括倉庫內生產和第三方承運商配送。在用户支付時,得物會根據倉庫的生產情況和運配資源,給用户一個承諾時效。

1.1 為什麼要預測承運商的線路時效

在履約過程中,得物需要監控訂單的流轉,及時的發現可能超時的訂單(與和用户承諾時效相比),這裏包含倉庫生產的監控和三方配送的監控。在實際過程中我們發現:配送節點發生變更時,承運商給的預測偏保守的。下面例子中,到了營業部承運商才給到比較精準的預計送達時間,故在分揀中心使用承運商的預計送達時間容易出現誤報。

2323232.png

下圖是承運商接口返回的預計送達時效的寬鬆指數,可以看到在接近目的地時,承諾時效才比較準確。

64011.png

2承運商網絡是如何運作的

在構建承運商網絡之前,需要先了解承運商網絡是如何工作的。下面是從A網點到E網點的配送示意圖,分為以下內容:

(1)節點,包含的攬收和派送網點以及分揀中心。

(2)線路,包括幹線和支線。例如從網點到分揀中心屬於支線,從分揀中心到分揀中心屬於幹線。

(3)班次:承運商為了平衡成本和時效,會設置生產班次。到分揀中心之後,需要根據目的地進行分揀,當到達一定量的貨物之後,會從分揀中心出發,前往下一個節點。承運商在設置班次的時候,會考慮單量,兼顧運輸的成本以及時效。

64012.png

上圖中:以紫色為例,在A網點,早上8點截單,即8點之前交接給承運商的貨物,會在8點20左右完成封車,然後從網點出發,前往B分揀中心,到達B分揀中心的時間是11點40,這個時候趕上了B分揀中心截單時間為12點的班次,B分揀中心會在12:30完成分揀並前往下一個分揀中心,以此類推完成整個配送過程。

在構建承運商的網絡時,需要進行建模。除了節點、線路和班次之外,核心還包括以下兩個模型:

(5)成品線,即從A網點到E網點經過所有節點。上圖中:A網點-B分揀中心-C分揀中心-D分揀中心-E網點構成了一條成品線。

(6)成品線波次:因為節點存在波次,所以成品線也存在波次,實際上成品線波次和第一個節點的波次數一樣。

3如何構建承運商網絡

在瞭解承運商網絡如何工作後,需要着手構建承運商的網絡。承運商回將軌跡信息推送到得物,內容類似以下的文本。

[
    {
"code":"180",
"desc":"快件到達【xxx營業部】",
"location":{
"city":"xxx市",
"district":"xxx縣",
"point":{
"latitude":xxx,
"longitude":xxx
            },
"province":"xxx"
        },
"node":"已攬收",
"opeTitle":"站點裝箱",
"time":"2022-09-04 17:29:27"
    },
    {
"code":"xxx",
"desc":"收取快件",
"location":{
"city":"xxx",
"district":"xxx",
"point":{
"latitude":28.65,
"longitude":120.07
            },
"province":"xx"
        },
"node":"已攬收",
"opeTitle":"配送員完成攬收",
"time":"2022-09-04 17:29:27"
    }
]

3.1 結構化清洗

軌跡的文本,需要經過結構化的清洗之後,才能獲取軌跡的含義。對於每一個運單,它的軌跡會經過很多個節點,而每個節點的數據類型如下:

1. waybill_no 表示運單號,同一個運單號會有多條節點記錄
2. station_index 表示當前這個節點的下標
3. station_enum 表示這個節點的類型,是分揀中心還是攬派網點
4. station_name 表示節點的名稱,例如上面例子裏的xxx營業部
5. station_status 表示這個節點的狀態,例如是進入還是離開
6. operate_time 表示當前節點的操作時間

3.2 軌跡裏面是否真的有班次信息

承運商網絡工作原理提到了承運商會按班次進行生產,從軌跡的結果裏面是否能找到班次生產的證據呢。通過分析,我們猜想:相同流向(例如從A分揀中心開往B分揀中心)離開某個分揀中心(例如離開A分揀中心)的時間應該是相對集中的。
實時上通過一些簡單的聚類方法,證實了我們的猜想。下面圖中,橫軸表示的是出分揀中心的小時,每一個點表示歷史上的某一個運單,縱軸沒有業務含義,只是為了方便顯示。

64013.png

繪製上述圖時使用的是kmeans聚類算法,kmeans聚類算法需要指定聚類的個數。故需要使用Knee/Elbow 這類的算法進行聚類數檢測,同時它對異常值敏感,故在實現時最終使用的DBSCAN。

64014.png

3.3 聚類參數該如何選取

DBSCAN雖然不需要指定聚類的個數,但是需要指定點之間的距離以及點的密度,通過反覆調整,最終確定這兩個核心的參數如下:

clustering = DBSCAN(eps=0.25, min_samples=max(5, int(x.size * 0.02)), metric=metric).fit(x_after_reshape)

其中eps為0.25,即15分鐘。點密度為5和總數的2%的最大值。

3.4 如何解決跨天的問題

從上面聚類圖看,同一個波次的點可能出現跨天的情況,即有些點出分撥中心的時間可能是23:50,有些分撥中心的點可能是00:10。這兩個點的歐式距離比較大,故需要重寫距離的metrics函數。

ret = abs(x[0] - y[0])
if ret > 12:
ret = abs(24 - ret)
return ret

3.5 線路是如何串聯的

分析節點的生產班次和線路的班次是不夠的,還需要將它們進行串聯,得到成品線班次,這樣才能在售前或者售中進行應用。這裏在處理的時候進行了一些簡化,一方面是分揀中心的分揀波次是沒有辦法識別到的,另外一方面其實可以不用關注分揀中心的分揀波次。
實際上,串聯成品線班次的過程是這樣的:

640.jpg
核心的代碼如下:

    List<NetworkResourceWaveDTO>
next = tmp.getResourceList().get(i)
            .getWaveList();
next.sort(Comparator.comparing(NetworkResourceWaveDTO::getOffTime));
    boolean match = false;
for (NetworkResourceWaveDTO nextWave : next) {
if (nextWave.getOffTime() > p.getEndTime()) {
            match = true;
            duration += nextWave.getDurationDay();
            p = nextWave;
break;
        }
    }
if (!match) {
        duration += next.get(0).getDurationDay() + 1;
        p = next.get(0);
    }
    productLineWave.add(p);
}

3.6 四級地址與攬派網點的關係是如何建立的

從應用的角度,輸入條件是買家的四級地址,但承運商網絡的終點是派送站點,故需要建立承運商派送站點和四級地址的映射關係。映射關係的建立比較簡單,取過去一段時間負責派送該四級地址的站點中,派送該地址單量最多的那個。

4工程落地的挑戰

Part 3更像是一個理論家的滔滔不絕,那如何在工程上進行落地呢?這裏麪包含了ODPS SQL的開發、UDF的開發以及DDD,總之需要十八般武藝。

4.1 如何在ODPS進行簡單的機器學習

在班次分析的過程中,使用到DBSCAN的聚類算法。如果在odps上使用這些算法呢?實際上python裏面已經實現了DBSCAN算法,而odps支持使用python編寫UDF。只是目前odps的運行環境並沒有安裝DBSCAN相關的包,故需要手動進行安裝,安裝的教程可以參考阿里雲的官方文檔
64015.png

4.2 在線服務化的問題

上述清洗過程需要每天或者至少一週運行一次,選取過去一個時間窗口的數據進行訓練,得到承運商的網絡,這樣才能及時的感知承運商網絡的變化。這意味着會定時的更新成品線、成品線波次以及節點波次的信息,在在線服務化的過程中,我們是直接將數據這些數據存放在redis裏面。為了不佔用太多的內存,通過使用hash數據結構對內存進行了一些優化,當然hash的一個缺點是無法為field設置超時時間,這意味着某個key的某個field數據實際已經是過期數據了,但是它不會被刪除,進而造成泄漏,但這種泄漏可以通過其他技術手段解決。

5進展與規劃

目前我們已經構建了第三方承運商網絡,首網點預測的準確率在65%左右,末分揀預測的準確率在85%左右。未來持續優化點包括:班次聚合(對於一些數據比較稀疏線路,需要做班次的聚合)、時間衰減(清洗數據需要選取過去一段時間的數據,對於太久遠的數據,應該進行衰減,使得它在結果中的貢獻小一些)等,相信準確率能有進一步提升。

64016.png

64017.png

6參考文獻

[1]. Knee/Elbow Point Detection
[2]. arvkevi/kneed
[3].https://datascience.stackexchange.com/questions/46106/kmeans-vs-dbscan
[4]. https://redis.io/docs/management/optimization/memory-optimization/
[5]. 用户調研:今年11.11消費者最關注“確定性” 京東是八成用户首選-新華每日電訊