一個機器學習專案,大約包括以下步驟:
- 框架問題。
- 取得資料。
- 探索資料。
- 資料的前處理。
- 嘗試各種機器學習的模型,找出幾個表現不錯的模型。
- 校正這幾個不錯的模型,並嘗試結合成一個解決方案。
- 撰寫文件。
- 發佈、監控並維護你的系統。
Step 1. 框架問題 (State the question and determine required data)
不同的目標,會影響隨後決定該使用哪些模型、什麼評測標準、還有要花多少力氣跟時間解決中間遇到的問題。
決定目標之後,可以開始考慮要選擇哪些機器學習模型。要採用監督式學習、非監督式學習,還是強化學習?這是分類問題、回歸問題,還是其他?這個系統是預計要用在線上學習(on-line)?還是離線學習(off-line)?
然後要選擇如何評估機器學習的效能。例如對於回歸問題而言,常見的評估方法是採用兩種公式 RMSE (Root Mean Square Error) 或 MAE (Mean Absolute Error)。
最後,列出目前為止所有的假設,並且再次確認這些假設。
Step 2. 取得資料 (Acquire the data in an accessible format)
首先一定要建立一個獨立的作業環境,使用 virtualenv 這個工具來建立獨立環境。
所有的資料最後幾乎都會轉換成 DataFrame 的形式,然後利用 Pandas 這個套件工具對資料做操作。你可以使用 pandas.DataFrame.head() 函式一窺各資料欄位為何,或使用 pandas.DataFrame.describe() 函式看各資料欄位的最大值、最小值、平均值、分位數、標準差等統計資訊。
接著要取樣部分資料用來測試。一開始的階段就要做好測試資料,這是為了避免數據窺視偏差 (
Data snooping bias)。俗語說:
「馬不知臉長,猴子不知屁股紅。」人類的大腦也習慣於既有模式,可能看了幾眼資料就傾向於選擇某些特定的機器學習模型,最後導致
Overfitting。
有道是「隔行如隔山」,機器學習的過程也類似於這樣的情形:
就像有個人雖然嚴重缺乏跨越自身領域之外的經驗和知識,像是「達克效應」(Dunning-Kruger effect)所敘述一般,卻帶著滿滿的自信去運作執行,這樣產出的結果不是大好就是大壞!有擔當的管理者有一個重要的責任,就是把下屬從愚昧之巔推到絕望之谷,至於他是否能爬上開悟之坡,就只能看個人的修為與造化了。
Step 3. 探索資料 (Identify and correct missing data points/anomalies as required)
從所有資料取樣部分資料,保留到最後做測試。取樣後剩下的資料,就是訓練資料。但是,在開始著手資料處理並且建立模型之前,我們想要更深入地探索資料的樣貌。
調整 pandas.DataFrame.plot.scatter() 函式的一些參數,畫出一張 Scatter plot。通過 pandas.DataFrame.corr() 函數,可以計算出資料各屬性之間的相關係數,包括 Pearson correlation coefficient、Kendall rank correlation coefficient、還有 Spearman’s rank correlation coefficient。相關係數範圍從 -1 到 1,越接近 -1 表示負相關,越接近 1 則表示正相關。相關係數為 0 表示兩個屬性之間沒有線性相關。
相關係數只能找出線性相關的因子(如 X 增加則 Y 就會增加或減少),並沒有辦法找出非線性相關的因子(如 X 越接近 0 則 Y 就會增加)的圖像,雖然 X 軸跟 Y 軸顯然是不獨立的,但它們的相關係數皆為 0,它們都屬於非線性相關。找出各屬性之間的相關性還可以使用 pandas.plotting.scatter_matrix() 函式。
還可以進行一些屬性合併,如果預期會對訓練結果有所幫助的話,再去看相關係數,如果呈現高度負相關,那麼這個合併的新屬性就能拿來當作訓練時的目標屬性。
Step 4. 資料的前處理 (Prepare the data for the machine learning model)
數據清理
如果發現數據為空(nan)的屬性有三種選擇:要不就捨棄那些為零的數據、要不就捨棄整個屬性,不然就是計算出該屬性的平均值,將那些數據填成平均值,這就是數據清理。
如果你選擇了填入平均值,記得保留這個平均值,之後在測試資料或新的資料裡,遇零的情況要填入同樣的平均值。Scikit-Learn 的 Imputer 類別可以幫忙處理數據填空。
此外,屬性若是文字,也可以利用 Scikit-Learn 的 LabelBinarizer 轉換成 One-hot 向量 。
合併屬性,則需要繼承 Scikit-Learn 的 TransformerMixin 來做這件事,來撰寫客製化的 Transformer 。
特徵選擇與特徵工程 (feature engineering)
Garbage in, garbage out. 特徵選擇決定捨棄那些沒有利用價值的資料欄位。特徵工程是使用數據的領域知識 (domain knowledge) 來創建特徵,這些特徵才會使機器學習算法產生效用。例如:把連續數據離散化、將特徵分解成類別、或以日期時間切割。又如:若屬性分佈圖在尾端有明顯拉高傾向,我們也許會將數據取對數 log(x)。類似的特徵轉換還有對特徵做平方根 sqrt(x) 或平方 x² 等。
特徵縮放
特徵縮放的目的就是要讓數據的範圍維持在一定的規模裡。要把數據範圍調整到同一規模,有兩種方式:Normalization (Min-max scaling) 跟 Standardization。
Normalization 就是把數據調整到介於 0 到 1 之間,做法是將數據除以最大值減去最小值,使用 Scikit-Learn 的 MinMaxScaler 就可以做到了。
Standardization 則是把數據減去平均值,再除以變異數。Standardization 並不像 Normalization,處理後的數據的範圍不會只介在 0 到 1 之間,這樣的特性使得 Standardization 並不適合用在深度學習的演算法裡。但是 Standardization 對 outliers 的影響比 Normalization 來得小多了。
Scikit-Learn 的 sklearn.pipeline.Pipeline 可以指定連串的前處理作業。之前提到的 Imputer、Customized Transformer 和 MinMaxScaler,宣告在 Pipeline 裡就能串成一連串的步驟。如此一來,方便我們減少代碼量的同時,也讓前處理的流程變得直觀許多。
Step 5. 嘗試各種機器學習的模型,找出幾個表現不錯的模型 (Establish a baseline model that you aim to exceed)
- Train the model on the training data
- Make predictions on the test data
- Compare predictions to the known test set targets and calculate performance metrics
先找出幾個可行的方案後快速套入,並且使用 Cross-validation 交叉驗證來避免訓練出 Overfitting 的模型。訓練資料、測試資料,跟驗證資料大致可切割成 7:2:1 的比例。可以利用 Scikit-Learn 的 K-fold cross-validation 去做交叉驗證。
假設 K=10,將原來的訓練資料均分成十份,其中九份拿到做訓練資料,剩下的一份當作驗證資料。同樣的動作反覆做十次,每次都取不同一份的資料當作驗證資料,剩下的另外九份做測試資料,這個就是 K-fold cross-validation。
Step 6. 校正這幾個不錯的模型,並嘗試結合成一個解決方案 (If performance is not satisfactory, adjust the model, acquire more data, or try a different modeling technique)
假設已經找到了幾個表現不錯的機器語言學習模型了,使用以下幾個方法進行微調。(model hyperparameter tuning)
第一個方法是
Grid Search。省掉自己手調超參數 (Hyperparameter) 的功夫。
使用 Scikit-Learn 的 GridSearchCV 設定好超參數的組合,GridSearchCV 會嘗試每一種參數組合並找到最佳的超參數。如果超參數的組合太多,使用 Scikit-Learn 的 RandomizedSearchCV 是更好的選擇。跟 GridSearchCV 類似,只不過不是一個個嘗試組合的結果,而是對每個超參數挑選一個隨機值,譬如設定跑 1000 回 RandomizedSearchCV,它會挑 1000 次隨機參數並找到最佳的超參數組合。
第二種方法是
Ensemble Methods。
Step 7. 撰寫文件 (Interpret model and report results visually and numerically)
撰寫文件做知識傳達,多利用資料視覺圖來輔佐,並提供簡單扼要的結論。
Step 8. 發佈、監控並維護你的系統
- 把輸入資料串連到模型、撰寫單元測試。
- 撰寫監控系統代碼,以便隨時監測輸入資料的品質。
- 模型的版本控制。