算法與算法工程師
先來一段我在知乎里回答“做算法工程師是一種怎樣的體驗(yàn)?”的答案。
理想中的算法工程師:提出假設(shè)-》收集數(shù)據(jù)-》訓(xùn)練模型-》解釋結(jié)果。
實(shí)際中的算法工程師:提出假設(shè)-》收集數(shù)據(jù)-》預(yù)處理-》預(yù)處理-》訓(xùn)練模型-》調(diào)試-》調(diào)試-》重新收集數(shù)據(jù)-》預(yù)處理-》收集更多數(shù)據(jù)-》調(diào)試-》調(diào)試-》調(diào)試-》…-》放棄。
這個(gè)答案被點(diǎn)了幾十個(gè)贊,在24個(gè)答案中排在第二位,說明具有一定的普遍性。排名第一的有100+贊,而他的觀點(diǎn)是:每天最重要的就是跑數(shù)據(jù)!
這不是段子,而是事實(shí)。為什么“高大上”的算法工程師實(shí)際上是個(gè)數(shù)據(jù)民工,要尋找這種理想與現(xiàn)實(shí)的差距的原因,首先要理解一個(gè)事實(shí):只有人能夠理解數(shù)據(jù),機(jī)器不能。
不管我們用什么機(jī)器學(xué)習(xí)算法——無論是LR,SVM,k-means,EM——對于它們來說,輸入數(shù)據(jù)都是一堆浮點(diǎn)數(shù)組成的矩陣而以(如果說的更本質(zhì)一點(diǎn),只是一堆01序列)。如果有一個(gè)特征是“小時(shí)”,而它出現(xiàn)了25,任何一個(gè)智商正常的人類都能明白,這是一個(gè)錯(cuò)誤,然后在數(shù)據(jù)清洗的時(shí)候把這樣的數(shù)據(jù)排除。但是機(jī)器就無法理解這一點(diǎn)。要具備小時(shí)的概念,又要理解什么是時(shí)間,一天有多少個(gè)小時(shí)…機(jī)器怎么能自動(dòng)化完成這樣的數(shù)據(jù)清洗工作?更進(jìn)一步,如果人發(fā)現(xiàn)“小時(shí)”這個(gè)特征中大部分?jǐn)?shù)據(jù)是0到12,而混入少量13(但13的數(shù)量又不是太少以至不能被當(dāng)成離群點(diǎn)排除),人就會(huì)懷疑,是不是使用了12小時(shí)制而13是一個(gè)錯(cuò)誤。機(jī)器目前是無法做到這一點(diǎn)的。
再說人肉特征。一個(gè)是特征變換,比如需要一個(gè)特征是某兩列數(shù)據(jù)的比率,這種除法是線性模型不能涵蓋的。當(dāng)然可以增大模型的假設(shè)空間,但是太小涵蓋不了需要的變換,太大又容易過擬合。另一個(gè)是加特征,比如我認(rèn)為點(diǎn)擊率和屏幕分辨率有關(guān)系。于是我去找屏幕分辨率數(shù)據(jù)加入特征,如果沒有還要想辦法采集。這些機(jī)器都做不了。
但是,人一但把數(shù)據(jù)準(zhǔn)備好,接下來就是機(jī)器學(xué)習(xí)算法發(fā)揮的時(shí)候了。但是,算法工程師的主要工作不在這里,這是因?yàn)檐浖袀€(gè)特點(diǎn),可以近乎無成本的復(fù)制。只要這個(gè)世界上有一個(gè)人實(shí)現(xiàn)了LR(知識(shí)產(chǎn)權(quán)的問題這里不考慮,更何況開源軟件很多),其他需要用LR的人都可以拿過來用了。顯然,這些算法工程師們也正是這么做的。
然而,等算法輸出結(jié)果以后,又需要人的工作了——怎樣用結(jié)果解釋實(shí)際問題,應(yīng)用到業(yè)務(wù)中去。顯然這個(gè)過程和前面數(shù)據(jù)清洗、人肉特征的性質(zhì)類似,都是只有人能完成,機(jī)器做不到的任務(wù)。
做過數(shù)學(xué)建模的同學(xué)對這個(gè)過程可能很熟悉——如何把一個(gè)問題描述成數(shù)學(xué)問題,再如何把結(jié)果應(yīng)用到實(shí)際問題上。這有點(diǎn)類似于通信中的“最后一公里”問題,主干網(wǎng)的光纖建設(shè)的很強(qiáng)大,而最終用戶的接入?yún)s成了一個(gè)麻煩事。對于機(jī)器學(xué)習(xí)的應(yīng)用問題來說,算法和相應(yīng)的軟件包都是標(biāo)準(zhǔn)化、通用化的,像骨干網(wǎng);而數(shù)據(jù)如何“接入”,則是只能由人完成。因?yàn)?,只有人能夠理解?shù)據(jù)
技術(shù)與技術(shù)人員
這個(gè)問題可以推廣到整個(gè)計(jì)算機(jī)領(lǐng)域。把算法工程師代換成程序員,把機(jī)器學(xué)習(xí)算法代換成軟件,這個(gè)觀點(diǎn)就變成了:大部分程序員所解決的,是通用的計(jì)算機(jī)工具和具體的實(shí)際業(yè)務(wù)之間的“最后一公里”接入問題。
為什么這么說,我們先來看歷史:計(jì)算機(jī)技術(shù)發(fā)展了幾十年,程序員的入門門檻是逐步降低的。最初的程序,要在裸機(jī)上寫匯編。后來有了unix,c語言,程序員至少不用親自調(diào)度進(jìn)程了。java出現(xiàn)之后,連內(nèi)存都不用管了。而(世界上最偉大的)php出現(xiàn)之后,網(wǎng)絡(luò)編程的門檻進(jìn)一步降低,任何人都可以在短時(shí)間內(nèi)搭建一個(gè)網(wǎng)站。
原來的那些問題去哪兒了呢?被少數(shù)造“”輪子的程序員們解決了——那些寫操作系統(tǒng)、編譯器、虛擬機(jī)、運(yùn)行時(shí)環(huán)境、框架…等等的程序員們。這個(gè)趨勢一直在持續(xù)——新興的rust、golang等語言試圖解決多核時(shí)代出現(xiàn)的并發(fā)問題,hadoop、spark、mesos試圖屏蔽分布式系統(tǒng)底層的細(xì)節(jié)……可以預(yù)見,以后的并行編程和分布式編程門檻將會(huì)大大降低。這個(gè)過程是必然的,因?yàn)橐豁?xiàng)技術(shù)的發(fā)展,就是為了讓更多的人能更方便的使用它。
而這些計(jì)算機(jī)工具不能直接應(yīng)用于業(yè)務(wù),因?yàn)橛?jì)算機(jī)不能理解人類的語言,所以就有了大量的程度員存在,把人類的語言“翻譯”成計(jì)算機(jī)語言。這些程序員是使用“輪子”的。當(dāng)然這之間并不是非黑即白的,一個(gè)軟件在多大程度上可以被稱為輪子,取決于它的復(fù)用性。如果一段代碼只能在一個(gè)地方使用,它顯然不能稱為輪子。而事實(shí)是,大部分為具體的業(yè)務(wù)邏輯所寫的代碼,復(fù)用程度很低。
對于把通用計(jì)算機(jī)工具應(yīng)用到具體業(yè)務(wù)這個(gè)過程,中間到底有多少問題是技術(shù)性的?大部分技術(shù)困難被操作系統(tǒng)、編譯器、虛擬機(jī)解決掉了,剩下的主要是大型軟件(如果這是個(gè)大型軟件)的復(fù)雜性控制——而這個(gè)問題又主要由少數(shù)高級(jí)別的架構(gòu)師負(fù)責(zé)。對于寫具體代碼的程序員,剩下的技術(shù)性困難已經(jīng)很少了。
舉一個(gè)我供職過的公司,這是一家互聯(lián)網(wǎng)公司,整個(gè)網(wǎng)站99%的代碼是php,基本上沒有java。沒有專門的前端工程師,php、html和javascript代碼混在一起。測試幾乎等于沒有,基本都是開發(fā)人員自測。上線流程只是個(gè)形式,質(zhì)量控制部門唯二的作用就是向服務(wù)器上同步代碼和出現(xiàn)事故之后給開發(fā)人員定責(zé)任。我曾經(jīng)和另一個(gè)部門合作,他調(diào)用我提供的接口,而他在我的接口沒上線的時(shí)候就上線了,導(dǎo)致一場事故。我本來是算法工程師,寫php只是客串,而在這個(gè)過程中,沒有任何上線依賴的控制,連提示也沒有,甚至沒有人對我進(jìn)行上線流程的培訓(xùn)。然而,這是一家中等規(guī)模的互聯(lián)網(wǎng)公司,己經(jīng)發(fā)展了十來年,占據(jù)了所在細(xì)分市場領(lǐng)域的頭號(hào)份額,并且己經(jīng)上市。
我舉這個(gè)例子并不是要黑它,而是想用事實(shí)支持上面的觀點(diǎn):大部分程序員,大部分所謂的“科技”公司,所面臨的技術(shù)問題比想象的要少的多(這也許是那家公司沒有CTO的原因)。
這不是個(gè)別情況,大多數(shù)公司都存在類似的問題——從技術(shù)角度看,它就是個(gè)渣,你會(huì)很奇怪它怎么還沒死。然而事實(shí)是,它不但沒死,反而活的生機(jī)勃勃,甚至上市了。公司的擁有者們早已實(shí)現(xiàn)了屌絲逆襲迎娶白富美的理想,而辱罵他們的程序員們還在苦苦的為房貸或者首付掙扎。這里面,有大量的非技術(shù)因素起著關(guān)鍵作用,盡管它們都自稱科技公司。
越來越多的人意識(shí)到了技術(shù)的局限性。年初,一個(gè)同學(xué)找工作,他向來是個(gè)“純技術(shù)流”的工程師,曾經(jīng)寫過很好的技術(shù)博客,甚至發(fā)起過開源項(xiàng)目。然而這次他說,“不想再做最底層的工程師了”,希望能做一些“高層的、能看到項(xiàng)目整體的”、以及“和人打交道,能夠把自己的想法向外推動(dòng),并產(chǎn)生價(jià)值”的工作。于是,他去某公司負(fù)責(zé)帶幾個(gè)小弟去了。當(dāng)我把這些轉(zhuǎn)述給另一個(gè)同學(xué)的時(shí)候,他的反應(yīng)是“我最近也有這樣的想法”。還有個(gè)同學(xué),說寫了幾年C++,技術(shù)上沒學(xué)到多少,反而是接觸的業(yè)務(wù)知識(shí)比較多。再比如我之前的leader,他是數(shù)學(xué)博士出身,曾經(jīng)對算法有一種近乎天真的信仰;在我離職的時(shí)候,他已經(jīng)完全轉(zhuǎn)型為業(yè)務(wù)和產(chǎn)品導(dǎo)向了。而某個(gè)幾年前就開始淡化技術(shù),聚會(huì)時(shí)大講“軟實(shí)力”的同學(xué),早已在BAT做了Team Leader,生活滋潤,終日以跑步為樂。為何?其實(shí)原因很簡單:公司里沒有那么多技術(shù)問題需要解決。
《代碼大全》里有個(gè)比喻,如果你的問題是給自己的愛犬造一個(gè)小窩,那么動(dòng)手做就是了,如果出了什么錯(cuò)誤,大不了重做一個(gè),最多浪費(fèi)一下午的時(shí)間。而造一個(gè)摩天大樓就不同了。所以,如果寫一份“狗窩”級(jí)別的程序,算法、數(shù)據(jù)結(jié)構(gòu)、設(shè)計(jì)模式這些又有多大意義呢?甚至違反了DRY原則也沒關(guān)系,反正一段代碼也拷貝不了幾次,出了bug就改,大不了重寫一次,最多浪費(fèi)一下午。而且,說不定這個(gè)項(xiàng)目兩周之后就被砍掉了。如果你做的是一份“造狗窩”的工作,就算你有造摩天大樓的技術(shù),和屠龍之技又有什么分別呢?唯一的“好處”就是你會(huì)據(jù)此向老板提出更多的加薪要求,以至于老板對你“另眼相看”。
程序員應(yīng)當(dāng)破除對技術(shù)不切實(shí)際的幻想——這不是說技術(shù)不重要,而是說要實(shí)事求是的分清,哪些是造狗窩的工作,哪些是建普通樓房的工作,哪些是造摩天大樓的工作。
再談算法
同理,算法工程師應(yīng)當(dāng)破除對算法不切實(shí)際的幻想,把注意力集中到數(shù)據(jù)的理解、清洗、預(yù)處理、人肉特征、業(yè)務(wù)應(yīng)用(而這些往往和屌絲、苦逼等形容詞聯(lián)系在一起)上來。
未來,機(jī)器學(xué)習(xí)工具將更加標(biāo)準(zhǔn)化、平臺(tái)化、通用化,并且進(jìn)一步降低使用門檻。與算法本質(zhì)無關(guān)的工程細(xì)節(jié),比如數(shù)據(jù)存儲(chǔ)方式、梯度下降過程、并行化、分布式計(jì)算等,將被制造“輪子”的程序員們屏蔽。算法工程師可能只需用類似Hive的方式,寫幾個(gè)類似SQL的語句就可以完成模型的訓(xùn)練、交叉驗(yàn)證、參數(shù)優(yōu)化等工作。
而機(jī)器唯一不能替代的就是對數(shù)據(jù)的理解,這是算法工程師存在的價(jià)值。而數(shù)據(jù)是和業(yè)務(wù)強(qiáng)相關(guān)的,算法工程師將更加接近產(chǎn)品經(jīng)理的角色,而不是程序員。深入理解數(shù)據(jù)、業(yè)務(wù)和產(chǎn)品,尋找模型和它們的結(jié)合點(diǎn),將成為算法工程師的核心競爭力。
插一句,相對于本文的觀點(diǎn),Deep Learning在某種程度上是一種的例外。它試圖解決特征工程的問題,也就是在某種程度上代替人提取特征。當(dāng)然,它還比較初級(jí),另外它最多只能解決特征變換問題,仍然處理不了數(shù)據(jù)清洗和預(yù)處理中需要用到領(lǐng)域知識(shí)的情況。
這里劉同學(xué)提出一個(gè)問題,那就是算法工程師對算法需要理解到何種程度?事實(shí)是,即使從算法的應(yīng)用出發(fā),工程師也需要掌握模型的優(yōu)缺點(diǎn)、適用場景、模型選擇、參數(shù)調(diào)優(yōu)等技術(shù)。這是毫無疑問的,從這一點(diǎn)上說,算法工程師需要一定的技術(shù)能力,這點(diǎn)又和產(chǎn)品經(jīng)理不同。
但是這就有另外一個(gè)問題:模型選擇和參數(shù)調(diào)優(yōu)技術(shù),是否是通用的?還是和具體的數(shù)據(jù)高度相關(guān)的?比如,是否存在這樣的現(xiàn)象,同樣的調(diào)優(yōu)技術(shù),在(比如說)電商數(shù)據(jù)上表現(xiàn)很好,到了社交數(shù)據(jù)上就不行了?這個(gè)問題我暫時(shí)沒有答案,如果誰知道,請告訴我。不過,一個(gè)現(xiàn)象是,目前做機(jī)器學(xué)習(xí)模型相關(guān)的項(xiàng)目,在改進(jìn)的時(shí)候,基本上都采用試錯(cuò)的方式,就是先做出改動(dòng),然后上線觀察效果;如果不好,就換種方法;如果效果有所改進(jìn),也往往沒有人知道為什么。如果存在一種通用的判斷模型優(yōu)劣的技術(shù),我們?yōu)槭裁催€要采取這種近乎窮舉的方式呢?
從“IT精英”到“IT民工”或者“碼農(nóng)”,這種稱呼上的轉(zhuǎn)變并非笑談,而是真實(shí)的反應(yīng)了計(jì)算機(jī)編程領(lǐng)域門檻逐步降低的過程。所以,我們應(yīng)當(dāng)給聽上去高大上的“算法工程師”或者“數(shù)據(jù)科學(xué)家”起一個(gè)類似的外號(hào),比如“數(shù)據(jù)民工”、“機(jī)農(nóng)”或者“蒜農(nóng)”之類,以免不明真相的孩子們被“高大上”的稱號(hào)吸引而誤入歧途。
其它
看的出我是一個(gè)比較純粹的技術(shù)人員,因?yàn)閷τ诜羌夹g(shù)的東西,我了解不夠,說不出那是什么,只能用“其它”一詞概括。
這“其它”,基本上是“人”的問題——比如前面提到的“如何推動(dòng)自己的想法”,“軟實(shí)力”之類,大的包括機(jī)遇,小到“發(fā)郵件應(yīng)該抄送給誰”這種細(xì)節(jié)。
當(dāng)然,如果你是個(gè)對技術(shù)本身感興趣的人,這些討論不適用,因?yàn)閷τ谶@類人,技術(shù)本身就是目的,不是手段。這里的視角,僅僅是社會(huì)普遍意義上的職業(yè)發(fā)展角度。無論是想在公司內(nèi)部獲得升遷,還是通過跳槽而得到晉升,還是自行創(chuàng)業(yè)而實(shí)現(xiàn)人生目標(biāo),技術(shù)都只是你的一種技能。如果再想想大部分公司里提供的是一份“造狗窩”級(jí)別的職位,這種技能起的作用又有多大呢?
不過多說一句,要求程序員“對技術(shù)感興趣”,甚至“在業(yè)余時(shí)間以寫代碼為消遣”,是一種相當(dāng)荒謬的事情。試想,招聘銷售人員的時(shí)候,從未有人要求求職者“對喝酒應(yīng)酬感興趣”;招聘財(cái)務(wù)人員的時(shí)候,也沒有人要求“對加減數(shù)字感興趣”;招聘外科醫(yī)生的時(shí)候,也絕不會(huì)要求“平時(shí)以解剖人體為消遣”。為什么程序員這種職業(yè)就要搞特殊?
究其原因,大概是大家還沉浸在對技術(shù)的一種非理性崇拜之中(當(dāng)然崇拜和褻瀆往往并存)——“技術(shù)改變世界”這句話常常被提到。這句話沒錯(cuò),但是要搞清楚,“技術(shù)改變世界”不等于“每一項(xiàng)技術(shù)都能改變世界”,更不等于“每一個(gè)技術(shù)人員都能改變世界”。其實(shí),程序員這一行和其它任何一個(gè)需要專業(yè)技能的行業(yè)沒什么區(qū)別,只是一種謀生的手段而已。
大部分所謂的“科技公司”也并不是真正的科技公司,頂多是“使用科技的公司”。其實(shí),在金融領(lǐng)域,對IT的要求要高多了,各大銀行也有自己的軟件開發(fā)部門,但是沒人把它們歸到IT行業(yè),而是屬于金融行業(yè)。然而,那些開商店的,開飯店的,賣房子的,給人說媒的,集資的,他們似乎只要做個(gè)網(wǎng)站,就成了“科技公司”了,這難道不是很荒謬嗎?(當(dāng)然,像亞馬遜這種從一個(gè)賣書的起家,居然后來搞起了云計(jì)算、推薦系統(tǒng)、無人飛行器等技術(shù)創(chuàng)新的,不在此列。)在這些公司當(dāng)中,技術(shù)到底起多大作用呢?
也許相當(dāng)一部分程序員們會(huì)自以為技術(shù)很重要,他們沉浸在對技術(shù)的憧憬和信仰中,內(nèi)心深處堅(jiān)定的相信自己可以通過技術(shù)能力的提升,來謀取更高的職位,走向人生巔峰。然而,大多數(shù)時(shí)候這只是一種自欺欺人的幻想罷了。天朝的程序員們有一種矛盾心態(tài),一方面自稱“民工”,認(rèn)為編程是一種只適合30歲之前的年輕人從事的體力勞動(dòng),而另一方面卻又把技術(shù)看的非常重要,甚至在業(yè)余時(shí)間也喜歡大談技術(shù),或者以攻擊其他程序員使用的技術(shù)為樂。如此抱著技術(shù)不放,并不是因?yàn)槎嗝礋釔奂夹g(shù),而是因?yàn)樗麄冎粫?huì)技術(shù)。沒有人愿意在別人面前展示自己的劣勢。把技術(shù)的地位抬的越高,仿佛自己就顯得越重要,而那些在需要人際交往、推動(dòng)自己的想法、和產(chǎn)品經(jīng)理討論需求的時(shí)候所表現(xiàn)出的能力低下,似乎就不重要了。
這是人性的弱點(diǎn)——對自己某種能力盲目而過分的自信,甚至把它作為自己的精神支柱。也許他在這個(gè)方面的確很擅長,但是自我評(píng)估卻比實(shí)際更高。誠然,自信是必要的,也是人生存和立足的精神基礎(chǔ)之一。然而自信是把雙刃劍——不切實(shí)際的自信(也許應(yīng)該叫自大了),會(huì)蒙蔽人的雙眼,扭曲事實(shí)。
那么我們應(yīng)該怎么做呢?首先比較悲觀的一點(diǎn)是,如果你從事著一份技術(shù)上處于“造狗窩”級(jí)別的工作,那么很遺憾,提高自己的技術(shù)水平恐怕對于在公司內(nèi)部的職業(yè)發(fā)展沒什么幫助。
如果你是一個(gè)真正對技術(shù)有興趣的人,可以考慮一下《黑客與畫家》里提到的一類“真正的程序員”的工作方式:他們求的一份“白天的工作”,這份工作僅僅用來生存,而在業(yè)余時(shí)間寫一些“真正有價(jià)值”的代碼。
恐怕大部分程序員都不是對技術(shù)有興趣的吧?如果你的目標(biāo)是事業(yè)上的發(fā)展,無非是跟人混和創(chuàng)業(yè)兩種方式。跟人混,要么內(nèi)部晉升,要么通過跳槽。前者需要老板認(rèn)為你牛逼;后者需要?jiǎng)e的公司的老板認(rèn)為你牛逼。注意,這里有個(gè)關(guān)鍵詞“認(rèn)為”,因?yàn)槿说闹饔^印象和客觀事實(shí)之間總是有差距的,而且這個(gè)差距往往超乎人的想象。所以重點(diǎn)是制造一種“牛逼”的印象,而實(shí)際上牛不牛逼并不重要,牛逼更好,不牛逼也可。
如果你想走技術(shù)路線,可以考慮去找一份“建造大樓”級(jí)別的工作,在那里,技術(shù)成為決定產(chǎn)品成敗的主要因素。這種級(jí)別的項(xiàng)目,一般只有大公司做的起。老板對于員工技術(shù)能力的評(píng)估,還是比較容易做到客觀的,因?yàn)榇a在那里,牛不牛逼,一運(yùn)行便知。但是對于所謂“軟實(shí)力”,往往就不好評(píng)判了,主觀性很大。
也正因如此,往往有很多人覺得自己很牛逼,而老板不這么認(rèn)為(錯(cuò)的不一定是老板,也可能是這個(gè)人自大),所以一怒之下走上創(chuàng)業(yè)的道路。自己給自己當(dāng)老板,終于不用在意老板的印象和事實(shí)之間的差距。然而這條路往往更為艱難,它對人的綜合素質(zhì)要求比較高。如果一個(gè)程序員在工作中不能和同事順利的合作,那很難想象他能夠滿足創(chuàng)業(yè)者所需要的各種素質(zhì)。所以,要走這條路,得有心理準(zhǔn)備。
總結(jié)
技術(shù)是為人服務(wù)的,IT業(yè)的發(fā)展過程,是在逐步降低計(jì)算機(jī)的使用門檻,使得越來越多的人能夠使用這種工具。這是好的,但它同時(shí)也降低了程序員這種職業(yè)的技術(shù)含量。如果真的想做技術(shù),那么去做一些真正的技術(shù)。否則,就需要多多關(guān)注技術(shù)以外的東西,單純寄希望于技術(shù),只能用來安慰自己,而不能獲得真正的職業(yè)發(fā)展。
-
工程師
+關(guān)注
關(guān)注
59文章
1571瀏覽量
68607
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論