弱弱開發女子 / 機器學習虛心學系列

專案經理、高階管理人都應該要知道的:機器學習專案的基本流程。

Hands-on ML with Sklearn and Tensorflow Chapter 2: End-to-End Machine Learning Project / 第1篇

Yijhen L.
Yijhen L.
Jul 18, 2019 · 15 min read

以下內容皆出自於<Hands-On Machine Learning with Scikit-Learn and TensorFlow by Aurélien Géron>這本書,我只是讀過,然後把其中的精華摘要出來而已。

如求學習成效更完美,建議購買原文書籍


一個機器學習專案的流程,基本應該要有以下八大步驟:

當然,根據案例及需求的不同,可以把流程做一些調整或補足的。

1. 框架問題

第一件事情要問你的老闆:業務目標是什麼?這個目標可能是為了讓產品使用者有更好的使用體驗,可能是為了增加作業效率以降低人力成本,可能是為了協助商業策略更加精確,也可能只是為了好玩。不同的目標,會影響隨後決定使用哪些機器學習模型、哪些評測標準、還有要花多少力氣跟時間解決中間遇到的問題。

你可以向老闆了解一下現有的解決方法是什麼。譬如廣告投放標的的預測,目前都是根據點擊率資料跟市場條件讓專員決定投放標的,而專員的預測錯誤率大約是15%。了解這些訊息,能夠幫助你評估導入機器學習後的效果會如何。

接著,你可以開始考慮要要選擇哪種機器學習模型。要採用監督式學習非監督式學習,還是強化學習?這是分類問題回歸問題,還是其他?這是系統預計是要線上學習?還是離線學習

網路上已經有很多整理好的資源,教你如何選擇機器學習模型。就列在這邊做參考。

選擇如何評估機器學習的效能。打個比方,對回歸問題而言,常見的評估方法是採用兩種公式 Root Mean Square Error (RMSE) 或 Mean Absolute Error (MAE)。而不同的機器學習系統,評估效能的公式也會有所不同,這裡就不多著墨。

最後,記得列出你們目前為止所有的假設,並且去確認這些假設。譬如房地產估價,你們認為這是一個回歸問題。此外,因為你們有 label 資料,所以可以進行監督式學習。再來,因為這些資料並不是一直持續在流入的,所以採用線下學習的方式就可以了。

但是這些都算是你們的假設。跟公司內部確認清楚後,才發現下游部門需要的只是評估房地產的價位是屬於「高階款」、「中階款」、「入門款」的其中哪一種。如此一來,這就是一個分類問題而不是回歸問題了。你不會希望進行回歸問題的三個月後,才發現一開始的假設就是錯的吧。搞清楚你們的假設是否成立是非常重要的。

👉 機器學習專案流程的待辦清單

2. 取得資料

開始作業前,首先一定要建立一個獨立的作業環境。如果只是自己練習用的話,使用 virtualenv 這個工具來建立獨立環境就夠了。不過如果要開放套件供別人使用,還需要同時測試多個 Python 版本。如果是寫產品的話,建議等開發到一個階段再用 Docker 建立獨立環境做測試。使用 Windows 系統的話,建議用 Anaconda

使用 virtualenv 建立好環境後,在環境底下安裝 JupyterMatplotlibNumpyPandasScipyScikit-learn 等資料分析必備的套件。

套件安裝好之後,就可以開始使用 Jupyter notebook。所有資料分析的操作,包括取得資料、資料視覺化、跑模型、做測試等都在 Jupyter notebook 裡完成。

通常資料會以表格、文件、或檔案的形式儲存在關聯式資料庫裡,或是其他 Data store 如常見的雲端資料庫。使用 vendor 如 Google Cloud PlatformAmazon Web Services 的雲端資料庫,基本上 vendor 都會開 API 供你做資料存取。你只需要有資料庫的認證 (Authentication) 跟授權 (Authorization),知道怎麼使用 API 就好了。如果只是練習用,可以到 kaggle.com ,上面有很多公開的 Dataset 以 CSV 檔案的形式提供下載。

