題目與適用情境
請為即時詐欺評分系統設計一條 ML 特徵管線。訓練集涵蓋過去 12 個月,線上每秒約有 5,000 次預測;每次預測需要讀取約 50 個特徵,留給特徵讀取的延遲預算是 5 ms p99。這些數值是本題用來討論取捨的容量假設。
特徵既有交易串流上的一小時金額彙總,也有每天更新的帳戶年齡。部分事件會延遲到達,歷史資料還可能被回填;模型更新時也可能改變特徵定義。請說明如何產生時間點正確的訓練資料、低延遲提供線上值、處理缺失和陳舊、發布新版本,並用可執行的驗證證明離線與線上語意一致。
這類題目適用於資料工程、機器學習工程和 ML 平台職位。它考察的重點不是背誦「加一個特徵庫」,而是把一項特徵從定義、計算、儲存、服務到驗證連成一條可追溯鏈路。
面試官考察重點
第一,候選人能否先定義特徵語意,再畫儲存架構。高品質答案會把實體鍵、資料型別、來源、轉換版本、事件時間、可用時間、彙總視窗、時效要求、預設策略和負責人寫進特徵契約。離線和線上系統都實作這份契約,不能各自憑名稱猜測含義。
第二,能否正確處理時間。eventat 表示業務事件何時發生,availableat 表示系統何時真正知道它。一筆紀錄即使發生在預測之前,若預測之後才到達,當時的服務也不可能使用它。訓練集若只判斷 eventat <= predictionat,仍可能把回填或晚到資訊帶回歷史。
第三,能否為不同存取模式選擇計算和儲存方式。離線訓練需要時間歷史和 point-in-time join;線上服務通常需要實體的最新值。視窗彙總適合預先計算並具體化,便宜且只依賴目前請求的特徵可以按請求計算。離線與線上可以使用不同執行引擎,但必須保持相同語意並用資料證明等價。
第四,能否設計安全的版本發布和故障行為。模型應固定依賴的特徵集合版本,新舊版本要能在灰度和復原視窗內共存。缺失不等於零;陳舊、儲存不可用和版本不相容都要有明確策略。
最後,面試官會看驗證是否可執行:契約檢查、黃金樣本、歷史時間點測試、線上特徵向量取樣、離線重播、晚到與亂序注入、回填和復原演練,以及延遲、時效、缺失率和一致性指標。
回答前需要釐清的問題
- 預測時刻與標籤視窗是什麼? 本題假設交易到達時立即評分,拒付標籤在之後 30 天內成熟;標籤不能回流為特徵。
- 線上延遲預算涵蓋什麼? 5 ms p99 是特徵讀取本身,還是包含網路、序列化和模型推論?本題只把它用於特徵讀取。
- 哪些特徵需要多新? 一小時交易額可能要求分鐘級時效,帳戶年齡通常允許日級更新;不能給所有特徵套同一個 TTL。
- 事件會多晚、是否亂序或重複? 這決定水位線、去重、重算和線上覆寫規則。
- 歷史回填要重現「當時所知」還是「最新修正事實」? 訓練過去線上行為時需要前者;做事後分析時可能需要後者,兩者不能混成一個資料集。
- 線上缺失或陳舊時業務怎樣降級? 風控情境可以切換基線模型、進入人工審核或拒絕高風險請求,不能預設把所有缺失填成零。
- 模型與特徵如何獨立發布? 需要知道是否允許並行具體化多個版本、舊版本保留多久,以及復原目標。
- 現有基礎設施是什麼? 單模型、純批次處理、低流量時,共用轉換程式碼和不可變快照可能已經夠用,不必先引入完整特徵平台。
30 秒回答框架
「我先建立帶實體鍵、雙時間、視窗、版本和時效要求的特徵契約。原始事件不可變保存;同一份定義產生離線歷史和線上最新值。訓練樣本按 predictionat 做 point-in-time join,同時約束 eventat 與 availableat,避免把後來才到達的資料帶回過去。模型固定 featureset_version,新版本與舊版本並行具體化、影子比較後再切流。線上取樣記錄實際特徵向量,我用原始事件和同版本定義離線重播,逐項比較值、缺失和時效,再注入晚到、回填、儲存故障與復原情境。」
分步深入解答
第一步:把特徵定義變成可執行契約。
每項特徵至少登記以下欄位:
| 契約欄位 | 作用 | |---|---| | 實體與連接鍵 | 明確特徵屬於帳戶、裝置還是交易,避免錯連 | | 型別與結構 | 在寫入前發現型別漂移或非法空值 | | 來源與轉換版本 | 讓訓練和服務能夠重建同一計算 | | eventat 與 availableat | 區分事件發生時間和系統可見時間 | | 視窗與 TTL/時效 | 定義彙總邊界和何時算陳舊 | | 預設值與降級策略 | 讓缺失、陳舊和故障有業務含義 | | 離線/線上可用性 | 說明是否需要歷史訓練和低延遲服務 | | 所有者 | 讓品質告警與變更審核有負責人 |
特徵名稱一旦發布,就不能靜默改變定義。若 txnamountsum_1h 從「已授權交易」改成「所有嘗試交易」,應發布新版本或新特徵名稱,而不是讓舊模型在不知情時讀到新語意。
第二步:讓離線和線上從相同事實出發。
交易、帳戶變更等原始事件先進入不可變日誌或可重播的歷史層。串流處理計算高時效視窗特徵,批次處理計算慢變維度和歷史回填。兩條路徑把完整時間歷史寫入離線儲存,同時把每個實體的最新有效值具體化到線上儲存。
「相同定義」不要求批次處理和串流處理必須使用同一種語言。團隊可以共用宣告式轉換或公共程式碼;確實需要兩套實作時,就把黃金樣本和重播一致性測試設為發布門檻。特徵庫只是組織這些約束的工具,不能自動消除兩套邏輯的差異。
線上寫入要具備冪等性。事件攜帶穩定 ID,重複事件不應重複累計;寫入最新值時比較特徵時間和版本,晚到的舊結果不能覆蓋已經更新的值。對於視窗彙總,必須明確允許遲到區間、水位線和修正方式。
第三步:產生真正時間點正確的訓練集。
每個訓練樣本都有 predictionat。對同一實體,普通 as-of join 會選擇 eventat <= predictionat 的最近特徵版本;存在晚到或回填時,還要滿足 availableat <= prediction_at:
eligible_feature = same_entity
AND event_at <= prediction_at
AND available_at <= prediction_at
selected_feature = latest eligible_feature by event_at, then available_at第二個條件很關鍵。某筆交易在週一發生、週三才到達,而歷史預測發生在週二;它在業務時間上屬於過去,在系統知識上仍屬於未來。若資料平台無法保存 available_at,就要使用當時的不可變快照或線上特徵日誌重現,不能用今天修正後的資料表冒充歷史服務狀態。
「當時所知」與「最新修正」應成為明確的資料集模式。前者用於重現模型在歷史時刻能看到什麼,後者適合財務核對或事後分析。標籤也單獨處理:只有觀察視窗成熟的樣本可進入訓練,標籤產生資料永遠不參與特徵連接。
第四步:在具體化與按需計算之間取捨。
一小時交易額、近七天裝置數等視窗彙總計算昂貴且有嚴格時效,適合在串流中增量計算並具體化。帳戶年齡這類低頻特徵可以批次更新。只依賴本次請求、計算便宜且無需歷史的特徵可以按請求計算,減少儲存和同步面。
線上儲存按實體鍵和 featuresetversion 讀取最新值,避免臨時掃描歷史。離線儲存保留時間序列,用於訓練、回填和稽核。讀取 API 回傳值之外,還應回傳或記錄特徵時間、計算版本和缺失狀態,服務端才能判斷是否陳舊或不相容。
第五步:明確缺失、陳舊與故障策略。
每項特徵或特徵群組都有獨立的時效預算。讀取時計算 predictionat - featuretimestamp,超出預算就標記陳舊。缺失、陳舊、合法的數值零是三個不同狀態,訓練資料也要使用與線上相同的缺失表示。
降級由風險決定。非關鍵特徵可以使用經過訓練驗證的預設值;允許短暫陳舊的特徵可以讀取上一個值;關鍵風控特徵不可用時,可以切到不依賴它的基線模型、轉人工審核,或採取更保守的決策。所有降級都要記錄原因,防止系統悄悄長期運作在預設值上。
第六步:版本化發布並保留復原路徑。
模型成品固定 featuresetversion,其中包含特徵名稱、結構和轉換版本。發布 v2 時,先同時具體化 v1 和 v2;用相同實體做影子讀取和離線重播;確認覆蓋率、時效、值分布和逐項差異符合預期後,再部署讀取 v2 的模型。v1 至少保留到復原視窗結束。
結構相容規則也要明確:新增可選特徵可以向後相容,刪除、改型別或改變語意通常需要新版本。模型部署前檢查線上儲存已具備所需版本和覆蓋率,避免模型先上線、特徵尚未填充。
第七步:用線上事實驗證一致性。
從線上請求取樣記錄實體、predictionat、featureset_version、每項特徵的值、特徵時間、缺失/陳舊狀態和最終模型版本。不要只記錄模型分數,否則無法判斷差異發生在哪個特徵。
驗證工作從不可變原始事件開始,使用相同版本定義,在相同預測時刻重建離線向量,再逐項比較:
- 數值是否一致,浮點特徵是否在宣告的容差內;
- 缺失、預設和陳舊狀態是否一致;
- 事件視窗邊界和時區是否一致;
- 線上讀取的版本是否與模型宣告一致;
- 晚到、重複、亂序和回填後能否穩定重播。
發布前還要注入線上儲存不可用、部分鍵缺失、資料逾時、v2 復原到 v1 等故障。執行時監控 p50/p95/p99 讀取延遲、具體化延遲、缺失率、預設率、陳舊率、版本不匹配率和重播差異率。模型效果監控可以發現後果,但不能取代這組特徵層證據。
高品質示範回答
「我會先定義特徵契約,而不是從資料庫選型開始。每項特徵登記實體鍵、型別、來源、轉換版本、事件時間、系統可用時間、視窗、時效預算和降級規則。原始事件進入不可變歷史層;串流處理負責一小時金額等高時效彙總,批次處理負責帳戶維度和回填。兩者寫入離線時間歷史,並把每個實體的最新有效值具體化到線上儲存。
訓練樣本以 predictionat 為錨做 point-in-time join。候選特徵必須同時滿足 eventat <= predictionat 和 availableat <= prediction_at。這能排除雖然早已發生、但當時尚未到達的紀錄。若要重現歷史線上行為,我使用 as-known 資料集;最新修正資料單獨用於事後分析。標籤等 30 天視窗成熟後才加入,且標籤來源不進入特徵管線。
線上讀取按實體和 featuresetversion 一次取得約 50 個值,並攜帶特徵時間與狀態。視窗彙總預先計算,只依賴請求的低成本特徵按需計算。重複事件用穩定 ID 去重,晚到的舊版本不能覆蓋較新的線上值。每個特徵有獨立的時效預算;缺失、陳舊和零值分開。關鍵風控特徵不可用時切換經過驗證的基線模型或人工審核,而不是靜默填零。
模型成品固定特徵集合版本。發布 v2 時並行具體化 v1/v2,做影子讀取和重播比較,覆蓋率符合門檻後再切模型,並保留 v1 供復原。為了證明一致性,我會取樣記錄線上實際特徵向量、時間和版本,從不可變事件離線重建同一時刻的向量,逐特徵比較值與狀態。發布門檻還包括晚到、亂序、回填、儲存故障和版本復原測試。執行時重點看讀取 p99、具體化延遲、缺失/陳舊率、版本不匹配和重播差異率。
如果目前只有單個低流量批次模型,我會先用一份版本化轉換和不可變訓練快照解決問題;只有多個模型真實共用特徵、同時需要歷史檢索和低延遲服務時,才引入完整特徵平台。」
常見錯誤
- 先選線上資料庫再定義語意 → 儲存低延遲也無法阻止同名特徵含義不同 → 先建立可執行的特徵契約。
- 只用
eventat做歷史連接 → 後來才到達的紀錄會被帶回過去 → 同時約束availableat或重現當時快照。 - 認為共用特徵庫就自動一致 → 批次處理和串流處理仍可能有兩套視窗、預設值和時區規則 → 用共用定義、黃金樣本與重播證明等價。
- 讓晚到結果直接覆蓋線上值 → 較舊視窗可能倒退實體狀態 → 比較特徵時間和版本,並讓寫入具備冪等性。
- 把缺失統一填成零 → 零可能是合法業務值,故障也會被模型當成訊號 → 區分缺失、預設、陳舊與真實零。
- 原地修改已發布特徵 → 舊模型會在無版本變化時讀取新語意 → 發布新版本並讓模型固定依賴。
- 模型先上線、特徵再慢慢回填 → 初始流量會大量讀取缺失或混合版本 → 先具體化、驗覆蓋率,再切模型。
- 只比較離線和線上分布 → 相似分布可能掩蓋單實體錯連或視窗偏差 → 對同一請求逐特徵重播比較。
- 只記錄預測分數 → 出錯後無法定位值、時間還是版本 → 取樣記錄實際向量及其詮釋資料。
- 所有情境都建設完整特徵平台 → 單模型批次處理可能承擔不必要複雜度 → 按共用規模、歷史檢索和延遲需求逐步引入。
追問與應對
追問一:事件時間和可用時間為什麼不能合併?
事件時間回答「業務上何時發生」,可用時間回答「系統何時知道」。晚到事件、人工補登和歷史回填會讓兩者不同。重現歷史預測時必須滿足兩條時間邊界,否則模型會使用當時不可見的資訊。若業務能保證同步到達且這項保證可稽核,兩者可以相同;不能把假設預設為事實。
追問二:批次處理和串流處理必須共用同一份程式碼嗎?
共用程式碼能減少差異,值得優先考慮,但不是唯一辦法。執行引擎、狀態管理或效能要求可能迫使團隊實作兩條路徑。此時應共用契約和測試資料,用黃金樣本、邊界條件和歷史事件重播驗證結果等價,並把差異測試作為發布門檻。
追問三:晚到事件怎樣修正線上視窗特徵?
先定義允許遲到範圍和視窗關閉規則。範圍內的事件可以去重後更新受影響視窗,並只用較新的特徵版本覆蓋線上值;範圍外事件進入修正或回填工作。是否改寫過去的訓練集取決於資料集模式:重現當時服務使用 as-known,分析最新事實使用 corrected,兩者分別保存。
追問四:怎樣判斷一個特徵應該具體化還是按需計算?
比較計算成本、重用程度、時效要求、讀取延遲和一致性風險。跨大量歷史事件的視窗彙總、高重用且延遲敏感的特徵適合具體化;只依賴目前請求、計算便宜且沒有歷史訓練需求的特徵適合按需計算。還要把回填成本和故障面算進去,而不是只看單次 CPU 時間。
追問五:如何在不中斷服務的情況下修改特徵定義?
發布新的特徵集合版本,並行具體化舊版和新版。先驗證結構與覆蓋率,再對線上實體做影子讀取和模型影響比較;隨後小流量切換讀取新版本的模型。舊模型繼續固定舊版,舊資料保留到復原視窗結束。禁止用同一名稱原地替換語意。
追問六:離線與線上浮點結果不完全相同怎麼辦?
先區分允許的數值誤差和語意差異。為每項特徵宣告絕對或相對容差,並使用相同的空值、時區、捨入和視窗邊界規則。若差異隨實體或邊界系統性出現,應按錯誤處理;不能用很寬的全域容差掩蓋錯連、精度截斷或不同彙總順序。
追問七:線上特徵儲存不可用時應該失敗還是降級?
由決策風險和可恢復性決定。低風險推薦可以短時使用快取或基線排序;高風險詐欺決策可能轉人工、採用更保守規則,或拒絕無法安全評估的請求。策略必須在訓練和演練中出現,記錄降級原因,並設定持續時間和流量上限,避免故障模式變成常態。
追問八:怎樣證明新管線真的減少了訓練—服務偏差?
選擇一組包含正常、缺失、邊界視窗、晚到和回填情況的歷史請求,保存線上實際向量及版本;用不可變事件在相同 prediction_at 離線重建,逐特徵比較值和狀態。上線後持續取樣同樣的對帳,並觀察差異率是否低於預設門檻。分布圖和模型指標只能補充,不能取代同請求重播。