頻率不等於重要性:一個未能通過檢驗的排名維度
我們依據語料庫頻率為一個領域詞彙進行排名,結果排名前 20 的詞彙全都是通用詞。一個預先規劃的資料閘門如何阻止了一個不良軸的發布。
我們需要為一個領域詞彙進行排序,以便將最重要的詞彙納入預算極為有限的提示中。最明顯的信號是頻率:計算每個詞彙在可信語料庫中出現的次數,按次數排序,就完成了。我們建立了這個系統,進行了測量,結果排名前 20 的詞彙是「諮詢」、「療程」、「臉部」、「預約」,以及其他十六個通用模型早已瞭若指掌的詞彙。沒有任何一個品牌名稱上榜。我們建立來提升獨特詞彙的軸線,結果卻恰恰提升了那些最不需要提升的詞彙。
這篇文章是關於為什麼頻率作為重要性信號會失敗,我們在失敗前避開的兩個陷阱(從用量衍生的頻率和原始計數),以及真正拯救我們的部分:設計推出流程,讓這個軸線可以低成本地失敗,並在程式碼和行為變更之間設置一道分佈檢查。
設定:30 個名額,數千個候選項目
此排序的取用者是語音辨識的關鍵字偏向提示。該提示有嚴格的權杖預算,實務上大約能容納 30 個詞彙。詞彙資料庫中存有數千個已確認的詞彙。無論我們選擇何種排序函式,它都決定了詞彙庫中哪 1% 的詞彙能影響轉錄;其餘的詞彙則形同不存在。
我們現有的排序方式使用來源信任層級(手動輸入的詞彙優先於網站挖掘的詞彙,網站挖掘的詞彙又優先於機器產生的詞彙),並以權杖成本作為決勝標準。問題出在分佈的中間部分:數千個詞彙共享同一個層級,而在同一層級內,決勝標準偏好短字串。在人類詞彙中,短字串偏向通用。雙字元的日常用詞浮到提示的頂端,而整個系統旨在轉錄的品牌名稱卻落在截斷點之下。
頻率看起來是解決之道。重要的詞彙應該經常出現在領域文本中;罕見的雜訊則不應出現。這個直覺沒有錯,但其不完整之處卻至關重要。
陷阱一:使用頻率會放大你自己的錯誤
第一個候選語料庫是我們自己的使用日誌:使用者實際說話內容的逐字稿。這是最誘人的語料庫,因為它反映了真實的需求。但當產生這個語料庫的管線,正是你試圖修復的管線時,它也會以一種微妙的方式被污染。
我們的語音轉錄引擎會將某個品牌名稱誤認為一個發音相似的競爭對手詞彙。在使用語料庫中,錯誤詞彙的出現次數是正確詞彙的十二倍,因為語料庫記錄的是引擎寫下的內容,而不是說話者所說的內容。若根據該語料庫進行排序,這個錯誤辨識就會被提升到偏誤提示中,這會讓引擎對錯誤的詞彙更加確信,從而進一步提高其出現頻率。錯誤就這樣自我強化。
我們從中得到的規則是:絕不要從你試圖修正的系統的輸出中,衍生出用來修正該系統的排序訊號。這種形式的回饋迴圈不會自我宣告;它們只會悄悄地收斂到失敗模式。
陷阱二:原始計數獎勵重複,而非共識
第二個候選方案是來自受信任網域網站的爬取頻率,這可以避開回饋循環,因為文本從未經過辨識引擎。但原始出現次數有其自身的偏誤:一個在每個頁面(導覽列、頁腳、促銷橫幅)都重複某個詞彙的單一網站,其票數可以超過十個各提及一次不同、但真正重要詞彙的網站。
我們將統計數據從原始計數切換為來源層級的文件頻率:也就是,這個詞彙到底出現在多少個不同的網站中?一個出現在七個獨立診所網站的詞彙,是整個領域的共同點;一個在某個診所網站上出現 400 次的詞彙,則是該診所的行銷手法。我們也為該軸設定了一個小的最大值上限,這樣它可以在不壓過信任層級的情況下,打破同層級中的平局。
這是對錯誤想法的正確改良。它修正了操縱和偏斜的問題,但它仍然無法解決核心問題。
衡量指標:通用詞彙終究勝出
在計數、重複資料刪除和來源歸屬功能建置並測試完成後,我們在 28 個網站上運行了計數器,並在將該軸線接入即時排名之前,查看了分佈的頂端。按文件頻率排名的前 20 名為:
諮詢、療程、臉部、輪廓、治療、預約、疼痛、發炎、額頭、組織、身形、胸部、彈性、脂肪、拉提、填充物,以及其他一些性質相同的詞彙。每一個詞都是任何語音模型無需額外設定就能正確轉錄的字詞。沒有任何品牌名稱。
事後看來,這個結果是顯而易見的。文件頻率衡量的是跨來源的一致性,而獨立來源之間最一致的內容就是普通語言。每家診所都會寫「諮詢」和「預約」;但只有部分診所會引進特定的設備或產品。在專業語料庫中,出現的廣度與分佈頂端的通用性相關。我們想要的特殊詞彙位於中間地帶:出現在數個來源中,但不存在於兩個極端。
頻率,無論是哪種類型,回答的都是「這個詞彙有多普遍?」而重要性,對我們的目的而言,則是「模型在處理這個詞彙上需要多少幫助?」這兩個問題幾乎是相反的。模型需要幫助的詞彙,恰恰是在一般文本中代表性不足的那些。
運作成功的部分:程式碼與行為之間的閘門
以下是避免這次成為昂貴錯誤的原因。在規劃審查期間,一位審查員指出了這個風險:爬取頻率可能與通用性相關,從而提升垃圾內容而非降低其排名。我們無法透過爭論解決這個問題,因此我們圍繞一項測量重新設計了推出計畫:
- 這個軸的實作帶有一個不變量,並由單元測試驗證:如果每個詞彙的頻率都是零,排名結果將與舊排名逐字節完全相同。空的資料意味著這個軸不存在。
- 頻率表由一個獨立的批次步驟填入,該步驟刻意尚未在排程的管線中啟用。
- 在填入資料與正式採用之間,設立了一個書面閘門:檢查分佈中的前 20 名。如果主要由獨特的領域詞彙主導,就採用這個軸。如果主要由通用詞彙主導,就截斷表格並跳過採用。
這個閘門失敗了,而失敗的代價很低。我們截斷了表格,讓這個軸的程式碼在其零資料不變量的保護下保持休眠,並推出了我們預先指定的備用方案:將測量中浮現的通用詞彙加入停用詞列表中,從而完全將這些詞彙從提示中排除。這次測量沒有白費;它產生了我們所能期望的最佳停用詞候選名單,並且有數據支持,而非僅憑直覺。
通用模式是:當一個排名信號看似合理但未經證實時,分別交付機制和數據,在兩者之間設置一個分佈檢查,並預先承諾「失敗」的樣貌以及備用方案是什麼。另一種做法是,將這個軸直接接入生產環境,並透過觀察品質指標的變化來評估它,這樣會耗費數週時間,並侵蝕對整個系統的信任。
我們會用什麼來取代詞頻
這次的關卡讓我們留下一個更尖銳的問題:如果不是詞頻,那什麼能預測「模型在這個詞上需要幫助」?在事後檢討中,有三個信號留存下來:
- 分詞器的碎片化。一個模型的分詞器會將其打碎成許多片段的詞語,就是模型很少見過的詞語。這可以僅憑詞彙庫離線計算,完全不需要語料庫,而且在我們先前的測量中,它清楚地區分了品牌名稱和日常用詞。
- 觀察到的混淆。一個從生產環境事件中收集而來的實際錯誤識別字典,指出了需要增強的確切詞語。這個字典很小,但每個條目都是基線事實。
- 中頻段文件頻率。如果真的要使用詞頻,有用的頻段是中間部分:也就是出現在少數幾個獨立來源中,但並非所有來源都有的詞語。分佈的頂端是通用詞語;底部則是雜訊。
這些方法沒有一個像計數一樣簡單。而這正是重點所在。
發布語料庫衍生排序訊號的檢查清單
- 絕不要用你試圖修正的系統所產生的語料庫來進行排序;封閉迴路會放大自身的錯誤。
- 跨獨立來源的文件頻率優於原始計數,並為該軸設定上限,使其無法壓過更強的訊號。
- 在採用前,查看分佈的實際頂端,而非指標的描述。在查看之前就決定通過標準。
- 以零資料不變量來實作該軸,如此一來,「沒有資料」可證明等於「舊有行為」,並將資料填充與採用保留為獨立的開關。
- 預先承諾一個後備方案。我們的方案是資料驅動的停用詞擴展,而它將一個失敗的軸轉變為一個有用的產物。
- 記住頻率所衡量的是什麼。普遍性與重要性指向不同的方向,正好發生在你的詞彙是專業化的時候,而這正是你唯一需要排序的時候。
這個軸仍在程式碼庫中,處於休眠狀態。如果我們有朝一日找到一個能通過這個關卡的訊號,只需一個批次作業就能採用它。在那之前,這個關卡已盡其責:它讓一個看似可行的想法在試算表中失敗,而不是在生產環境中。