在 Jupyter notebook 裡,無論通過雲端存儲 API 取得資料或匯入 CSV 檔,幾乎都會轉換成 Pandas DataFrame 的形式,然後利用 Pandas 這個套件工具對資料做操作。你可以使用 pandas.DataFrame.head() 函式一窺各資料欄位為何,或使用 pandas.DataFrame.describe() 函式看各資料欄位的最大值、最小值、平均值、分位數標準差等統計資訊。

接著要從所有資料裡取樣部分資料用來測試。之所以在最一開始的階段就要做好測試資料,是為了避免數據窺視偏差 (Data snooping bias)。因為人類的大腦很擅長學習既有模式,可能就因為你多看了幾眼資料,於是就傾向於選擇某些特定的機器學習模型,最後導致 Overfitting

👉 機器學習專案流程的待辦清單

3. 探索資料

從所有資料取樣部分資料,保留到最後做測試。取樣後剩下的資料,就是訓練資料。但是,在開始著手資料處理並且建立模型之前,我們想要更深入地探索資料的樣貌。譬如,對含有地理資訊的資料來說,我們會使用 Pandas 套件去畫一張 Scatter plot 來看每個資料經緯度的分佈情形。

Image for post
Image for post
A geographical scatterplot of the data, with better visualization highlighting high-density areas.

這是在加州的房地產物件經緯度分佈圖。從上圖中可以發現,靠近洛杉磯跟聖地牙哥的灣區地帶,房地產物件非常密集。調整 pandas.DataFrame.plot.scatter() 函式的一些參數,再畫出一張如下所示的 Scatter plot。顏色代表的是房地產價格,紅色表示價格越高,而紫色表示價格越低。圓圈的大小代表人口密度,圓圈越大表示人口越多。

Image for post
Image for post
California housing prices

從上圖中可以發現,房地產的價格跟位置還有人口密度有很大的關聯,對照經緯度,發現越靠近海邊的有越貴的傾向。而人口密度低的地方,幾乎不會看到有高價格的房產。(這邊只是舉例,雖然這些結論很淺顯易懂。)

不過,可以猜測使用分群演算法應該可以有不錯的分群效果,然後,我們可以計算各資料跟所屬群中心點(clustering center)的距離當作是一個新的特徵,譬如剛才說的越靠近海邊的房地產有越貴的傾向。當然,這不是簡單的Rule-based,以為只要是海邊的物件就是高價格物件,因為南加州的 coastal 區域就不屬於高價區。還是必須經過機器學習找出價格模式。

通過 pandas.DataFrame.corr() 函數,可以計算出資料各屬性之間的相關係數,包括 Pearson correlation coefficientKendall rank correlation coefficient、還有 Spearman’s rank correlation coefficient

相關係數範圍從 -1 到 1,越接近 -1 表示負相關,越接近 1 則表示正相關。相關係數為 0 表示兩個屬性之間沒有線性相關。不同資料集的相關係數如下圖所示:

Image for post
Image for post
The standard correlation coefficient of various datasets (source: Wikipedia)

由第二排可以知道,相關係數跟斜度無關。打個比方,英呎為單位的身高數據無論跟英寸為單位或是奈米單位的數據都是正相關,但斜度會不同。

相關係數只能找出線性相關的因子(如 X 增加則 Y 就會增加或減少),並沒有辦法找出非線性相關的因子(如 X 越接近 0 則 Y 就會增加)第三排的所有圖像,雖然 X 軸跟 Y 軸顯然是不獨立的,但它們的相關係數皆為 0,它們都屬於非線性相關。

找出各屬性之間的相關性還可以使用 pandas.plotting.scatter_matrix() 函式,如下圖所示:

Image for post
Image for post
Scatter matrix
Image for post
Image for post
Median income versus median house value

