從全棧工程師到數(shù)據(jù)科學(xué)家,入職第一年我都做了些什么?
萬(wàn)事開頭難,從一個(gè)軟件開發(fā)程序員轉(zhuǎn)型為數(shù)據(jù)科學(xué)家,第一年該怎么做?
一位博主就記錄了自己從全棧工程師轉(zhuǎn)行數(shù)據(jù)科學(xué)家第一年的心路歷程,包括好的方面和不好的方面,希望能幫助到同樣處境的人。
我覺得自己非常幸運(yùn),雇主給了我一個(gè)機(jī)會(huì),讓我從一個(gè)全棧軟件開發(fā)人員轉(zhuǎn)型變成數(shù)據(jù)科學(xué)家,和內(nèi)部數(shù)據(jù)團(tuán)隊(duì)一起工作。
入職一年,我很享受這份工作給我?guī)淼娜绿魬?zhàn),完全不同于以前做開發(fā)。我想寫這篇文章,首先是為了回顧過去一年所做的事情:我經(jīng)歷的改變,我做得好的地方,我可以改進(jìn)的地方。第二,通過記錄我曾經(jīng)遇到過的問題和挑戰(zhàn),我希望能幫助到和我處境相似的人。
在開始之前,我先介紹一下我的背景:我之前不是做軟件開發(fā)的,我擁有計(jì)算機(jī)科學(xué)的碩士學(xué)位和博士學(xué)位。因此,我不算冷啟動(dòng),我有工具、模型和分析方法方面的相關(guān)經(jīng)驗(yàn)。我從事開發(fā)工作將近8年。自從我的論文發(fā)表以后,我經(jīng)歷了很多變動(dòng)。
本文將分為兩部分。進(jìn)展順利的部分和進(jìn)展不佳的部分。對(duì)于那些只對(duì)結(jié)果感興趣的人,也可以拉到底直接看最后的結(jié)論。
進(jìn)展順利的方面Python 和 R
剛開始,我不確定在項(xiàng)目中該使用Python或R。所以一開始我對(duì)這兩種語(yǔ)言均作了研究學(xué)習(xí),并在項(xiàng)目中結(jié)合使用了這兩種語(yǔ)言。
R經(jīng)常讓我想起Matlab,兩者在用來編寫和執(zhí)行代碼的界面非常像(我嘗試了R Studio和Visual Studio的R插件),同時(shí)寫代碼和處理數(shù)據(jù)的方法也很像。
但我只在碩士論文中用了R,還在博士學(xué)位論文中用了一些。除此之外,R和其他編程語(yǔ)言相比(這些年來,我在軟件開發(fā)中經(jīng)常使用C#)就沒什么共性了。R這個(gè)工具極度以數(shù)據(jù)為中心,與數(shù)據(jù)進(jìn)行交互的方法也很不一樣。
在R里有:列表,矩陣,向量,數(shù)組和數(shù)據(jù)幀。每個(gè)都有不同的使用場(chǎng)景,你需要學(xué)會(huì)什么時(shí)候使用。R與C#的語(yǔ)法很不一樣,所以剛開始學(xué)R我遇到了不小的困難。我并不是說R不好,只是我使用Matlab10年,并且作為開發(fā)我的腦子已經(jīng)習(xí)慣了某種思維方式,所以比較難轉(zhuǎn)變。所以我剛開始的時(shí)候覺得R很難上手。
作為一名有8年C#開發(fā)經(jīng)驗(yàn)的程序員,我覺得Python比R更容易起步。很可能是因?yàn)槲业拇竽X已經(jīng)習(xí)慣了C#的思維方式。python比R更接近于C#,所以我學(xué)Python比R快很多。
在使用這兩個(gè)語(yǔ)言時(shí),我沒覺得兩者有明顯區(qū)別,尤其是對(duì)于可用的庫(kù),兩者在我想做的工作的實(shí)現(xiàn)方面有差不多的處理能力,我也會(huì)得到相同的結(jié)果。但在摸索過程中,我對(duì)兩個(gè)工具分別都有些困惑。
總的來說,編程編久了,Python對(duì)于我的程序員思維更友好。
所以我很快放棄了學(xué)習(xí)R,轉(zhuǎn)而專注Python。這有助于我更快地進(jìn)步,不必再花時(shí)間閱讀新語(yǔ)法,事情變得簡(jiǎn)單許多,我一直覺得簡(jiǎn)單才是王道。這對(duì)我應(yīng)對(duì)角色的許多其他變化也是有幫助的,因此,這樣做可以最大程度地減少更改。
關(guān)于使用哪種以及何時(shí)使用,我敢肯定大家定對(duì)此有很多意見,但是對(duì)我來說,從開發(fā)人員過渡到數(shù)據(jù)科學(xué)家后,我發(fā)現(xiàn)Python變得更容易掌握和使用,尤其是在我擔(dān)任新職位后想快速發(fā)展并取得成果的初期。
所以與R相比,使用Python讓我更快進(jìn)入狀態(tài),在輸出方面,我沒有發(fā)現(xiàn)兩者有任何明顯區(qū)別。所以我把這個(gè)歸類為進(jìn)展順利,因?yàn)槲液茉缱龀隽藳Q定,且至今沒有遇到任何情況讓我覺得自己選錯(cuò)了Python,相反我節(jié)省了不少時(shí)間,所以我能更快地開始工作。
文檔記錄
記錄一切,我定義的一切是從模型超參數(shù)到從何處以及如何獲得訓(xùn)練數(shù)據(jù),到在整個(gè)項(xiàng)目中做出選擇的理由。另外,以有序的邏輯方式編寫文檔,實(shí)現(xiàn)這一目標(biāo)的一個(gè)秘訣是,哪怕你只是寫給自己看(例如,在我的情況下,我是唯一的數(shù)據(jù)科學(xué)家),你應(yīng)該想象有人會(huì)讀這份文檔。
此外,記錄時(shí)要對(duì)自己有一定的約束,不要拖拉,不要走捷徑。不然等你開始寫的時(shí)候,你可能已經(jīng)忘記一些需要注意的細(xì)節(jié)。因此一定要及時(shí)寫下來。在完成文檔之前,我覺得工作就還沒做完。我從一開始就遵循這種方法,我覺得至關(guān)重要。
我發(fā)現(xiàn)一件事是,即使在一個(gè)中型企業(yè),等到一個(gè)項(xiàng)目的研究成果在公司開始推廣已經(jīng)是一段時(shí)間以后了,利益相關(guān)方因?yàn)橛衅渌乱?,所以不?huì)立刻作出回應(yīng)。
有時(shí)候在我完成一個(gè)項(xiàng)目幾個(gè)月后,有人跑來問我問題,我一時(shí)想不起來,但如果我翻看我之前做的文檔記錄就能馬上提供詳盡答案。例如,有一次我與另一位經(jīng)理聊起幾個(gè)月前做的一個(gè)項(xiàng)目,我向他展示了我已經(jīng)完成的工作,他問我訓(xùn)練集的大小是多少,以及我用來獲取數(shù)據(jù)的日期區(qū)間。我并記不得那些數(shù)據(jù),但我記得自己已經(jīng)寫下過,而且我也記得寫在了哪里。所以我能馬上把文檔拿給他們看。
我發(fā)現(xiàn)自己遇到的另一種情況是當(dāng)業(yè)務(wù)優(yōu)先級(jí)發(fā)生變化,你可能會(huì)需要停下手頭還沒完成的項(xiàng)目去做另一個(gè)項(xiàng)目。當(dāng)你再回到之前開始的項(xiàng)目時(shí),完整的文檔可以讓你從之前停下的地方繼續(xù)進(jìn)行下去。
不順利的一面數(shù)據(jù)存儲(chǔ)
回顧前一年,進(jìn)展不順利的一個(gè)原因是我處理數(shù)據(jù)的方式(對(duì)于數(shù)據(jù)科學(xué)家而言這非常關(guān)鍵)。
當(dāng)我沒有使用數(shù)據(jù)庫(kù)的經(jīng)驗(yàn)時(shí),我基本上復(fù)用了在博士期間使用數(shù)據(jù)的方式。使用平面文件(特別是CSV)來存儲(chǔ)數(shù)據(jù)。我把從生產(chǎn)環(huán)境中提取的初始數(shù)據(jù),清洗后的中間過程數(shù)據(jù),分析后的數(shù)據(jù)和結(jié)果都存在了CSV里。我工作流程中的每一步驟都需要通過Python腳本讀取上一步創(chuàng)建的文件,并創(chuàng)建新的文件。
這種把內(nèi)容存儲(chǔ)在硬盤上,并通過Python腳本與數(shù)據(jù)交互的原始辦法,很快就出現(xiàn)了一些問題:
有時(shí)很難在大量文件中找到我要找的那個(gè)文件。即使我記錄了文件的內(nèi)容和位置,但有時(shí)還是很難找到我想要的確切文件,因?yàn)槲募?shí)在太多了。
我似乎總是在忙著用Python把從文件中讀取數(shù)據(jù)或者將數(shù)據(jù)寫入文件。我寫了很多文件訪問的命令,但其實(shí)是在做重復(fù)勞動(dòng),寫這些代碼對(duì)我要做的工作并沒什么幫助。
想快速地將數(shù)據(jù)總結(jié)一下似乎都有點(diǎn)費(fèi)力:讀取數(shù)據(jù),匯總統(tǒng)計(jì),輸出統(tǒng)計(jì),查看統(tǒng)計(jì)結(jié)果。
有些文件很大,用起來很困難(在notepad中打開10GB以上的文件很麻煩)。
第一年,我花了很長(zhǎng)時(shí)間才意識(shí)到SQL是我的解藥。
在從事數(shù)據(jù)科學(xué)家工作之前我使用過SQL,但是我一開始沒有意識(shí)到它對(duì)我的價(jià)值。當(dāng)我意識(shí)到SQL就是我的解決方案后,我花了很多時(shí)間來學(xué)習(xí)更多有關(guān)SQL的知識(shí),因?yàn)槲以谧龀绦騿T的時(shí)候稍微學(xué)了一點(diǎn)SQL。
具體來說,我學(xué)習(xí)了如何查詢數(shù)據(jù)(特別是我以前沒接觸過的高級(jí)語(yǔ)句)以及搭建和維護(hù)數(shù)據(jù)庫(kù)的基礎(chǔ)知識(shí)。我甚至通過了兩個(gè)Microsoft SQL的考試。我現(xiàn)在主張盡可能用SQL。我把所有項(xiàng)目的數(shù)據(jù)都存在了SQL數(shù)據(jù)庫(kù)中,盡量在SQL中做數(shù)據(jù)查詢和操作。
我的原則是:能在SQL中完成的處理,就在SQL中做。SQL處理不了的任務(wù)再用Python(例如,模型訓(xùn)練和執(zhí)行)這里延伸出一個(gè)問題:你需要學(xué)會(huì)使用Python庫(kù),例如 SQLAlchemy,從 SQL讀取數(shù)據(jù)到Python里。
現(xiàn)在我的后SQL生活變得容易很多:
所有項(xiàng)目數(shù)據(jù)存儲(chǔ)在一個(gè)容易找到的地方。
沒有重復(fù)代碼用于讀寫文件。
我能快速查詢數(shù)據(jù)并從數(shù)據(jù)中輕松得到統(tǒng)計(jì)結(jié)果。
我能夠很容易地查看大量數(shù)據(jù),特別是前幾行的數(shù)據(jù)。
額外的好處是現(xiàn)在很容易把不同的數(shù)據(jù)聯(lián)系起來,因?yàn)閿?shù)據(jù)都已經(jīng)在關(guān)系數(shù)據(jù)庫(kù)中了,現(xiàn)在安全性也提高了:把數(shù)據(jù)存在本地磁盤上有潛在的風(fēng)險(xiǎn)。數(shù)據(jù)都在服務(wù)器里,安全很多。
因此,我強(qiáng)烈推薦學(xué)好SQL并用起來。
如何展示成果?
還有一個(gè)進(jìn)展不順利的地方是我做的一些展示。從開發(fā)人員到數(shù)據(jù)科學(xué)家的一個(gè)變化是,我做演示的場(chǎng)合變多。展示的內(nèi)容各種各樣,有面向技術(shù)人員的demo演示,有面向業(yè)務(wù)相關(guān)人員的項(xiàng)目報(bào)告,再到與公司內(nèi)部其他部門討論項(xiàng)目工作,甚至向公司外部的第三方合作方展示工作。
對(duì)于這些人我覺得我沒有做好的一點(diǎn)是我沒有根據(jù)受眾來調(diào)整自己的展示方法。有些展示我做得還不錯(cuò),比如對(duì)開發(fā)人員的技術(shù)演示我覺得我做得還不錯(cuò)。因?yàn)槲腋夹g(shù)人員擁有差不多的背景所以說技術(shù)的內(nèi)容彼此也聽得懂,交流起來會(huì)更容易一些。其他類型的演示更難一些,不幸地是很多時(shí)候我在展示的時(shí)候才意識(shí)到聽眾對(duì)我講的內(nèi)容不是很在意。
我的受眾分為四類,從展示的難易程度來分如下:從最簡(jiǎn)單的(最左邊)開始,到最難的(最右邊):開發(fā)人員,業(yè)務(wù)方,其他部門以及外部人員。
我還可以將最左邊的那些受眾標(biāo)記為最技術(shù)性的,將右邊的那些受眾標(biāo)記為更“銷售型”的,當(dāng)從左向右移動(dòng)時(shí),兩者之間會(huì)有一個(gè)過渡。我發(fā)現(xiàn)針對(duì)左邊受眾的展示是最容易準(zhǔn)備的——他們對(duì)我正在使用的技術(shù)或所從事的業(yè)務(wù)領(lǐng)域有深刻的了解。
針對(duì)外部人員的演示是最難的,因?yàn)樗麄兺嚓P(guān)知識(shí)最少。過去,我與這些聽眾進(jìn)行交流的時(shí)候會(huì)直接進(jìn)入到技術(shù)細(xì)節(jié),就像我和左邊聽眾交流時(shí)一樣,但是結(jié)果很不好,因?yàn)樗麄儾灰欢ň哂腥魏螖?shù)據(jù)科學(xué)或機(jī)器學(xué)習(xí)的背景,所以我談?wù)撛S多概念對(duì)他們沒有多大意義,他們不知道我在說什么。對(duì)這些受眾來說,如果我花點(diǎn)時(shí)間介紹一下我正在做的工作以及更多的背景知識(shí),效果會(huì)更好。甚至對(duì)某些受眾來說,向他們介紹機(jī)器學(xué)習(xí)的概念,為什么我們要使用它以及它的好處。有時(shí)候,對(duì)我來說,不過多討論技術(shù)細(xì)節(jié)反而是好事,給他們一些大概的框架概念就好。
在反思了這一點(diǎn)之后,我現(xiàn)在在準(zhǔn)備演示材料時(shí),會(huì)更多地考慮我的目標(biāo)受眾。具體來說,我會(huì)考慮聽眾可能知道或不知道的內(nèi)容,以及需要向他們呈現(xiàn)的內(nèi)容,以幫助我準(zhǔn)備需要討論的內(nèi)容和專業(yè)程度。這樣他們就可以更好地理解我正在談?wù)撌裁?,并從演示中得到一些收獲。為此,在準(zhǔn)備演示文稿時(shí)我為自己準(zhǔn)備了一些有用的問題,如下:
聽眾對(duì)于數(shù)據(jù)科學(xué)領(lǐng)域了解多少?
聽眾對(duì)于我試圖解決的問題了解多少?
聽眾知道我在使用的技術(shù)嗎?
聽眾對(duì)于我采用的技術(shù)細(xì)節(jié)或者結(jié)果感興趣嗎?
計(jì)劃
與做程序員時(shí)相比,做數(shù)據(jù)數(shù)據(jù)家的工作計(jì)劃更有挑戰(zhàn)。作為開發(fā)人員,工作相對(duì)比較直接,所以也更好估算和排期。你通常知道你要實(shí)現(xiàn)的目標(biāo)以及如何實(shí)現(xiàn)。當(dāng)我還是一名開發(fā)人員的時(shí)候,我使用敏捷開發(fā)工具。
因此,工作內(nèi)容可以先評(píng)估、計(jì)劃,然后排好優(yōu)先級(jí)就開始做。在敏捷的方法論指導(dǎo)下,如果工作沒什么意義,或者你不清楚如何做,你就不會(huì)把它排進(jìn)工作計(jì)劃。因?yàn)闊o法評(píng)估,因?yàn)槲粗?,你要等到所有不明確的地方明確后才開展工作。
數(shù)據(jù)科學(xué)的工作并不像這樣簡(jiǎn)單,對(duì)于給定的問題你不會(huì)總是提前知道什么會(huì)起作用。也不會(huì)總是知道哪種類型的模型最準(zhǔn)確。類似這樣的情況與剛才提出的觀點(diǎn)出現(xiàn)矛盾,當(dāng)你是開發(fā)人員時(shí),只有問題明確后,你才會(huì)把他們放入你的工作列表中。作為數(shù)據(jù)科學(xué)家,未知是你工作的一部分,因?yàn)槟愕墓ぷ骶褪且卮疬@些問題。或者你正在處理的問題可能會(huì)隨著項(xiàng)目進(jìn)展而改變。因此,有時(shí)候你提前做的幾周計(jì)劃可能很快要重新考慮。
在計(jì)劃方面,我喜歡將開發(fā)工作視為線性的——你知道自己在做什么以及如何做。數(shù)據(jù)科學(xué)工作我覺得是分叉樹,可能需要試不同的道路,可能會(huì)碰到死胡同。
數(shù)據(jù)科學(xué)家做短期工作計(jì)劃還是可行的,比如你正在訓(xùn)練和測(cè)試的模型之類的——接下來一兩周的工作,但是,長(zhǎng)期計(jì)劃很難做。你不可能總是提前知道什么會(huì)起作用,什么不會(huì)。所以我們才要進(jìn)行實(shí)驗(yàn)和測(cè)試,這是數(shù)據(jù)科學(xué)家工作的核心價(jià)值。
最后,花點(diǎn)時(shí)間去做不一定會(huì)有成果的工作,即使不起作用,也沒什么大不了的。
回答正確的問題
在過去一年中(這讓我栽過很多跟頭),我發(fā)現(xiàn)數(shù)據(jù)科學(xué)工作的關(guān)鍵部分是回答問題,但更重要的是回答正確的問題。
正如我所說,我栽過幾次跟頭,當(dāng)時(shí)我正在回答一個(gè)問題,但并沒有回答業(yè)務(wù)方實(shí)際想要回答的問題,之所以發(fā)生這種情況,是因?yàn)闃I(yè)務(wù)方使用的業(yè)務(wù)語(yǔ)言跟我用的的技術(shù)語(yǔ)言有差異,有時(shí)候我們用一樣的詞但要表達(dá)的意思卻不同。
針對(duì)這問題我的解決方法是在做項(xiàng)目的實(shí)際工作(現(xiàn)在稱為“項(xiàng)目前”工作)之前先做準(zhǔn)備性工作,在這個(gè)階段,我會(huì)從業(yè)務(wù)方那里收集初始需求和信息。做一些初步分析,然后給業(yè)務(wù)方展示。
運(yùn)用敏捷的工作思路,我希望在每個(gè)sprint實(shí)現(xiàn)一個(gè)可交付的成功,并向業(yè)務(wù)方展示該成果。這樣,我與業(yè)務(wù)方建立了一個(gè)有效的循環(huán)反饋機(jī)制,向他們展示一些東西并詢問他們的意見,這可以建立一個(gè)有效對(duì)話,從而更清晰地定義真正要解決的問題。這個(gè)方法在項(xiàng)目各個(gè)階段都有效,不僅僅是初始階段。當(dāng)你向業(yè)務(wù)方展示你的工作結(jié)果時(shí),可能會(huì)激發(fā)他們不同的想法以及他們之前沒有考慮過的思路。從而你能找到他們真正的痛點(diǎn)。
所以過去一年來我發(fā)展的一項(xiàng)關(guān)鍵技能是與業(yè)務(wù)方的互動(dòng)交流,深入挖掘他們真正想要的東西。
總結(jié)Python比R更容易學(xué)習(xí),因?yàn)閷?duì)于程序員來說python與其他編程語(yǔ)言更接近。
邊執(zhí)行邊做文檔
學(xué)習(xí)如何使用關(guān)系數(shù)據(jù)庫(kù),比如SQL,用數(shù)據(jù)庫(kù)來查詢,操縱和存儲(chǔ)數(shù)據(jù)。
你需要準(zhǔn)備很多展示,不僅是向項(xiàng)目業(yè)務(wù)方的報(bào)告,還要向公司其他同事報(bào)告,甚至是公司外面的人。
你需要提高演講能力以滿足不同受眾(技術(shù)或非技術(shù))的需求。
工作計(jì)劃不是一帆風(fēng)順的,因?yàn)槟銦o法預(yù)知什么起作用什么無效,要有心理準(zhǔn)備有時(shí)候花了時(shí)間不一定取得預(yù)想的結(jié)果。
花時(shí)間找你真正要解決的問題,不要不加思考就埋頭開始做,與業(yè)務(wù)方建立反饋閉環(huán)是很有必要的。