算法工程師為什么成天做數(shù)據(jù),都做哪些數(shù)據(jù)?
為什么很少做模型
在大家想象當中,可能算法工程師做的事情是今天看paper,明天把paper實現(xiàn)了,后天就上線使用,然后公司的收入刷刷漲,我們的工資、級別也跟著漲。但實際上,大多數(shù)崗位下的工程師日常并不是這樣。國外有一個著名的大佬(我忘記名字了)曾經(jīng)說過,算法工程師有70%的時間是投入在數(shù)據(jù)上的,花在模型和調(diào)參上的只有不到20%。
這句話大家可能或多或少都聽過,但是想必都不是很理解,為什么會這樣呢?為什么不能多花點時間做模型呢?原因也很簡單,并非不想,而是不能。
不能的原因也很有很多,我隨便舉幾個最常見的。
框架限制
模型不能隨便動的原因有很多,一般來說最常見的是框架的限制。這種情況在大公司和小公司里都有,比如之前我在某大公司的時候,公司的框架非常成熟,以至于很少寫代碼去實現(xiàn)某一個模型,而更多的是可視化界面的連線以及設置操作。問題來了,在這個場景當中,可視化界面當中可選的模型是固定的,都是基礎團隊開發(fā)好的,他們開發(fā)好了這么多模型,我們就只能使用這么多模型,除非我們脫離這整個流程,但顯然這是不可能的。
所以當時在很長的一段時間里,我們只能在有限的模型當中做選擇。直到后來,公司開發(fā)出了新的框架工具,可以讓我們自己定制神經(jīng)網(wǎng)絡的代碼實現(xiàn)深度模型,這才鳥槍換炮迎來了全面升級。
小公司雖然不像大公司這樣有一套成熟且不易改動的框架,但是一般也會有自己的一套流程。比如公司前人留下來鏈路是基于開源xgboost開發(fā)的,你想要使用TensorFlow訓練神經(jīng)網(wǎng)絡模型代替原有的xgboost,一般來說這是肯定有效果的,也一定會迎來提升。但問題是,你可能需要把訓練模型、線上調(diào)用模型的整個鏈路都重構。很多算法工程師的開發(fā)能力不太行,而且也不太愿意做工程重構的事情,再加上這塊工作量也不小,所以很容易出現(xiàn)的情況就是,大家都明知道怎么做比較好,但是由于投入比較多,大家也都不愿意做,一直delay。
效果難保證
第二個原因是paper上的一些模型和做法,效果其實是很難保證的。如果你讀過paper會發(fā)現(xiàn)paper的結論往往都有很多前提。比如某某特定的數(shù)據(jù)或者是場景,前期強大的recall以及過濾系統(tǒng),或者是完善的特征準備等等。paper里不會把這些都寫出來,它只會寫上做法以及結果。所以這就導致了,很多paper里寫得天花亂墜的方法,實際應用起來效果可能并不好。
這也不是paper吹牛,而是你沒有同樣的條件。舉個例子,阿里的數(shù)據(jù)埋點非常精準,精準到用戶從打開app到關閉app的每一個動作和行為都有記錄,每一個商品或者是模塊在用戶處展示了多少時間,甚至是用戶翻頁的速度都有全面完整的記錄。就這種數(shù)據(jù),一般規(guī)模的小公司根本做不了。你做不了這個數(shù)據(jù),你就沒有paper里那些精準的特征。那你如何保證你使用阿里的模型也有同樣的效果呢?
優(yōu)先級問題
我們都知道,事情根據(jù)緊急以及重要可以分成四類,不重要不緊急、緊急不重要、緊急且重要、重要不緊急。很多人也都知道,最重要的事情是把那些重要且不緊急的事情做好。說起來大家都會說,但是實際上未必人人都會這么選。
當你面臨KPI考核壓力的時候,一線的工程師可能就只能盯著緊急的事情做。因為他們需要趕緊做出一點成績來完成自己的業(yè)績,完成自己業(yè)績的最好方法絕不是去升級或者是更新模型,而是找一些特征做一做,或者是使用一些取巧的方法看看能否提升效果?;〞r間去更新模型,付出的勞動很大,也不一定有效果。但是做特征代價很小,做了一個沒效果,可以再做一個,迭代也快。
這其實并不完全是工程師鼠目寸光,也是整個職場氛圍的影響的結果。大家都看重業(yè)績和績效,以至于大家都陷入了局部最優(yōu)解,但是卻離整體最優(yōu)解越來越遠。
要想避免這種情況,需要有高瞻遠矚、統(tǒng)籌規(guī)劃的架構師或者是leader,能夠抗住升級模型的風險壓力。對可能出現(xiàn)的情況以及將來要做的事情有充足、詳細的規(guī)劃,并且有足夠的經(jīng)驗應對各種可能出現(xiàn)的事情。但是大家也都知道,擁有這種能力的leader在職場里鳳毛麟角。大公司里都不多見,小公司里就更加難得了。
做哪些數(shù)據(jù)
說完了模型的問題,我們來聊聊數(shù)據(jù),既然不能頻繁地變更模型,工程師們就只能更多地來做數(shù)據(jù)了,那么工程師們到底又在做哪些數(shù)據(jù),需要花費這么多時間呢?
訓練數(shù)據(jù)
大公司里有完整的流程,我們把流程設計好了之后,訓練數(shù)據(jù)、測試數(shù)據(jù)、模型訓練以及部署可以一條龍流水線作業(yè)。但是在中小型公司里,這往往是做不到的。
原始數(shù)據(jù)是不能直接用來訓練模型的,這中間需要復雜的處理流程。首先,需要做采樣。就拿CTR預估的場景來舉例,一般情況下真實場景下的點擊率不會超過10%。但是模型訓練一般正負樣本的比例是1:3左右,那么這就需要我們對負樣本進行采樣。
采樣你還不能直接采,因為可能這些樣本當中還存在很多臟數(shù)據(jù)或者是非法的數(shù)據(jù)。我們需要先把這些有問題的數(shù)據(jù)過濾了之后,再進行采樣,這樣才能保證我們的數(shù)據(jù)是干凈的。采樣了之后,我們需要進行特征和字段的查找補全。因為數(shù)據(jù)往往是分開存儲的,比如用戶的基礎信息是一張表,用戶的行為數(shù)據(jù)又是一張表,商品的信息是一張表,各種各樣的數(shù)據(jù)存放在各種各樣的地方。我們有了樣本之后,還需要去查找很多的數(shù)據(jù),才能把所有需要用到的字段搜集齊。
當我們搜集了所有需要的數(shù)據(jù)之后,我們才能開始真正樣本的制作,也就是使用這些我們查找以及搜集到的原始數(shù)據(jù)生成輸入模型的樣本特征。每一個特征可能都有自己獨特的生成邏輯,這也是一個龐大的工程。這一步做完還沒結束,還會需要把數(shù)據(jù)轉化成模型需要的格式。比如tfdata或者是tensor、json之類的。
這么一系列步驟,大公司一般都有一整套完整的自動調(diào)度流程, 工程師們不需要操心,只需要拿來用就好了。但是在中小型公司,可能就只有一些手動工具了,需要數(shù)據(jù)都需要手工去跑一些任務或者是腳本。跑的過程當中還有可能會失敗以及遇到各種問題,雖然說起來平平無奇,也沒什么價值,但這些事情都是需要工作量的。
新的特征
特征怎么做?在kaggle之類比賽當中,可能就是使用pandas寫兩個函數(shù),或者是幾行處理的邏輯就搞定了。但實際上絕不是這么簡單。
我舉一個最簡單的例子好了,比如我們將年齡進行歸一化,做成一個標準化年齡的特征。這個簡單吧,我們就用比較簡單的最大最小值歸一化方法好了,公式是:
算法工程師為什么成天做數(shù)據(jù),都做哪些數(shù)據(jù)?
歸一化之后,這個特征值會被縮放到0-1的區(qū)間里。但是這里面用到了兩個參數(shù),一個是最大值,一個是最小值。這兩個參數(shù)怎么來?你可能會覺得這還不簡單,我們遍歷下數(shù)據(jù)不就知道了。但問題是這個數(shù)據(jù)你并不是只用一次,以后每次生成訓練數(shù)據(jù)都需要生成這個特征,難道每次跑的時候都手動遍歷一下數(shù)據(jù)找下最大最小值嗎?而且數(shù)據(jù)是在變化的,每一天用戶年齡的最大和最小值可能都不一樣,假如說我們要跑好幾天的訓練數(shù)據(jù)怎么辦?
設計一個新的特征是簡單的,但是里面的一些參數(shù)會讓事情變得復雜,我們往往需要設計復雜的機制來將新完成的特征加入流程。
效果分析
還有一塊數(shù)據(jù)處理的大頭在效果分析,效果分析有兩種,第一種是做一些之前沒有的指標以及相關的分析,或者是應老板的要求做一些業(yè)務指標的分析,達成我們的績效。
比如像是最基礎的CTR、CVR、收入等數(shù)據(jù),也有像是老板臨時起意想要看的某些數(shù)據(jù)。比如分析一下某些特征的分布,比如看一下某個特定族群中樣本的數(shù)量或者是數(shù)據(jù)的情況,等等等等,不一而足。
第二種是我們模型做出來之后的效果分析,如果說模型的效果還,那還好。如果效果不好,問題就來了,我們怎么樣確定是哪里出了問題?是因為模型本身的性能不足呢?還是我們的特征不夠或者是特征當中存在問題呢?還是我們的數(shù)據(jù)質(zhì)量不高呢?還是說什么地方存在bug呢?
算法不像是工程,工程當中絕大多數(shù)事情是確定的,結果不對一定是因為邏輯有bug,那么只要仔細測試,分析原因,總能解決。那種難以復現(xiàn),找不到原因的問題非常罕見。但是算法不一樣,大多數(shù)情況下并沒有絕對的錯誤和正確,甚至沒有絕對的原因。我們扮演的角色更多地像是偵探,根據(jù)一些蛛絲馬跡推測導致問題的原因,然后用實驗嘗試著解決,在這個過程當中就涉及到大量的數(shù)據(jù)處理和分析的工作。
比如,如果你懷疑是某些特征分布有問題導致了模型效果不好,那么你需要分析特征的分布。如果你懷疑是數(shù)據(jù)存在bug,那么你需要設計方案,篩選數(shù)據(jù),仔細甄別數(shù)據(jù)當中的問題,驗證自己的想法。如果你覺得是訓練數(shù)據(jù)量不夠,那么你需要增大訓練量,設計對比實驗……總之,想要排查問題都需要大量的數(shù)據(jù)分析,絕不僅僅是看看代碼,想一想就能有結論的。
感想
很多想要從事算法的人真正做了算法之后,往往會有幻滅感。會有一種強烈的面試造航母,入職擰螺絲的感覺。原因也很簡單,我們面試的時候問的是各種各樣的模型,各種先進的理念和方法,但是入職之后面臨的工作卻是各種各樣的數(shù)據(jù)分析以及數(shù)據(jù)準備。比如我當年大部分時間都在寫SQL做數(shù)據(jù),我一度懷疑公司的職位安排。
但當我理解了這一切的運作機制之后,我就理解了。實際的工作場景和線上算法比賽不同,線上比賽我們可以使用各種各樣的trick來提升成績。還可以搞各種跨界混搭,比如今年的騰訊算法大賽的冠軍的做法就是把BERT應用在了用戶行為分析的場景下。但是在實際的場景當中,由于系統(tǒng)以及各方面的制約,這些想法都是很難實現(xiàn)的而且效果也難保證,最終還是要落實到基本的數(shù)據(jù)支撐上來。
打個不確切的比方,各種各樣的算法模型就好像是工具箱里的各式工具,我們僅僅了解工具是沒用的。最重要的是要理解使用工具的場景,從而可以根據(jù)需要選擇最合適的工具。但很遺憾的是,我們對數(shù)據(jù)以及場景的理解是很難量化的,所以面試的時候只能退而求其次問你工具的使用了,長此以往很多人本末倒置,搞錯了核心競爭力,出現(xiàn)對面試的種種非議也就不奇怪了。