從上面兩張圖可以發現,收入跟房地產價值有高度正相關,是一個很好的目標屬性。此外,房價的上限就在 $500,000,而在 $450,000、$350,000 跟 $280,000 的地方,隱約都有一條水平線。我們會把這些資料都拉出來觀察一下,如果明顯都座落在同一區,我們可能會選擇不把這些數據當成訓練資料,免得機器學習模型從這些奇怪的數據學到並複製成一種模式。

你還可以進行一些屬性合併,如果預期會對訓練結果有所幫助的話。譬如現有的屬性有 total_bedrooms 跟 total_rooms,如果合併這兩種屬性,兩者相除計算出 bedrooms_per_room 創造出新的屬性,再去看相關係數,會意外發現價值越高的房地產,臥房率會越低,呈現高度負相關。那麼這個合併的新屬性就能拿來當作訓練時的目標屬性。

👉 機器學習專案流程的待辦清單

4. 資料的前處理

資料的前處理有四種:數據清理特徵選擇特徵工程特徵縮放

數據清理

發現數據為空的屬性,三種選擇:要不就捨棄那些為零的數據、要不就捨棄整個屬性,不然就是計算出該屬性的平均值,將那些數據填成平均值。這是數據清理。如果你選擇了填入平均值,記得保留這個平均值。之後在測試資料或新的資料裡,遇零的情況要填入同樣的平均值。Scikit-LearnImputer 類別可以幫忙處理數據填空。此外,屬性若是文字,也可以利用 Scikit-Learn 的 LabelBinarizer 轉換成 One-hot 向量

上述可拿來利用的合併屬性,我們需要自己寫客製化的 Transformer,繼承 Scikit-Learn 的 TransformerMixin 可以做到這件事。知乎上這篇〈优秀的Transformers与Pipeline〉搜集了很多範例,可以參考看看。

特徵選擇與特徵工程

特徵選擇決定捨棄那些沒有利用價值的資料欄位。而特徵工程是使用數據的領域知識來創建特徵,這些特徵會使機器學習算法產生效用。例如:把連續數據離散化、將特徵分解成類別、或以日期時間切割。又如:若屬性分佈圖在尾端有明顯拉高傾向,我們也許會將數據取對數 log(x)。類似的特徵轉換還有對特徵做平方根 sqrt(x) 或平方 x² 等。

特徵選擇跟特徵工程其實學門都滿大的,有很多專門深入的研究,我也很難一次說明白。上面提到的都只是最幼幼班的做法。有興趣可以看看這篇:Discover Feature Engineering, How to Engineer Features and How to Get Good at It。在機器學習領域有句俗話 ”Garbage in, garbage out.”。要是餵給模型吃的是很醜很髒的東西,幾乎不用指望可以能到什麼有意義的結果。我是感覺特徵工程有點像美肌美顏相機,把特徵先修得美一點,總不至於百分百會得到沒啥用處的結果。

特徵縮放

資料前處理的部份少不了特徵縮放,是最重要的環節之一。特徵縮放的目的就是要讓各屬性的數據範圍維持在差不多的規模裡,不要有的屬性數據範圍可以廣到從 1 到 60,000,而有的屬性範圍卻只在 1 到 15。要把數據範圍調整到同一規模,有兩種方式:Normalization (Min-max scaling) 跟 Standardization

Normalization 就是把數據調整介於 0 到 1 之間,做法是將數據除以最大值減去最小值,使用 Scikit-Learn 的 MinMaxScaler 就可以做到了。而 Standardization 是把數據減去平均值,再除以變異數。Standardization 並不像 Normalization,處理後的數據的範圍不會只介在 0 到 1 之間,這樣的特性使得 Standardization 並不適合用在深度學習的演算法裡。但是 Standardization 對 outliers 的影響比 Normalization 來得小多了。想像一下本來範圍只有 0 到 15 的數據,若是不小心資料錯誤出現 100 這樣的 outlier,經過 Normalization 的特徵縮放後,數據範圍會由原來的 0 到 15 變成 0 到 0.15。

