--- tags: 'ML notes' --- # ML in Production **First rule in [Google’s 43 Rules of Machine Learning](https://developers.google.com/machine-learning/guides/rules-of-ml):** Don’t be afraid to launch a product without machine learning. ## Challenges ![](https://i.imgur.com/nXy9yph.png) 1. Unclear technical feasibility - 很難去評估一個AI系統實際運作的時候會發生甚麼問題 - EX : 很多公司都說他們的自駕車可信,但最終都會出現問題 2. Complex product specification - 難以確切的描述出在各種不同狀況下的可接受錯誤有多少,也難以去為一個AI系統寫出一個spec,因為可能造成錯誤的事件類型太多了 3. Need for data - 不只需要寫code,也需要存取資料。 - 針對小型客戶是可以從少數的資料開始,但面向商業的客戶則是早已自己有一個流程,要如何從中取得資料是一個很大的問題,而且通常難以放大Scale 4. Additional maintenance cost - boundary conditions 很模糊,不知道當系統偏差到什麼程度的時候會需要維護,很多時候要等到客戶反應才知道 - Resarch vs Production ![](https://i.imgur.com/sDX8LEA.jpg) ## Start with... - **Scatter plot** for visualizing numerical value - **box plots** for visualizing categorical value ### Heuristics - **Recommendations:** Recommend top-performing items from the previous period; can also be segmented by categories (e.g., genres, brands). If you have customer behavior, you can compute aggregated statistics on co-interactions to calculate item similarity for i2i recommendations (see Alibaba’s Swing Algorithm here). - **Product classification:** Regex-based rules on product titles. Here’s an example from Walmart’s product classifier (Section 4.5): If product title contains “ring”, “wedding band”, “diamond. *bridal”, etc., classify it in the ring category. - **Review spam identification:** Rules based on the count of reviews from the same IP, time the review was made (e.g., odd timing like 3 am), similarity (e.g., edit distance) between the current review and other reviews made on the same day. ## Work Flow of a production-ready model 1. produce a set of user stories 2. gather the data 3. verify the data 4. consider the ethics associated with deploying your model 5. leverage a range of dimensionality reduction techniques 6. model the data 7. evaluate the model 8. deploy model ![](https://i.imgur.com/VBn3Vru.png =400x400) ## Maintenance ### Problems [Understanding Dataset Shift](https://towardsdatascience.com/understanding-dataset-shift-f2a5a262a766) 1. **Data Drift** : 模型是用某一個分布的資料去訓練,但上線之後資料的分布改變了 - 比如因為氣候變遷而使得電力的需求遽變 - 可細分為 **Covariate shift** 和 **Prior probability shift**,前者是指 X 的分布改變,後者是指 Y 的分布改變 2. **Concept Drift** : 模型學習了 $x$ -> $y$,但上線之後 x 和 y 之間的關係改變了 - 比如因為通貨膨脹而使得原本利用住宅地址預測房價的模型失效 - 原因也可能是因為 Feature Drift,也就是有些 input variables 的分布隨著時間而改變,但模型沒有學到這樣的改變,而非真的是 Concept Drift,下面兩張圖是兩者的差別 - [Concept Drift](https://concept-drift.fastforwardlabs.com/) ![](https://i.imgur.com/BUj2CN2.jpg) - Feature Drift - Virtual Feature Drift 是指資料雖然改變了但卻沒有影響到模型判斷的根據 (Decision boundary) ![](https://i.imgur.com/oZYCQCY.jpg) 3. **Changing requirements** : 模型是為了某個 task 而建立的,但上線之後 task 的需求改變 - 比如原本是要偵測建築工人在危險區域是否沒有戴著工地帽(hard hat)超過5秒,但後來改成只要沒戴著超過3秒就要發出警告 >Data 和 Concept Drift 會因為 AI System 的 boundary conditions 很模糊而難以偵測 (因為輸入是一個資料分布而不是確切的有範圍的值 - Different types of Data Drift ![](https://i.imgur.com/LNJwgxO.jpg) [source](https://www.youtube.com/watch?v=7XCsi64HLQ8) ### 如何偵測與解決這三大問題 ? 1. 重新訓練 - 可參考[The Ultimate Guide to Model Retraining](https://mlinproduction.com/model-retraining/) 2. 利用一些工具去持續 monitoring model,比如 [AWS SageMaker Model Monitor](https://docs.aws.amazon.com/sagemaker/latest/dg/model-monitor.html), [Seldon](https://docs.seldon.io/projects/seldon-core/en/latest/analytics/analytics.html), [MLWatcher](https://github.com/anodot/MLWatcher) 3. 統計方法 : 利用統計的假設檢定來比較兩塊資料的分布是否有差 (distribution drift 是否發生) - $H_0$是D1=D2,Reject $H_0$則表示兩個資料所擷取出來的特徵分布不同 - 同時也可以假設 D2 的分布>> D1,如果接受這個假設就表示兩個資料分布的差距越來越大,如果拒絕則表示 D2 和 D1的差距正在縮小 (偵測 data drift 的嚴重程度) - **Kolmogorov-Smirnov (K-S) test:** 用以檢定兩個資料分布是否不同或一個資料分布與另一個理想分布是否不同 - **Population stability Index (PSI):** 用來偵測一個變數隨時間變化多少 (若 PSI >= 0.2就不該繼續使用現有模型了) - **Histogram intersection:** 比對兩個資料的分佈的相似性有多高來偵測 drift 4. 對特徵做更進一步操作 : Feature Removal, Importance Reweighting, Adversarial Search 5. Ensemble models 6. 其他方法 - [Machine Learning Model Drift Detection Via Weak Data Slices, IBM, 2021 Aug](https://arxiv.org/abs/2108.05319) 認為只要偵測出所謂的 Weak data slice 就可以看出 data drift 發生的徵兆 - Weak data slice 是指有一塊 data slice 的 misclassification rate (MCR) 比測試資料集的 MCR 還要高許多 - 他們認為假如只要出現了這種 Weak data slice 就表示 ML Model 的某一塊特徵空間出現了錯誤,而且這塊 data slice 越大,出現錯誤的可能性越高 ### Retrain or not retrain? [retrain or not retrain](https://evidentlyai.com/blog/retrain-or-not-retrain) > 根據不同的domain,model decay的速度會有所不同 - 下圖是工廠的製造 vs 消費者的購物相關模型,可見一年與一個月的差別 - 但 model decay 不能只用時間來衡量,工廠製造的批次、原物料的變動、社會新的風潮等等都會影響到模型 ![](https://i.imgur.com/GLII30D.png) - 其他例子 - Fraud dectection 需要考慮對抗式樣本 (Adversaries) 隨著時間會變化所造成的影響,比如可能會有人故意玩搜尋引擎的優化,可能就要有辦法去預測這種行為,來避免被這種人玩壞 - Real-time system 需要考慮 most-recent feedback,比如音樂推薦系統在使用者按下不喜歡之後就要馬上改變模型 - 但也未必要整個重新訓練模型,可以只重新平衡這個使用者的 preference matrix 的各個權重 #### Retrain model 帶來的壞處? 1. 額外的計算成本 2. 額外的系統複雜度 3. 容易出錯 4. 可能需要重新做一些驗證以及其他 stakeholders 的再次認可 簡單來說,如果模型沒壞,就不要硬要 retrain - 雖然是否要重新訓練這個議題是domain-specific,但還是有些通用的檢查方法 #### 1. Defining the retraining strategy in advance > How much data does the model need? - 有兩種測試 : rough one and more granular test Rough one - 個別只取一部分的資料來測 - 比如如果有五年的資料,你也未必要全部都用,可以只取一兩年的資料分別測試看看是不是就足夠了 ![](https://i.imgur.com/nGmPTnG.png) Granular one - 測試不同參數的模型在各種不同資料量級的表現藉此確認是否資料越多越好 ![](https://i.imgur.com/90568lX.png) 實驗步驟 1. 拿出 avaliable train set 2. 固定 test set 3. 選出 initial train set 4. 定義出每一步要增加多少train set 5. 開始持續增加 實驗結果會拿到一個 Data Quality 和 train size 的關係圖,可以藉此得到最好的 train size 是多少 - 有可能是已經找出 optimal train set的模型 ![](https://i.imgur.com/U5qSPPX.png) - 也有可能發現模型還可以繼續成長 ![](https://i.imgur.com/MFuCiKG.png) - 當然,需要注意的是這個評估模型的 metrics 要與跟 business metrics 有相關 - 但這樣的實驗其實只有回答了如何測試data要多少的問題,但沒有回答**how often to retrain the model**這個問題 #### 2. How quickly will the quality go down in production? - 持續的用較舊的資料訓練出模型,並且 apply 到新資料上,用來作為對照組 - 比對目前的模型跟舊模型就可以看出模型 decay 的時間大概有多長 (會得到所有時間點上的模型用在目前資料上的表現結果) ![](https://i.imgur.com/p52c9dQ.png) - 如果有足夠多的資料甚至可以重複這個過程好幾次,把結果平均起來得到更準確的結果 ![](https://i.imgur.com/aZ0YHsx.png) - 用這個方法的前提是 **模型訓練的方法要一樣**,也就是模型參數跟資料前處理要是一樣的,不然這些因素的影響可能會比 model decay 還大 結果分析 - 有些模型非常穩定,六個月前的模型和現在的模型一樣好 - 但有些模型卻 decay 的非常快速,這時可以採取下列三個方法來減緩 1. Make a model a bit "heavier" but more stable 讓模型更加笨重,但更穩定  - 用更多資料、用更多特徵工程 2. Make a model more dynamic - 取更短的時間去訓練但增加調整模型的次數,或是用 active learning 3. Address the model pitfalls separately - 模型可能對於某些 segment 特別表現不好,這時候可以把這些 segment 辨識出來,然後利用非 ML 方法或是 rule-based 去處理 透過過去的資料來評估model decay的速度並不能適用在所有情況下,因此 estimating past drift **NOT** always make sense ![](https://i.imgur.com/zRhoXti.jpg) 不能適用的情況 - 比如預測交通號誌圖片的辨識系統所遇到的問題是亮度不足以及有噪聲圖片的長尾問題,但實際上所要預測的交通號誌並不會改變,在這種情況下就不能使用過去資料來評估 - 另一個例子是 text model 的 update,比如辨識文件種類的模型,雖然會需要更新但並不是持續的更新而是有一個 update schedule 可以適用的情況 - 持續更新的模型,比如 consumer behavior, mobility patterns, or time series problems like electricity consumption #### 3. How often do you receive the new data? ![](https://i.imgur.com/M3gDg2y.png) - 有些時候資料並不是 real-time 或是 up-to-date 的,很有可能收到的是 delay 的資料來分析 - 比如在模型會在兩周內 degrade 但新資料是一個月才會拿到一次的時候 可能的解決辦法 : 1. 假如有部分的資料是可以提早拿到的,就建立多個有不同 update schedule 的模型 2. Hybrid model ensemble - 比如用 sales statistics and business rules 做為 baseline model,然後再利用 ML 來矯正其預測 - 有時這些 rule-based model 會在準備要更新資料之前表現得比 ML Model 更好 3. Rebuild the model to make it more stable - 建立更穩定的模型,把一點點的 test performance 用來犧牲以獲得更高的模型穩定性 4. Adjust the expectations - 如果這個模型的 up-to-date 並沒有那麼重要也可以對其做調整 ![](https://i.imgur.com/cczeWA2.jpg) **Retraining schedule 的結論 :** 情況一、追逐 Model quality - 如果 Model degrades 得比新資料進來的速度還快,那就在每一次有 large enough chunk of data arrives 的時候 retrain model 情況二、你有一串新的資料點 - 可以很快速的拿到新資料,但此時舊模型仍然表現很好,這時候就得決定 retrain 的頻率要更高還是更低 #### 4. How often should you retrain? ![](https://i.imgur.com/mXmz9OV.png) - 除了根據 model decay 以及新資料進來的時間來決定 retrain 的時機以外,還有一些分析方法可以幫助決定 - 例如下面這個方法,每周都增加一些資料來預測,觀察從甚麼時候開始model在test set上的quality開始改進 ![](https://i.imgur.com/3ERTvor.jpg) - 但當然有些情況是即使增加訓練資料也不會讓模型表現有甚麼變化 - 例如只用每天的資料去增加沒用,需要以每周的資料去增加 - 這通常是因為一些比較少見的事件累積了許多或是因為 seasonal patterns 而使得模型需要更多的資料去抓取到變化 - The realistic choice of training window might be smaller than it seems. ![](https://i.imgur.com/DcEUJuE.png) - 在決定 retrain 的時機的時候,可以考慮每一個 buckets 所帶來的改變以及 retraining 所帶來的成本和麻煩,在他們之間做出取捨 - 可以重複這個過程好幾次來確保獲得比較有 quality 的結果 #### Summing up 1. Plan for periodic retraining - 與其隨便選一個 retrain 週期,不如深入研究資料最佳的週期是多長 2. Monitor for actual performance - 持續觀察上線的模型,確保及時發現 model decay 3. Analyze - 不要直接重新訓練模型,而是可以好好研究舊模型的 performance 是如何變化的 ### Update or Remake model 原則上要盡量避免去修改模型架構 - 盡量使用 retrain 來對模型做更新 - 丟掉或是把舊資料的權重降低,並把新資料的權重提供,抑或是把舊資料中重複度較高的丟掉 - 不然就是對模型做調參實驗、改變 feature engineering、data post-processing 等等 - 總之想盡方法來改進目前模型來符合目前需求 ![](https://i.imgur.com/6ME0Enj.jpg) 假如真的到了需要改變模型架構的地步,要確保這可能是甚麼原因所造成的,將這些原因考慮進去來設計新的模型 - 分析某個 underperforming segments 的特性、資料的改變、特徵之間的 correlations, 模型錯誤的 patterns 等等 - 可能的根本原因像是消費者習慣的大改變、商業決策的改變、資料儲存流程的改變等等 ### Which test is the best? We compared 5 methods to detect data drift on large datasets https://evidentlyai.com/blog/data-drift-detection-large-datasets ## Depolyment ### Batch inference vs Online inference [Batch Inference vs Online Inference ](https://mlinproduction.com/batch-inference-vs-online-inference/) Batch inference 和 Online inference 是兩種用來 serving ML model 的方式,各有其優缺所在 #### Batch Inference - 又稱 offline inference 或 static inference - 從 a batch of observations (就是歷史資料)中產生出預測值 優勢 : 1. 對 Infra 需求較低、較為簡單 (REST API亦可做到),不必太擔心計算成本,也可用 Spark (MapReduce)之類的 big data tool 來加速模型推論,因為這些輸入資料都已經在資料庫之中了 2. 預測的結果也較能夠經過一些後處理(post process)來檢查正確性之後才呈現給使用者 挑戰 : 1. 無法做到 real-time 的預測,因此若有[長尾(long tail)](https://hackmd.io/2jE27_9LSuyehpCo8odrAw?view#Improving-ETA-Prediction-Accuracy-for-Long-tail-Events)情況就無法使用,因為面臨到長尾事件的時候會預測很差,無法預測我們不知道的事情 2. 無法處理 cold start 的情境 (完全沒有歷史資料),會需要建立更多模型去幫忙處理 (像是判斷跟這個使用者相似的使用者有哪些,利用這些相似使用者的資料去推薦) Usage : - 可以預先基於一群資料去做預測,將預測結果保存下來,當需要用到的時候直接拿出來用 ![](https://i.imgur.com/uxKvYAx.png) Tools : - [Apache Airflow](https://airflow.apache.org/docs/apache-airflow/stable/) - [K8s CronJobs](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) - [Perfect](https://docs.prefect.io/core/) #### Online Inference - 又稱 real time inference 或是 dynamic inference - 根據現在所接受到的 request 去 real-time 產生出預測 優勢 : - 可以 real-time 預測,UX 會很好,也可以處理 long tail 挑戰 : 1. 對 infra 需求高,因為收到 request 的瞬間就得馬上做推論,計算成本會很高,延遲不能太久(要在毫秒等級內做完) - 在幾十毫秒內得做完(1)擷取特徵 -> (2)跑模型 -> (3)驗證模型輸出 -> (4)把結果丟到網路上傳給使用者 3. 需要確保輸入的資料以及模型產生的結果他們的分布和訓練資料是相似的,也就是需要監測模型,否則可能會產生出不好的結果給使用者 (Model Shift) - Model shift 產生的話就得重新 train 模型 ![](https://i.imgur.com/reuOm7x.png) Usage : - DoorDash, Uber Eats 的 ETAs (預期抵達時間) - Self-driving car, 人臉辨識 App #### 如何選擇? Ask question about product : - 誰需要使用這個模型的推論結果 ? 需要多快呈現結果給他們 ? (who is using and how soon they need?) #### Examples - [Uber's Michelangelo](https://pooyanjamshidi.github.io/mls/lectures/mls03.pdf) ![](https://i.imgur.com/JSOHZp8.jpg) - Simple Flask API ```python= import logging from flask import Flask, request app = Flask(__name__) @app.route('/predict', methods=['POST']) def predict(): """Return a machine learning prediction.""" data = request.get_json() loginfo('Incoming data: {}'.format(data)) return {'prediction': None} @app.errorhandler(500) def server_error(e): logging.exception('An error occurred during a request.') return """ An internal error occurred: <pre>{}</pre> See logs for full stacktrace. """.format(e), 500 if __name__ == '__main__': app.run(host='127.0.0.1', port=8080, debug=True) ``` ## How DoorDash Do? DoorDash 是美國一家做食物外送平台的企業,我個人非常喜歡看它們寫的關於如何把 ML Model 應用在實際問題上的文章 這部分主要會翻譯我對於 [DoorDash Engineering Blog](https://doordash.engineering/) 的理解以及內容翻譯。 ### DoorDash' ML Platform [DoorDash’s ML Platform – The Beginning](https://doordash.engineering/2020/04/23/doordash-ml-platform-the-beginning/) 這篇基本介紹了一個 ML 平台應該要有什麼東西 #### Scenarios and Requirements DoorDash 總結他們在使用 ML Model 的時候會有三種使用場景 1. Online Models : 這種模型是實際存在在產品中的模型,與使用者體驗息息相關,因此會需要有較高的執行效率,比如預測食物準備時間、預測運送時間以及搜尋排名等等 2. Offline Mdoels : 這種模型雖然實際存在產品中,但並不在使用者的 request/response 之中,因此效能不會特別重要,但仍然需要讓他們的運算持續運行,像是需求與供給的預測 3. Exploratory models : 這裡就是不會真實運用到產品中的實驗模型 上面三種使用場景衍生出了下面三種對於 ML Platform 的需求 1. Standardizing ML frameworks : 保存一些 ML frameworks,像是LightGBM, XGBoost, Tensorflow, Pytorch 之類的 2. Model lifecycle : 支援 end-to-end 的觀察 model 的生命週期,有助於訓練模型、模型評估、[online shadow testing](https://microsoft.github.io/code-with-engineering-playbook/automated-testing/shadow-testing/) (模擬真實使用場景)、A/B Testing、 3. Features : 能夠儲存 features 的地方,分為 request-level features 和 environmental features 兩種,前者是根據客戶的要求所訂的特徵,比如像是一個訂單中有幾個餐點,後者則是接單當下的環境,比如像是一間餐廳的平均等待時間以及它在過去 30 分鐘內所接的訂單量 #### Pillars of the ML Platform 這四個是維持 ML Model 預測場景以及需求而出現的重要元件 1. Modeling library : 一個可用來訓練以及評估模型的 python library,可用在 prediction services 以及 offline model 中 2. Model Training Pipeline : 一個在工程師上傳到git repo 之後可以自動訓練模型並且在訓練完之後將模型儲存到 Model Store 中的 pipeline 3. Features Service : 用來幫忙抓取預測的時候所需要的特徵,要做到 feature computation, feature storage 和 feature serving 4. Prediction Service : 能夠載入模型、評估模型並從 feature store 中抓取特徵、產生預測 logs、支援 shadowing testing 和 A/B testing - DoorDash 完整的 ML Platform 圖 ![](https://i.imgur.com/ogHBYhB.jpg) ### 平衡 Supply 和 Demand [Managing Supply and Demand Balance Through Machine Learning](https://doordash.engineering/2021/06/29/managing-supply-and-demand-balance-through-machine-learning/) 這篇有些東西講得有點模糊,但整體而言還算有趣 #### 問題描述 以前在午餐、晚餐時間這種需求會飆高的時段,DoorDash會增加Dasher送餐所能獲得的錢,用這種方式來補足較多的需求,但實際上並不會向客戶收更多的錢,也就是說他們得自己負擔 由於尖峰時刻的需求很負責,他們建立了一個能預先預測供需不平衡的系統來幫他們做到 incentive allocation 這樣的系統會需要 1. 定義要用甚麼樣的metrics 和 project objectives 來明確衡量供需 2. 產生 high-fidelity forecasts 的供需預測 3. 在各種不同的限制之下制定出最好的incentive allocation方式 4. 管理不確定性 5. 增進系統的 reliability and maintainability ###### 如何定義供需與如何衡量? 對顧客來說 - **在需求尖端時缺乏Dasher送餐**是問題的核心 - 造成 order lateness, longer delivery times, or inability to request a delivery 對Dasher來說 - **缺少訂單**是問題的核心 對merchants (DoorDash) 來說 - **供應過少的Dasher**是問題的核心 - 造成 delayed deliveries, which typically results in cold food and a decreased reorder rate 因此在理想的情況下這樣的系統應該要去平衡 **delivery-level** 的供需而不是 **market-level** 的供需 - delivery-level 的平衡代表每一個顧客都至少有一個在最佳時間可以幫忙送餐的dasher - market-level 的平衡代表Dashers的數量和訂單數量是一樣的,但並不需要每一個顧客都有一個Dasher可以幫忙的 (不需要符合Delivery-level balance) 但 delivery-level 的平衡不夠實際,最後他們是使用market-level metrics 來平衡 --- 他們主要用來衡量供需的 metric 是 **number of hours required to make deliveries while keeping delivery durations low and Dasher busyness high**,也就是當Dasher很忙而運送時間很短的時候運送所需的小時數 - 用小時來衡量可以更好的結合各個區域的交通狀況和配料、食物準備情況 舉例說明:假設今天有一個地區,DoorDash預估每小時需要1000個Dasher來送餐才能滿足需求,但卻只能找到800個Dasher,有200個Dasher需要被補齊 - 這時系統會先算出Dasher們每一個小時和每一天的空閒時間有多少,作為可以運用的資源 - 不要直接將這兩個 metrics 混合成一天去評估,這會造成人為的 smoothing,比如說早餐時段的oversupplied,而晚餐時段的 undersupplied 會被誤認成整天都供需平衡 - 接下來會利用這個metrics來提供額外的固定獎金給在特定時段和特定區域送餐的Dasher,藉此達到供需平衡 #### 如何預測區域性的供需? 我們已經有 1. 衡量供需的metrics 2. 在特定時間與區域中可以運用的資源(Dasher數) 3. 為了平衡需求所採取的動作是甚麼 現在需要的是 1. 如何決定預測的詳細需求 (到底需要預測什麼) 2. 如何預測每一個市場的供需條件 ##### 決定預測的詳細需求 他們使用的是 LightGBM 來預測這一個多變數的回歸問題 這是因為他們的需求是 1. 支援 multivariate forecasting - 即使在有許多變數的情況下預測的精度也要足夠 2. 支援 extrapolation - 也就是即使用在一個新的城市、國家這樣沒有歷史資料的情況下也能夠work - population size, general traffic conditions, number of available merchants, climate, and geography 這些都可以用來告訴我們這個城市的 extrapolation 3. 支援 counterfactuals - 假設stakeholders好奇說如果把獎勵金提高或是下降的話會如何影響這個供給預測的模型的話,這個模型要有辦法做這件事情 - 這樣的功能不只是可以幫助我們預測會發生什麼,同時也能預估採取這個價格的獎勵金會造成多大的影響 - 在LightGBM中,counterfactuals可以透過改變不同的輸入來達成 4. Small dependency footprint - 也就是盡量不需要依賴太多第三方套件 - 依賴太多的話會造成升級上面的不方便、容易有資安漏洞、更多的相容性問題 5. Thriving community - 這個模型要有一個充滿熱情的社群去持續幫助改善這個模型 #### 利用ML去預測 ![](https://i.imgur.com/RvtKHwH.png) 首先單純從 Incentive 和 Dashers 們為了這個 incentive 而願意送餐的時間來看,看起來 Incentive 高到一個程度之後,Dashers 反而不願意送餐? 很明顯這種情況不合理,更有可能是漏了一些 confounding variable 沒有考慮到,比如當時可能是感恩節之類的,這時候 Dashers 們與其去送餐更願意待在家裡與家人一起過 這個例子就展現了處理資料的工程師能夠事先對於 data 有 domain knowledge 是多麼重要的一件事情  另外一個利用 ML Model 去預測真實資料的挑戰是 Model 所做出的預測必須要能夠符合真實世界的決策,預測得太準通常不是一個好想法 舉例來說,下圖是從一個 mean=100, std=25 的常態分配所抽樣出來的三個不同地區的每日需求量,也就是說這三個需求量有25%的變動量,接下來將這三個區域直接結合就變成了下一張圖。 ![](https://i.imgur.com/ESNqjzQ.png) ![](https://i.imgur.com/ZiYkAzR.png) 這個 Combined 的圖會變成 mean=300,但 std 卻不會因此變成 75,而是變成$\sqrt{3*25^2}=43.3$,變動只佔了 14.4 %,變動比例竟然因此而變少了 40% 左右 由此可見即使 data aggregations 有助於整體資料的預測,但卻會使得系統在因應變化時的處理更加沒有效率 (系統所能處理的變動變少會導致無法處理突然上升或下降的需求量) #### Choosing an optimizer 一般的 ML Model 只能做到根據input去準確的預測出output,這樣的 Model 比較沒辦法根據特定的 business constraints 而提供不同的結果,因此在這種情況下,MIP (Mixed-integer programming) 或是 RL-based 的模型會較為合適,而 DoorDash 所採用的是 MIP。 選擇 MIP 作為 optimizer 可以擁有客製化的目標函數,能夠根據各種不同商業上的需求去調整,也能在各種不同限制下去進行最佳化 他們使用了兩個 global 限制式 1. 永遠不在特定的時間以及地點中設定大於一個的 incentive 2. 這個 incentive 永遠不會超過他們的 finance 和 operations partners 所設定的最大預算 而其他的限制式就是當地所在的區域或是城市而有所不同,能有不同的預算設定或是一些為了排除掉某些時間、地區中 incentive 而設置的懲罰,抑或是根據不同的輸入而變動的 incentive 限制式 #### 處理不確定性 Dealing with uncertainty ##### 問題描述 處理不確定對於要在這種資源有限的情況下如何分配 incentives 的問題非常重要,下面他舉了一個A,B兩個城市的供需平衡例子來說明 ![](https://i.imgur.com/hELJ29y.png) 如果沒有把不確定考慮進去,Optimizer 會產生兩個問題 首先,它沒辦法了解**供需平衡是有可能會從極度的需求不足到極度的需求過多都有可能發生** - 如果根據平均值去預測的話,圖中的 A 會供給不足,而 B 則是輕微的供給過多。這種情況下 Optimizer 是沒辦法很好的最佳化 B 的,因為 B 的平均值分布非常廣泛 第二個問題是它遇到不確定性較高的預測時會過度的分配資源給這些不確定性高的地區。 - **在 Dashers 和訂單都很少的長尾區域中,不確定性就會特別高**。因為這些區域既多而且彼此之間的 variance 很大,如果不針對這些區域的不確定性個別處理的話,模型會分配過多的資源在長尾區域,導致 over-supply,並且分配過少的資源在 variance 較低的區域,導致其 under-supply。 ##### 如何解決? DoorDash 利用重新抽樣每小時之間的期望預測值來解決這個 variance 問題。也就是說他們測量了當下那個小時、那個地區有可能會造成 undersupply 的機率。 - 比如在上圖中,城市 B 就有34%的機率會 undersupply。當 undersupply 發的時候,如果可以預測 undersupply 所造成的影響有多大,就可以做出比 mean prediction 更準確的預測 #### Decoupling data dependency chains ML Model 在資料的來源持續變動的情況下通常不太可靠,雖然他們可以直接把多個 data sources 都直接串到 Model 中,但這樣的系統會非常的複雜而且缺乏可靠度。 他們希望能以簡單且可靠為目標去設計預測模型。 ![](https://i.imgur.com/JXHP87B.jpg) 他們做了兩件事情去確保模型的簡單與可靠 第一,把 data pipelines 根據所屬的 business domain 拆分 第二,移除中介的資料相依性(intermediary data dependencies) - 它們主要使用的資料來源都是 BI team 審查過的來源或是直接從其他產品中複製而來的資料,這樣就不會讓不同的 project 所需要的 ETL 造成 long dependency - 下圖是舉例說如果 E 是一個資料轉換,這個資料轉換就會經過很長的依賴鏈,假設 A~D 其中一個 fail 的話就會導致這個轉換直接失敗 ![](https://i.imgur.com/9LZWXmh.jpg) #### Focus on experimentation 如何測試系統已經是可維護的? 為了確定系統已經是可維護的,DoorDash 選擇直接改動或是建立新的實驗,來確定這些新的 feature 有在好好運作。假設這些新的 feature 很難測試的話就代表我們失敗了。 另一個代表系統失敗的象徵是當這個系統已經維持不變很長一段時間,比如說六個月 。這樣就表示他們建立了不會持續進步、構思以及實驗的系統。因此依賴於 CI/CD 來自動化檢查套件的相依性、測試以及增加文件等等算是必做的。 ### Improving ETA Prediction Accuracy for Long-tail Events [Improving ETA Prediction Accuracy for Long-tail Events](https://doordash.engineering/2021/04/28/improving-eta-prediction-accuracy-for-long-tail-events/) 這篇是在講說他們怎麼處理在預測食物預期時間的時候所遇上的長尾事件,寫得非常好 他們做了三件事情去處理不論是因為突然的交通問題、天氣因素等等所造成的預測不準確 1. 加入 real-time delivery duration signals 2. 加入能夠有效抓到長尾資訊的特徵 3. 設計客製化的 loss function 去預測食物的預期到達時間 #### Tail events and why they matter 長尾事件(Tail events)並不是 outliers,outliers 發生的機率通常小於 1%,但長尾事件發生的機率更高也更頻繁 比如說真實世界有許多現象都是下圖的 Right-skewed Disribution with tail events characterized by relatively high values,像是線上零售商在黑色星期五的時候交易量會突然爆增,而過完之後又突然驟降 ![](https://i.imgur.com/afcxxwi.jpg) #### Why tail events are worth predicting 雖然 Outliers 是有害的,但其源頭可能性過多難以預測,相對而言 tail events 的發生通常有某種規律性 ( 而且發生的機率大概是 5~10% ,大於 outliers許多 ),因此某種程度上是可預測的。 #### Why are tail events hard to predict? 即使 tail events 是規律發生的,但預測的難度還是很高。 預測難度高的主因有兩個 1. Lack of sufficient ground truth data - 長尾事件的發生會是case by case的,發生當下的情況、時間都有所不同,很難去學習到共通的特徵 - 舉例來說,線上零售商一年中只有很少假日的資料可以利用,即使有兩個也只有兩次,相對而言很難看出趨勢,尤其如果是新的線上零售商又更難 2. 很難取得跟 tail events 發生機率最有相關的 leading indicators。 - 舉例來說,一個客戶可能是為了某個派對或是團體而下一個很大的訂單,但DoorDash沒辦法事先知道這種事情 #### DoorDash ETAs and tail events DoorDash是如何計算estimated arrival times (ETAs)跟他們遇上的tail events 是甚麼? - Setting ETAs - 預測客戶下訂單之後到食物抵達之間所需的時間 - 但送餐的實際時間可能會因為各種原因而延遲,因而超出系統所預測的時間,這會影響到客戶心情 - 可是如果每次都多留一點時間,又會讓客戶直接決定不訂了 - 如何解決 ETAs 的問題 ? - 他們會盡量避免推薦食物給送餐時間會很久的客戶,讓他們的選擇變少 - 讓客戶面臨 Quality vs Speed 的取捨 - Tail events in the ETAs’ context 在 ETAs' context 下,tail events 是指送餐花了異常久的時間 其原因可能如下 : 1. 餐廳太忙 2. 交通堵塞 3. Dashers 不夠 4. 客戶的住處地址太難找 ![](https://i.imgur.com/tEenRy8.png) #### Improving ETA tail predictions 三個方法 1. Added real-time features 2. Utilized historical features 3. Used a custom loss function when large deviations occur 在這之前要先做好 feature engineering 來深入了解 business domain ,以便知道哪些訊號代表了 tail events 的發生,並且要利用這樣的資訊去 improve model learn 首先,建立 **north star metric**,也就是一個產品要使企業成功的關鍵指標 - 他們的指標是餐點有準時到達的比例,或是餐點的 ETA 在可容忍的 +/- margin of error 之下有到達 第二,把所有相關的特徵都列出來,思考如何去做出改變來 improve model - Historical features : 他們發現把 feature 做 bucketing 和 target-encoding 可以更準確的預測到 tail events - 舉例來說,有一個連續型的特徵叫 marketplace health metric (ranges 0-100),我們可以對其定義其值只要<10,就代表是由於供給不足所造成更長的送餐時間 - 他們利用 target-encoding 將其切分成幾個 bucket,並以每個 bucket 中所有資料的平均當成新的特徵 - 增加這一個特徵可以讓模型學習到"供給非常不夠的情況"與"更長的運送時間"之間有關係,而不是期望模型自己可以從這種相對稀少的情況去學習出這個 pattern - Real-time features : 建立一個 real-time feature 來找到影響送餐時間的 key leading indicators - 比如天氣、假日等等 - 可以避免模型需要考慮所有可能影響ETAs的資訊 - 而是只考慮那些他們所定義好的突發事件,當這些事件發生的時候就會對ETAs做調整,例如當一個地區突然下暴雨的時候就會把那個地區的ETAs都拉長 - Custom loss function : Using a quadratic loss function - 使用 MSE 可以更能抓到 deviations 很大的 tail events - 也就是說當這個事件不是那麼常發生的時候 ( the amount of relevant data is sparse ) ,最好要用 quadratic 的 loss function ![](https://i.imgur.com/V4rAZ9m.png) - 他們一開始是用 Quantile loss function,他可以很好的處理某個分位數的運送時間,但沒辦法處理好 tail events - 最後就改成 Asymmetric MSE loss function ![](https://i.imgur.com/rLQV6u7.png) - 除了 tail events 以外,asymmetic MSE loss 也可以更能表示 business trade-offs,比如說它能表示出一個遲到的送餐比一個早到的送餐還要糟糕幾倍 ($(1-\alpha)*\alpha$) asymmetric MSE loss more accurately and intuitively represented the business trade-offs we were facing. For example, by using this approach we need to explicitly state that a late delivery is X times worse than an early delivery (where X is equal to the following part of the equation above). #### Conclusion 1. Feature engineering 是最值得投資的處理 2. 把 loss function 改成更符合 business tradeoffs 會幫助很多 ### Ship to Production, Darkly: Moving Fast, Staying Safe with ML Deployments [Ship to Production, Darkly: Moving Fast, Staying Safe with ML Deployments](https://doordash.engineering/2022/03/08/ship-to-production-darkly-moving-fast-staying-safe-with-ml-deployments/) ## 6 Little-Known Challenges After Deploying Machine Learning [6 Little-Known Challenges After Deploying Machine Learning](https://eugeneyan.com/writing/challenges-after-deploying-machine-learning/?utm_source=convertkit&utm_medium=email&utm_campaign=EDS+%234%3A+Deliver+Sustainably+By+Being+Production-Aware%20-%203024421) 這篇談到的是在做完 ML Model 的 Deploy 之後會面臨到的挑戰 ### 1: Schemas Change When They Shouldn’t (& vice versa) - 不穩定的上游資料會極大的損害到 ML Model 的結果 - 舉例來說,有一個叫 gender 的 column,原本只有 male 跟 female 兩種可能值,但為了政治正確,後來增加了 Transgender, Other 和 Prefer not to say,同時也把 male 變成 Male,female 變成 Female。 - 這種非常簡單的轉換不僅模型沒辦法偵測到 (因為它並不是變成 NULL ),還會造成模型的失效,尤其在 gender 非常重要的應用上時更是,像是 customer segmentation, personalized recommenders 等等 - 如果是和其他人一起共用的data的話會造成使用資料上的限制,因為不能只考慮到 ML Model 的優化 - **Data leakage** 是指 label 混到 feature 之中,導致模型在 offline 時表現好,但 online 時表現差 - 舉例來說,為了預測病人的住院費用,預估的住院時間會是這個模型很重要的一個特徵,但如果有人直接改動了這個data,全部改為真實的住院時間的話,模型就會把這個特徵的權重變很大,也因此在 offline evalution 得到很好的結果,但在把模型上線的時候就會變得很差 ### 2: Unwanted Model Interactions (Internal & External) 這個問題有兩個層面 第一個是內部的問題,確切來說就是特徵過多,其中有一些 redundant feature 不僅會造成 data pipeline 需要花額外的成本,也會給模型增加不必要的複雜度,但我們卻很少重新地去評估特徵取捨 第二個是外部的問題,也就是模型與模型之間互相影響。 - 舉例來說,一個電商平台的首頁會有很多的 widget,並會有一個 overall ranker 利用 click-thru, conversion, revenue 等等來決定是否顯示各個 widget - 當你發現一個模型變差的時候會很難知道到底是你的模型本身變差還是別的模型影響到你的模型,又抑或是 widget's ranker 的演算法有改? ### 3: Infra & Codebase is Messy (read: Chaotic) >**Machine learning systems often have poor engineering practices** 這是因為 ML Systems 牽涉到的技術實在是太多了,比如你只是要取資料出來訓練,codebases 中可能就得使用到 Scala 和 Spark 來處理大數據,使用 Python 做機器學習,還有使用 SQL 來查找資料。 但不同的語言和 codebases 都會有不同的 infra 以及 skills 來支援他們。只要發展的時間拉長,他們的維護成本就會越來越高,想使用單一個語言去重寫也幾乎是不太可能的事情 除此之外,Configuration code is often messy or non-existent,這是因為在 ML System 中會有一些參數是去嘗試出來才知道的,比如超參數、分類問題的 threshold、歷史資料要取幾天來訓練等等 - 如果很不幸的你得把這些設定放到 production code 來增進模型的表現或是你用 MLFlow 來管理,那當 ML System 越長越大的時候,這些 config code 可能最後會比 ML code 還多 那要如何解決 config code 會越來越大的問題呢? 要如何確定這次的修改不會讓模型炸掉? 最後,還有 Infrastructure environments 可能不支援你所使用的開發環境的問題,比如 Spark 要到 2.3版 之後才支援 MLP 中的 rawPrediction,但若你的 Infra 不支援的話你也沒辦法用,要等到 Infra 去更新的話又可能得等上幾周 ### 4: Real-World Bias and Bad Guys Come Knocking 假如你的模型並不是線上即時更新的,在遇上 data drift 的時候就會表現得越來越差,也就是說現實中的資料與訓練資料漸漸變得完全不同 >**Real-world data is dynamic but your model is static** 另一個問題是模型與現實世界的 Feedback loops 會使得你無法從表現上觀察到問題 - 舉例來說,你有一個預測商店目前存貨量的模型,當存貨量過多的時候模型會得到懲罰,因此,模型永遠都會估算較低的存貨量,這樣就會進較少的貨,以避免存貨過多,但也因為這樣而導致商店永遠都會缺貨 - 可是實際上這個模型的確是很準確的 - 另一個例子,假設有一個排名系統,今天排在前面的商品得到了許多的關注,那明天他也會排在前面,後天也會排在前面,這樣無限循環下去只會造成新商品永遠都得不到流量 - 而且這種情況在訓練模型的時候很難發現 最後是對抗式模型(Adversaries),這種模型會嘗試詐騙你的模型,使其有利可圖 - 舉例來說,在排名系統中,有些賣家會用假商品或是低品質商品來取得高排名,甚至是他們自己去買自己的商品 - 這種對抗式模型會嘗試許多方法,並觀察哪一個對你的模型有用,以此來汙染你的資料,使你的排名模型效果變差 ### 5: Org Issues - Priorities Clash; Diffused Responsibility 這邊談的是組織內不同角色的互相影響與牽制 舉例來說,Data science team 會希望部屬最好的模型,而最好的模型通常會需要最大的計算量,反之,工程部門更希望系統更加穩定、耗費的資源不要這麼多以及其維護成本低,而商業部門則希望模型的結果能較快產出 因此在做一個 ML System 的時候不能只考慮到 Data scienece 的目標,而是**要集合許多 stakeholders 的需求,取出一個平衡出來** 除此之外,部門的不同也會造成開發協作的成本變高以及時間成本變多 假如今天要對產品加入一個新的 feature,通常會有以下的流程 1. data engineering 更新 data pipelines 和 feature store 2. data scientist 更新 ML code 並且跑 offline evaluation 3. engineer 把 code 部屬到系統中 4. quality assurance (QA) 測試系統 >“What one programmer can do in one month, two programmers can do in two months” - Frederick P. Brooks ### 6: With Users, You Have to Provide Customer Service 使用者越多,規模越大,機器學習產品的缺點就越容易被發現 舉例來說,Google 誤將人類標註為黑猩猩的事情,這事情發生後過去了兩年,他們仍然還是沒有發現問題在哪裡 假如你有10億個使用者,那麼0.001%的錯誤率也至少會有1千個使用者受到影響,因此**機器學習產品必須得提供一個 feedback 管道給客戶,讓你可以快速找到問題在哪裡** **使用者需要知道為甚麼 (People need to know why)** - 假如你有一個預測看病帳單的模型將客戶的價格預測成了平常的三倍但卻不告訴他為什麼,那不只會害人恐慌,也會造成不信任 - 造成這個三倍價格的可能原因太多,這個病是不是有併發症? 是不是因為他的身體狀態差? 是不是因為他有抽菸 ? .... **使用者在乎隱私以及他們的資料如何被使用 (People care about privacy and how their data is used)** - 使用者都希望自己可以控制自己的資料,不希望自己被資料追蹤 (比如廣告追蹤) - 所以應該**要讓使用者可以決定是否要提供資料給我們** - 歐洲的 GDPR 也因此而生 ## A Practical Guide to Maintaining Machine Learning in Production [A Practical Guide to Maintaining Machine Learning in Production](https://eugeneyan.com/writing/practical-guide-to-maintaining-machine-learning/) ### Monitor Training and Serving Data for Contamination ## Data platforms ### The Quick and Dirty Guide to Building Your Data Platform [The Quick and Dirty Guide to Building Your Data Platform](https://towardsdatascience.com/the-quick-and-dirty-guide-to-building-your-data-platform-2f21dc4b7c94) ### Apple’s Data Platform for ML [Apple's MLdp](https://medium.com/acing-ai/apples-data-platform-for-ml-665135ae6cc) ![](https://i.imgur.com/MGYJPUL.png) MLdp需要做到那些? - Client端方面,MLdp 提供 REST API 和 SDKs 讓客戶使用 - Server端方面,MLdp 提供 domain specific language (DSL)來作資料處理 MLdp會需要什麼功能? 1. **a basic conceptual data model**,描述資料如何從raw data被標註,且被標註之後放到哪裡 2. **A version control system**,確保ML Model的實驗是有reproducibility 的 (也就是說當下使用了哪些資料、特徵、模型參數以及訓練結果等等都得記錄下來以便重新做出結果) 3. **A data interface**,讓data team可以方便地使用資料以及與其他的資料處理系統做串接,也要能支援一些ML的framework 4. **A hybrid data store design**,不僅適合 streaming (continuous data injection with high concurrent updates) 也要適合 batch (slowly-changing curated data) 型態的資料 5. **A storage layout design**,要有資料的版控,要支援平行資料處理以便分散式訓練、方便資料查詢以及探索的indexing、也要有 streaming I/O 來支援 on devices 訓練以及在 data center 的訓練 6. **A distributed cache**,用來加速ML訓練 總之他們最後做出了 **Data model, Data interface, Storage, Data layout design 以及 distributed cache** 來滿足以上需求 ### Serve hundreds to thousands of ML models — architectures from industry [Serve hundreds to thousands of ML models — architectures from industry](https://towardsdatascience.com/serve-hundreds-to-thousands-of-ml-models-architectures-from-industry-bf3d9474d427) ![](https://i.imgur.com/1Nt01sU.png) #### Data Model 他們做了4個objects : dataset, annotation, split, and package - dataset 中提供 raw data - annotation 提供 label 或是描述 dataset 的 feature - split 提供 horizontal partitions of the foreign keys referencing its associated dataset 來分割成 train, test, val dataset - package 沒有實際作用,但提供了一個 higer-level 的抽象層來觀察 dataset, annotations 以及 splits 把 annotation 和 dataset 分開的好處是可以讓不同 ML Project 都有不同的 label 以及 split - split 就像資料庫中的 partial indexes,而 annotation 就像與這個 split 相關的 label 另一個好處則是可以比較方便更新label (Label can evolve) #### Data Interface ![](https://i.imgur.com/TfMImHY.png) 這邊提供了 1. high-level API,也就是 DSL 提供了 declarative programming - 對資料使用 SQL 做查詢以及做 feature engineering 2. low-level API,提供了 imperative programming - 和主要的ML框架整合以及提供 streaming I/O for client-side data processing 除此之外為了縮短client-side data access 到 data center 的時間,提供了 data center caching 給那些在 data center 訓練模型的團隊 因為他們發現 **ML 主要的時間都花在 feature engineering 上而非 training 上** #### Storage and Data Layout Design - 支援 streaming 和 batch 的 hybrid data store,可以讓 data curation stage 有很高的更新速度 以及在 training stage 有很高的 throughput reads - 支援 scale-up 的 scalable physical data layout - Partitioned indices (support efficient retrieval) that support dynamic range queries, point queries, and efficient streaming on-demand for distributed training. #### Distributed Cache 主要目的是縮短 data distance,因此提供了一個 transparent distributed cache in the data center collocated with the compute cluster of ML tasks 這個 cache 服務可以部署到任何一個 virtual cluster environment 上 ## A/A Testing and A/B Testing [A/A Test:商業實驗不能忘的前置動作](https://haosquare.com/aa-testing-before-ab-testing/) [A/B Testing](https://haosquare.com/ab-testing-peeking/) [Sequential A/B Testing](https://haosquare.com/sequential-ab-testing/) [How Not To Run an A/B Test](https://www.evanmiller.org/how-not-to-run-an-ab-test.html) [What to Do When the A/B Test Result Is Not Significant](https://towardsdatascience.com/what-to-do-when-a-b-test-result-is-not-significant-21e905ff9eba) ### A/A Testing A/A Testing 是用來檢驗 A/B Testing 的實驗流程本身是否有問題,實際做法是在比較產品版本一樣但使用者不一樣的樣本 A/A Testing 實驗流程(同A/B Testing): 1. 決定好要觀測的指標、建立假設 2. 設定參數:顯著水準與檢定力、最小期望指標差異、指標變異數 3. 依照參數 計算所需樣本數 4. 啟動實驗,隨機分配流量 5. 分析結果 ![](https://i.imgur.com/XE5o9q5.png) 假如結果發現兩樣本是不一樣的產品版本,可能代表 1. 實驗系統的流量分配邏輯有 Bug,不是真的隨機分配 2. 統計方法或假設有問題,偽陽性錯誤率會高於我們控制的顯著水準 ### A/B Testing (Split testing) - 用來測試兩種不同的產品版本哪個表現較好 - 一定要確保兩產品除了實驗組特性以外的事情都是一樣 - 不能"偷看"結果,比如明明要收集500個樣本才能做決策,但卻到收集200個樣本的時候就下判斷,這時候會大大提升偽陽性發生的機率 如何設定 Sample size ? [How many subjects are needed for an A/B test?](https://www.evanmiller.org/ab-testing/sample-size.html) - 舉例 : 若要將原本40%的次日留存率提升1%,則填入40和1,但需要注意下方的 Statistical power 代表有幾%的機率可以檢測到 A/B 組確實有差異,Significance Level 則是假如 A/B 組並沒有差異,但檢定卻因為隨機性而判定成有的機率 (偽陽性) ### A/B testing versus Multi-armed bandits https://adezb.medium.com/a-b-testing-versus-multi-armed-bandits-83aa992d1199 ## Causal Inference [Why data scientists should learn causal inference?](https://leihua-ye.medium.com/why-data-scientists-should-learn-causal-inference-a70c4ffb4809) [A Survey of Causal Inference Applications at Netflix](https://netflixtechblog.com/a-survey-of-causal-inference-applications-at-netflix-b62d25175e6f) - Causal Inference 有三種: Randomized Controlled Trials (RCT, aka. A/B testing), quasi-experimental designs 和 observational designs - A/B testing 有造成使用者不開心的風險 - [若有 user interference,A/B testing 可能會違反 Stable Unit Treatment Value Assumption (SUTVA)](https://towardsdatascience.com/how-user-interference-may-mess-up-your-a-b-tests-f29abfcfccf8) - 若短期內需要得到結果,不適合使用 A/B testing,因為 A/B 需要幾個月的時間