設計檔案在軟體開發和機器學習專案中扮演著至關重要的角色,但常常被誤解為僅適用於大型企業或複雜專案。然而,無論專案規模大小,設計檔案都能幫助團隊釐清目標、預先發現潛在問題,並確保所有成員對專案有一致的理解。撰寫設計檔案的過程本身就是一個深入思考和規劃的過程,有助於團隊在專案早期階段發現並解決問題,避免後期耗費大量資源進行修正。良好的設計檔案應具備靈活性,可根據專案需求調整範本和內容,其目標並非直接佈署系統,而是提供一個可行的設計方案,作為後續開發的基礎。
常見的設計檔案誤解
在軟體開發和機器學習工程領域,設計檔案的撰寫是一項重要的步驟。然而,許多人對設計檔案的理解存在誤解。本章將探討這些常見的誤解,並介紹如何撰寫有效的設計檔案。
誤解1:設計檔案只適用於大公司
許多人認為設計檔案只適用於大型企業,而對於新創公司或小型團隊來說並不重要。然而,這種看法是錯誤的。設計檔案的價值在於揭示計畫中的盲點,無論是產品還是技術層面。這對於任何規模的團隊都是有益的。即使是小型團隊,也可以透過簡短的設計檔案來確保所有成員對計畫有相同的理解。
撰寫設計檔案的過程可以幫助團隊發現潛在的問題,並在中期節省大量的資源。對於新創公司來說,這種規劃過程尤其重要,因為它們需要在快速變化的環境中做出正確的決策。
誤解2:設計檔案只適用於複雜專案
另一個常見的誤解是設計檔案只適用於複雜的大型專案。然而,即使是簡單的專案,也可以從設計檔案中受益。一個結構良好的設計檔案可以幫助團隊識別潛在的風險,並防止專案範圍的擴散。
內容解密:
- 簡單專案同樣需要設計檔案來確保專案的順利進行。
- 設計檔案可以幫助團隊保持對專案目標的一致理解。
誤解3:設計檔案必須遵循固定的範本
許多公司,尤其是大型企業,會使用固定的範本來撰寫設計檔案。然而,這種做法可能會限制團隊的創造力和靈活性。我們建議保持範本的簡潔,並根據具體的需求進行調整。
內容解密:
- 範本應該是靈活的,而不是僵化的。
- 根據專案的需求調整範本的內容和結構。
誤解4:設計檔案必須導致系統佈署
最後一個誤解是設計檔案必須導致系統的佈署。事實上,設計檔案的目的是幫助團隊規劃和完善專案,而不是直接導致系統的佈署。就像工程師需要藍圖來建造機器一樣,設計檔案是規劃和迭代的過程,最終才會導致系統的佈署。
內容解密:
- 設計檔案是一個迭代的過程,需要不斷的修訂和改進。
- 最終目標是產生一個可行的設計方案,而不是直接佈署系統。
內容解密:
- 圖表展示了一個專案從開始到結束的流程。
- 每個步驟都是專案成功的關鍵環節。
設計檔案的目標與反目標
在設計機器學習(ML)系統時,同樣適用於一般系統設計的原則。一個ML系統是一個高度複雜的機器,由多個相互連線的領域組成,需要在實施前進行徹底的準備,通常設計檔案會經過多次迭代。儘管如此,好的設計檔案往往導致沒有實際的ML專案被啟動。
這看起來很荒謬,但讓我們設想你面臨兩個選擇:
- 花6個月時間不斷地研究模型、特徵、損失函式和資料集,最終卻將專案擱置(大多數ML專案最終都這樣)
- 花2到4週時間試圖描述
- 為什麼要進行這個專案?
- 我們如何進行?
- 我們是否具備所需的一切?
- 我們能否以較少的努力獲得較低效率的解決方案?
- 預期的結果是否可實作?
意識到90%的結果可以透過兩個IF陳述式得出可能會令人沮喪,但這仍然比第一個選擇要好得多。
目標與反目標的設定
設計檔案的其中一個目標是透過設定根本和邊界來減少對問題的不確定性。在檔案起草之前,對問題和解決方案的理解程度很低,且所有相關方的理解不一致。有一種技術可以幫助解決這個問題,即使用反目標——反向陳述,可以幫助我們縮小問題空間和解決方案空間。
設計檔案的每個部分都可以被視為對多個問題的答案:潛在系統的目標是什麼,關鍵的成功標準是什麼,我們應該關注哪些技術方面,如何解決給定的子問題等。一個新手錯誤是忽略權衡並列出無盡的系統目標:例如,它應該做X、Y和Z;具有高效能;精確;易於維護且開發成本低廉;並且直觀易懂。顯然,成功地將所有好的屬性融入一個系統是不可能的,你需要一種方法來抵消這種可能過度的情況。
設定反目標使我們能夠剔除那些我們並不真正關心的方面,並進一步突出我們認為至關重要的方面。假設我們正在建立一個內部使用的系統,輸出結果是各種報告,供執行團隊和分析師閱讀。我們可以一開始就假設處理時間對於這樣的系統並不是關鍵——只需使其運作速度足夠快,以便在早上準備好報告即可。因此,「處理時間」將成為反目標列表中的第一項,這樣我們就不會為此引數而煩惱。又或者,設想為一家精品店建立推薦引擎:如果你目前的商品數量只有三位數,那麼你肯定不需要支援數百萬件商品(見圖4.1),這意味著過度的生產力對於最終解決方案來說是不可接受的。
此圖示說明精品店由於商品數量有限,不需要在推薦引擎設計上過度追求擴充套件性。
像這樣設定反目標有助於我們只專注於重要的方面,並放棄那些對達成主要目標沒有正面影響的方面。
以下範例展示了精品店推薦引擎的目標和反目標列表可能是什麼樣子:
- 目標:
- 提高從檢視到加入購物籃的轉換率
- 為使用者提供多樣化的推薦
- 為使用者提供低延遲的體驗
- 反目標:
- 在處理商品數量方面的擴充套件性
- 在並發使用者方面的擴充套件性
- 對新商品類別的支援
同樣的邏輯也適用於設計檔案的其他部分。如果你在形成實施方案後意識到它有內在的關鍵缺陷,那麼在檔案中提及這個問題作為反例是有意義的。假設你正在設計一個可擴充套件的系統,並考慮大量使用雲端基礎設施,直到你瞭解到最大的潛在客戶由於隱私原因對使用自己的硬體有嚴格限制。在這種情況下,像「雲端解決方案X可能是資料儲存的好選擇,但由於Y的雲端隱私限制而不適用於此情況」這樣的一句話,可以設定重要的限制,並可能引發關於替代技術實施方案的想法:「如果X在技術上是可行的,那麼是否有可以在我們自己的伺服器上安裝的開源X替代方案?」
內容解密:
上述段落強調了在設計檔案中設定目標和反目標的重要性。透過明確目標,我們可以專注於真正需要解決的問題;透過設定反目標,我們可以避免不必要的複雜性和資源浪費。正確地設定目標和反目標,可以幫助團隊更有效地工作,並確保最終的解決方案符合實際需求。
不明確的目標對最終結果的影響
我們有兩個故事來突出不明確的目標設定如何影響ML系統的開發。
2016年,Valerii 在一家大銀行的催收部門工作。當時,銀行的管理階層決定將ML引入日常業務中,並依靠演算法支援而不是操作一套僵化的規則和直覺。Valerii 的第一個任務之一是建立一個模型,用於挑選下一個需要聯絡的使用者,以最大化輸出——即可以透過激勵措施(承諾付款、減免費用、折扣)啟用的使用者。現有的流程涉及大量手動工作,產出轉換率約為50%。新的流程涉及在約100個工程特徵上建立一個相當基本的非線性模型,在接下來的2個月內測試結果驚人地好,轉換率達到80%,而舊流程仍保持在50%。
團隊很高興並興奮地向高階副執行長展示結果。但在我們完成簡報後,她立刻問道:「這些客戶有什麼特別之處?我想要了解他們的動機。」在2016年,使用具有100個特徵的非線性模型來回答這樣的問題並不容易,更不用說人們做某件事的原因與他們實際做的事是完全不同的。例如,從一開始,高階副執行長的目標是瞭解為什麼,而業務的目標是瞭解誰。因此,團隊必須完全不同地設計系統和模型,以同時回答這兩個問題,即使這樣做效率較低。因此,一開始的不好的(或不合適的)目標使團隊倒退了3個月。
第二個例子涉及我們在第2章討論過的定價演算法。一開始,我們的目標是根據周轉率最大化總商品交易量,同時保持利潤率在給定的水平。
在某個時候,模型找到了一種聰明的方法來實作這個目標。產品目錄中有一個音箱,模型開始以低於進貨價的價格出售。結果,在24小時內銷售的音箱數量超過了之前90天的總和。公平地說,這仍然在利潤率限制之內,因為我們的任務並不介意利潤率為負。
然而,你可以想像這與我們真正想要的結果完全不同(正確的目標應該是增加收入同時保持利潤率,影響X%類別中的Y%的SKU,且掠奪性定價不超過Z)。當然,收入增加了,利潤率也保持在給定的限制內,但最終,大家只是跑去買那個特定的型號。沒有其他音箱被購買。
幸運的是,這只是一個小規模物品動態定價的測試釋出,顯示最初的目標設計得很糟糕,我們需要開發出一種更徹底的方法來進行目標設定。幸運的是,整體設計是解耦的,易於調整。
內容解密:
上述兩個故事說明瞭不明確或不適當的目標可能導致專案方向錯誤或無效。第一個故事中,團隊最初關注的是提高轉換率,但管理階層真正關心的是客戶動機,這導致了方向上的偏差。第二個故事中,定價演算法達到了最初設定的目標,但最終結果卻與預期不符,因為它沒有考慮到實際業務需求和潛在後果。這兩個例子都強調了在專案開始時明確和適當地設定目標的重要性,以確保專案走在正確的方向上,並最終達成預期的結果。
設計檔案結構
在討論機器學習(ML)系統的設計檔案時,我們不會遵循傳統軟體開發中的做法。實際上,不同公司對於設計檔案的結構有不同的要求,因此我們不會探討格式的細節。相反,我們將重點放在設計檔案中需要涵蓋的關鍵內容。此外,本文的目標是將設計檔案作為ML系統設計的一部分進行介紹。從本文開始,每章末尾都會有一個實務區塊,代表設計檔案的一部分,這些內容將結合理論與實際案例,提供解決實際問題的方法。
在本文中,我們將介紹兩個虛構案例,每個案例都有其特定的特點、問題和背景。這兩個案例將成為兩份不同設計檔案的基礎,並隨著章節的推進逐漸增加深度和複雜度。最終,我們將得到兩份完整的設計檔案。
首先,我們開始為一個專案概述設計檔案,就像在現實生活中所寫的那樣。為此,我們虛構了一家名為Supermegaretail的零售公司,該公司正在開展一個需求預測專案。
Supermegaretail 需求預測專案設計檔案
問題定義
起源
Supermegaretail是一家在不同國家和地區經營數千家商店的零售連鎖店。該連鎖店的顧客購買各種商品,主要包括食品、日用品、個人護理產品、運動補充劑等。
為了銷售這些商品,Supermegaretail必須在將它們送到商店之前採購或生產它們。採購的商品數量是需要定義的關鍵數字,這裡有不同的可能場景。
為了簡化計算,我們假設Supermegaretail為某家特定商店購買了1,000單位的商品A:
最佳情況:Supermegaretail購買了1,000單位,並在下一次交貨前售出了999單位。僅剩0.1%的庫存,使零售商接近最佳收入和利潤。
糟糕情況:Supermegaretail購買了1,000單位,但只售出了100單位。這種情況通常很糟糕,因為庫存過多導致損失巨大。
更糟情況:Supermegaretail購買了1,000單位,並恰好售出了1,000單位。這被視為一種更糟的情況,因為我們不知道如果有更多的庫存,顧客是否會購買更多。缺貨的情況使我們無法準確瞭解市場需求,甚至可能驅使顧客轉向競爭對手。
此外,Supermegaretail有大量的易腐食品,不能長時間存放在貨架上:它們要麼被售出,要麼變成浪費。
該專案的目標是盡可能縮小交貨量與銷售量之間的差距,同時避免缺貨情況,並達成特定的服務水平協定(SLA)。為此,我們計劃利用ML系統預測特定商店在特定時期內對特定商品的需求。
相關性和原因
本文透過探索性資料分析來強調問題的相關性。
現有流程分析
目前,Supermegaretail的訂貨、交貨和銷售流程是如何運作的?
對於Supermegaretail,可能的清單如下:
與製造商簽訂合約的規劃期限:為期1年的合約,在前9個月內可於90天前進行調整。
額外折扣與增加銷量的關係:每增加2,000萬美元的採購額,可獲得額外2%的折扣。
作為物流樞紐的分銷中心數量:全國有47個分銷中心,它們是物流樞紐,也是預測的匯總實體。
分銷中心與商店之間的交貨頻率:通常每2天,就有一輛卡車連線分銷中心和商店。
店內倉函式庫的存在或缺失:大多數商店內沒有倉函式庫。然而,卸貨區可以有效地用於存放卸下的商品2到3天。
誰在何時決定交付什麼以及交付到哪裡?:分銷中心會制定交付計劃,商店經理可以覆寫和調整該計劃。
內容解密:
此段落詳細闡述了Supermegaretail的需求預測專案背景和現有流程,包括採購、銷售、庫存管理等方面的挑戰和目標。透過對現有流程的分析,我們能夠更好地理解如何利用ML系統來最佳化需求預測,從而減少交貨量與銷售量之間的差距,避免缺貨情況,並提高整體營運效率。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title 設計檔案撰寫流程與誤區
package "常見誤解" {
component [僅適用大公司] as myth1
component [僅適用複雜專案] as myth2
component [固定範本限制] as myth3
component [必須導致佈署] as myth4
}
package "設計檔案價值" {
component [揭示專案盲點] as blind
component [統一團隊理解] as align
component [預先發現問題] as discover
component [節省開發資源] as save
}
package "目標與反目標" {
component [設定專案目標] as goal
component [定義反目標] as anti
component [縮小問題空間] as narrow
component [突出關鍵要素] as highlight
}
}
collect --> clean : 原始資料
clean --> feature : 乾淨資料
feature --> select : 特徵向量
select --> tune : 基礎模型
tune --> cv : 最佳參數
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型
note right of feature
特徵工程包含:
- 特徵選擇
- 特徵轉換
- 降維處理
end note
note right of eval
評估指標:
- 準確率/召回率
- F1 Score
- AUC-ROC
end note
@enduml
此圖示展示了Supermegaretail需求預測專案的主要組成部分和目標,包括利用ML系統來最佳化需求預測,以減少交貨量與銷售量之間的差距,避免缺貨情況。
設計檔案的審查與撰寫
在進行機器學習(ML)系統設計時,撰寫一份完整的設計檔案至關重要。這份檔案不僅能夠幫助團隊成員瞭解專案的整體架構和目標,也能夠在實施過程中提供清晰的指引。
預報視野與業務相關部門
在需求預測的場景中,預報的視野可以是一週、一月,甚至是一年。不同的業務部門,如物流、採購和營運部門,都與需求預測息息相關。
損失計算
計算預測需求與實際需求之間的差距所帶來的損失是評估改善需求預測的重要步驟。損失主要來自於庫存過剩和斷貨兩方面。雖然計算庫存過剩的損失相對直接,但斷貨所帶來的損失則較難量化,通常需要透過A/B測試或專家意見來估算。
內容解密:
- 斷貨損失的計算通常依賴於歷史資料和專家經驗。
- 透過A/B測試,可以比較不同預測策略下的銷售資料,從而評估斷貨的真實損失。
- Supermegaretail 的初步計算顯示,去年的損失約為8億美元。
風險與挑戰
在開發新的需求預測系統時,需要考慮多種風險和挑戰,包括:
- 現有的預測方法是否已經足夠有效?
- 是否能夠快速改善現有的解決方案,還是需要全新開發?
- 新方案是否會對現有的業務流程產生負面影響?
內容解密:
- 評估現有預測方法的優缺點有助於決定是否需要新的解決方案。
- 考慮不同類別商品的預測準確度差異,可以採用混合方法,先針對問題較大的類別進行改善。
- 需要進行廣泛的資料分析,以瞭解現有方案的限制和潛在改進空間。
設計檔案的審查
審查設計檔案是一個重要的過程,可以確保檔案的完整性和可行性。作為審查者,需要:
- 瞭解檔案的整體結構和內容。
- 對檔案中不明確或存疑的部分提出疑問。
- 提供建設性的反饋和替代方案。
內容解密:
- 鼓勵審查者提出不同的觀點和意見,有助於完善設計方案。
- 需要理解每位審查者提出的建議背後的理由。
- 「看起來不錯」這種模糊的反饋作用有限,需要具體指出問題和改進方向。
審查設計檔案的重要性與實務
在技術開發過程中,審查設計檔案是一項至關重要的步驟。良好的設計檔案審查不僅能夠確保專案的成功實施,還能夠提前發現潛在問題,從而避免後續的修改成本和風險。
設計檔案審查例項分析
案例背景:PhotoStock Inc.
PhotoStock Inc.是一家專門提供庫存照片的公司,該公司的主要業務是為客戶提供高品質的圖片搜尋服務。為了提升搜尋體驗,公司決定開發一個現代化的搜尋工具,以提高客戶滿意度和購買轉換率。
初步設計檔案審查
在初步的設計檔案中,團隊提出了以下幾個關鍵問題和目標:
現有搜尋引擎的問題:目前的搜尋引擎根據模糊搜尋演算法,使用Elasticsearch作為搜尋引擎,但其索引僅在每週一晚上更新。許多使用者對搜尋結果不滿意,導致搜尋到購買的轉換率偏低。
評審建議:提供更詳細的使用者資料和相關報表連結,以佐證搜尋引擎的問題。同時,應進一步分析搜尋結果相關性對轉換率的影響。
目標設定:計劃將搜尋到購買的轉換率提高100%。
評審質疑:為何設定100%的提升目標?是否有具體的資料支援該目標?同時,應考慮搜尋轉換率的多重影響因素,而非僅僅依賴搜尋結果的相關性。
風險評估:新搜尋系統可能導致使用者行為模式的改變,從而影響現有客戶的忠誠度;同時,新系統的缺陷可能導致收入的損失。
評審建議:提供使用者行為模式改變的具體例項,並考慮利用藍綠佈署和A/B測試來降低風險。
參考資料:列出了一些外部參考資料,包括企業級搜尋系統和學術論文。
評審建議:增加內部相關資料,如PhotoStock BI儀錶板和UX研究報告。同時,應擴大市場相關解決方案的調查範圍,而非僅限於特定的解決方案或學術論文。
設計檔案審查的最佳實踐
透過上述案例的分析,可以歸納出設計檔案審查的一些最佳實踐:
提出合理問題:在早期階段提出合理且建設性的問題,以促進團隊討論和解決方案的最佳化。
補充缺失內容:評審者應指出設計檔案中缺失的部分,無論是透過提問還是直接陳述,以確保檔案的完整性。
促進健康討論:評審的目標是促進團隊之間的健康討論,從而得出更好的解決方案,而非進行攻擊性的批評。
設計檔案的動態特性
設計檔案是一個動態的檔案,在專案開發的不同階段都可能需要進行修改和完善。因此,團隊成員應該無所顧忌地對設計檔案進行編輯和評審,以確保專案能夠順利推進。
綜上所述,設計檔案的審查是技術開發過程中不可或缺的一環。透過有效的審查,可以提前發現問題、最佳化解決方案,從而提高專案的成功率。團隊應當鼓勵開放的討論和持續的檔案更新,以確保專案能夠滿足業務需求並達到預期的目標。
設計檔案的演進與重要性
設計檔案(design doc)是一個不斷演進的檔案,它記錄了系統設計的過程和決策。在實際的開發過程中,設計檔案會經歷多次修改和完善。最初的版本往往不夠完善,需要透過同行評審和反饋進行改進。
設計檔案的迭代過程
- 初步迭代:撰寫第一版設計檔案。
- 同行反饋:接收同行的反饋意見。
- 多次修改:根據反饋意見對設計檔案進行大幅度修改(例如,60%、30%、10%的內容修改)。
- 實行與調整:在系統實作後,根據實際運作情況和新的需求對設計檔案進行進一步的修改。
設計檔案不是一次性的產物,而是一個伴隨系統整個生命週期的動態檔案。系統上線後,仍需要根據實際執行情況、新的需求和技術發展對設計檔案進行更新和完善。
為何設計檔案是活的
- 系統演進:隨著系統的不斷發展,新功能的新增、基礎設施的變更或法規的要求,都需要對系統進行調整。
- 技術進步:新的技術或模式可能會使現有的系統設計變得過時或有改進的空間。
- 知識傳承:當開發人員離開公司時,完善的設計檔案可以幫助後繼者理解系統的設計和實作。
實踐“設計兩次”的方法
對於複雜的系統,「設計兩次」(design it twice)是一種有效的策略。這意味著在最初的設計基礎上,再次採用完全不同的設計方法,以揭示潛在的問題和機會。
重視設計檔案的價值
- 降低複雜性:好的設計可以降低系統的複雜性,使其更容易被理解、建立、修改和維護。
- 投資未來:在初期投入更多時間和精力進行多輪設計迭代,可以在長期內獲得回報。