Scikit-Learn 的 sklearn.pipeline.Pipeline 可以指定連串的前處理作業。前面所提到的 Imputer、Customized Transformer 以及最後的 MinMaxScaler,宣告在 Pipeline 裡就能串成一連串的步驟。如此一來,方便我們減少代碼量的同時,也讓前處理的流程變得直觀許多。

👉 機器學習專案流程的待辦清單

5. 嘗試各種機器學習的模型,找出幾個表現不錯的模型

在最上面框架問題的地方列出了一些參考資源,教你如何選擇機器學習模型。找出幾個可行的方案後快速套入,並且使用 Cross-validation 交叉驗證來避免訓練出 Overfitting 的模型。訓練資料、測試資料,跟驗證資料大致可切割成 7:2:1 的比例,這個不一定。

普遍可以利用 Scikit-Learn 的 K-fold cross-validation 去做交叉驗證。假設 K=10,將原來的訓練資料均分成十份,其中九份拿到做訓練資料,剩下的一份當作驗證資料。同樣的動作反覆做十次,每次都取不同一份的資料當作驗證資料,剩下的另外九份做測試資料,這個就是 K-fold cross-validation

👉 機器學習專案流程的待辦清單

6. 校正這幾個不錯的模型,並嘗試結合成一個解決方案

假設你已經找了幾個表現不錯的機器語言學習模型了,以下幾個方法可以總合地進行微調。

第一個方法是 Grid Search。省掉自己手調超參數 (Hyperparameter) 的功夫。使用 Scikit-Learn 的 GridSearchCV 設定好超參數的組合,GridSearchCV 會嘗試每一種參數組合並找到最佳的超參數。如果超參數的組合太多,使用 Scikit-Learn 的 RandomizedSearchCV 是更好的選擇。跟 GridSearchCV 類似,只不過不是一個個嘗試組合的結果,而是對每個超參數挑選一個隨機值,譬如設定跑 1000 回 RandomizedSearchCV,它會挑 1000 次隨機參數並找到最佳的超參數組合。

第二種方法是 Ensemble Methods。這個留到之後再多做解釋。

最後,就是本番的測試資料上場了。通常測試資料的結果表現會差一點,這是因為訓練好的模型,那些超參數是基於驗證資料得到的。不要想拿測試資料再去重新校正超參數,被改進的模型套用在新的資料集上表現不見得會更好。

👉 機器學習專案流程的待辦清單

7. 撰寫文件

這部分跟技術比較無關,主要是撰寫文件做知識傳達。無論是簡報或文件,可多利用資料視覺圖來輔佐,並在最後提供簡單扼要的結論。

👉 機器學習專案流程的待辦清單

8. 發佈、監控並維護你的系統

接下來你要做的事情是:準備系統上線的工作。這包括把輸入資料串連到模型、寫單元測試等。此外,你還需要寫監控系統代碼,以隨時監測輸入資料的品質。由於之後還會不定期地依照新的資料重新訓練機器語言學習模型,你還要考慮模型的版本控制,如果新版的模型效果透過監控系統發現問題,還可以切換到上一個版本。

然後,你的機器語言模型又要如何部署在應用系統端?通常有幾個做法,之後再另外寫文章說明好了。總之,這一連串的工作,我們可以稱之為 machine learning pipeline。

打造 machine learning pipeline 並不是簡單的事情。其實這屬於資料工程的一環,也應該由所謂的資料工程師透過跟資料科學家的合作來實現。(資料工程的定義:Data engineering: A quick and simple definition)不過很多時候你既不是一個資料科學家也不是一個資料工程師,只是團隊裡少數幾個有電腦工程背景的工程師。為滿足工作需求,也就只能不斷地去找解答解決這些問題了。

👉 機器學習專案流程的待辦清單

參考資料

Image for post
Image for post
https://www.buymeacoffee.com/cC8qlLt

弱弱開發女子,在東京的開發者人生。

Notes about data science/engineering, machine learning, and…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store