- 框架問題。
- 取得資料。
- 探索資料。
- 資料的前處理。
- 嘗試各種機器學習的模型,找出幾個表現不錯的模型。
- 校正這幾個不錯的模型,並嘗試結合成一個解決方案。
- 撰寫文件。
- 發佈、監控並維護你的系統。
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
假設 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. 發佈、監控並維護你的系統
- 把輸入資料串連到模型、撰寫單元測試。
- 撰寫監控系統代碼,以便隨時監測輸入資料的品質。
- 模型的版本控制。