標籤:

Hands-On ML,CH2:房價預測

主要步驟

  • 縱觀全局
  • 獲取數據
  • 探索並可視化以深入了解數據
  • 為機器學習演算法準備數據
  • 選擇模型並訓練
  • 調整模型參數
  • 發布解決方案
  • 啟動、監視和維護系統

縱觀全局

這次任務是用加州的人口普查數據建立一個加州房價模型。

這一數據具有加州每個街區的人口、收入中位數、房價中位數等維度。

模型需要從這些數據中學習,考慮到所有特徵,最終能夠預測任何地區的房價中位數。

構建問題

首先思考一下:

  • 學習類型是有監督、無監督或強化學習?
  • 任務類型是分類任務、回歸任務還是別的什麼?
  • 是否應該使用批量學習或在線學習技術?

讓我們來回答一下:

  • 這顯然是一個典型的監督學習任務,因為訓練樣本中含有標記(每個實例都有預期的輸出,即該地區的房價中值)。
  • 它是一個典型的回歸任務,因為要求預測一個值。更具體地是一個多變數回歸問題,因為系統將使用多個特性來進行預測(它將使用地區的人口、收入等)。
  • 在系統中沒有連續的數據流,沒有特別需要對數據快速變化進行調整,數據量小到可以在內存中運行,所以普通的批量學習應該做的很好。如果數據是巨大的,可以將批處理學習工作分解到多個伺服器(使用MapReduce技術,稍後將看到),或者使用在線學習技術。

選擇一個性能度量

回歸問題的典型性能度量是均方根誤差(RMSE)。它測量了系統在預測中所犯錯誤的標準偏差。方程2-1給出了計算RMSE的數學公式:

檢查一下假設的問題

再次確認一下需求

獲取數據

安裝工作環境

安裝python環境

觀察一下數據和結構

每行表示一個地區的數據,一共有十個特徵(屬性、維度)。

info()方法用於快速地描述數據,特別是行總數,以及每個特徵的類型和非空值的數量。

數據集有20,640個實例,這按照機器學習標準是相當小的,但是作為入門還是很好的。注意一下,total_bed rooms屬性只有20,433個非空值,這意味著207個區域沒有這個特性,這個問題我們稍後處理。

除了海洋鄰近區域,其他的屬性都是數值型的。海洋鄰近區域的類型是object,它可以是任何類型的Python對象,但是由於是從CSV文件中載入的數據,所以我們知道這是text屬性。

當查看前五行時,會注意到該列中的值是重複的,這意味著它可能是一個類別屬性。通過使用value_counts()方法,我們可以看到類別和個數。

describe()方法顯示了數值屬性的一些摘要信息。

另一種快速感測數據的方法是為每個數字屬性繪製直方圖。直方圖顯示了給定值範圍(橫軸)的實例數量(垂直軸)。在整個數據集上調用hist()方法,為每個數字屬性繪製一個直方圖:

通過直方圖我們注意到一些問題:

  • 收入中位數屬性看起來不像美元。在與收集數據的團隊進行核對後,被告知數據已經被按比例調整,上限為15,下限為0.5。機器學習中使用預處理的屬性是很常見的,這不一定是一個問題,但是應該理解數據是如何計算得到的。
  • 房屋年齡中位數和房屋價值中位數也有上限。後者可能是一個嚴重的問題,因為它是目標屬性。機器學習演算法可能會學習到價格永遠不會超過這個限度。這就需要與客戶進行確認,以確定這是否是一個問題。
  • 不同屬性有相當差異的度量尺度(數量級)。我們將在後面討論維度度量尺度。
  • 許多直方圖都是尾部重的:它們向中位數的右邊延伸遠比左邊多。這可能使一些機器學習演算法更難檢測到模式,稍後我們將嘗試將這些屬性轉換為更多的鐘形分布。

創建一個測試集

進一步查看數據之前,需要創建一個測試集,把它放在一邊,永遠不要偷窺它。

大腦是一個厲害的模式檢測系統,它很容易過度擬合:如果你看測試集,你可能偶然發現一些看似有趣的模式,使得你選擇一種特定的機器學習模型。這樣當使用測試集估計泛化錯誤時,結果可能會很好,而在真正生產環境中卻可能存在大誤差,這稱為數據窺探偏差。

sk-Learn提供了一些函數以各種方式將數據集拆分為多個子集。

上面代碼只考慮了隨機抽樣的方法。如果數據集足夠大(特別是相對於特徵的數量),這通常是可以的,但如果數據集不大,那麼就有可能導致抽樣偏差。

大多數收入中值都集中在2-5(萬美元)左右,但是有一些卻遠遠超過了6。有一點很重要:每一層(等級)的數據集中有要足夠數量的實例,否則層的重要性估計可能會有偏差。這意味著不應該有太多的層(等級),而每個層的數據量應該足夠大。

下面的代碼通過將中位數收入除以1.5(以限制收入類別的數量)來創建一個收入類別屬性,並使用ceil函數進行舍入,然後將所有大於5的類別合併到第5類中。

現在你可以根據收入類別進行分層抽樣了。可以使用sk-learn的分層shufflesplit類:

我們來看一下分層抽樣結果

現在,應該刪除income_cat屬性,以便數據恢復到原來的狀態:

我們在測試集生成上花了相當多的時間,因為這是機器學習項目中經常被忽略但卻很關鍵的部分。此外,當我們之後討論交叉驗證時,上面的這些想法很多都是有用的。

探索並可視化以深入了解數據

之前,我們只要快速瀏覽一下數據,就能大致了解所操縱的數據類型。

現在的目標是深入一點。

首先,要把測試集放在一邊,僅僅探索測試集。另外,如果訓練集非常大,那可能需要取樣出一個探索集,使操作簡單快捷。

但我們的例子中,訓練集非常小,所以可以直接在訓練集合上操作。現在創建一個副本,這樣就可以在不損害訓練集的情況下進行各種操作。

可視化地理數據

既然有地理信息(經度、緯度),那我們可以創建一個地區的散點圖

現在可以清楚地看到高密度區域,我們再加上虛化參數

現在情況好多了:你可以清楚地看到高密度區域,即灣區、洛杉磯和聖迭戈附近,再加上中央山谷的一長排相當高密度的區域,特別是薩克拉門托和弗雷斯諾。

雖然我們的大腦非常善於識別圖片上的特徵,但是還是需要使用可視化的參數來讓圖案脫穎而出。

每個圓圈的半徑代表地區的人口(選項s),顏色代表價格(選項c)。我們將使用一種被稱為jet的預定義顏色地圖,它的範圍從藍色(低值)到紅色(高值)

這張圖片告訴你,房價與地理位置(例如,靠近海洋)和人口密度有關,你可能已經知道了。

海洋接近屬性也可能有用,儘管在北加州,沿海地區的房價並不太高,所以這不是一個簡單的規則。

觀察相關係數

在數據集不太大的情況下,您可以使用corr()方法輕鬆地計算每對屬性之間的標準相關係數

相關係數從-1到1。當它接近1時,意味著有很強的正相關;例如,當收入中值上升時,房價中值往往會上升。當係數接近-1時,意味著有很強的負相關;你可以看到在緯度和中位數房屋價值之間有一個小的負相關(即:當你往北走的時候,價格有輕微的下降趨勢。最後,係數接近於零意味著沒有線性相關。)

例如,x和y的相關性在散點圖上的表示如下:

當然,相關係數只測量線性相關係數(「如果x上升,y通常上升/下降」)。它可能完全忽略了非線性關係(例如,「如果x接近於0,那麼y通常會上升」)。

比如第三行,儘管它們的坐標軸明顯不是獨立的,但底部行的所有圖的相關係數都為零,因為這些都是非線性關係的例子。

第二行顯示了相關係數為1或-1的例子;特別注意這和斜率無關。

另一種檢查屬性之間相關性的方法是使用pandas的scatter_matrix函數:

因為現在有11個數字屬性,會得到121個圖,這在一個頁面上是無法畫出的,所以讓我們只關注一些看起來與房屋價中位數相關的有可能的屬性。

預測中位數房屋價值的最有希望的屬性是中位數收入,我們來仔細看看它們的相關散點圖。

這幅圖揭露了一些事情:

首先,相關性確實非常強:你可以清楚地看到上升的趨勢,而且這些點也不太分散。

第二,我們早些時候注意到的價格上限,在50萬美元的水平線上清晰可見。

但是還有一些不那麼明顯的直線:在水平線約45萬美元、約為35萬美元、約是28萬美元等

我們可能想嘗試刪除相應的區域,以防止演算法學習到這些數據的怪現象。

特徵組合實驗

在將數據輸入機器學習演算法之前,已經確定了一些可能想要清理的數據怪癖,並且發現了屬性之間的有趣關聯,特別是目標屬性相關的。

還注意到一些屬性有一個尾重分布,所以可能想要轉換它們(例如通過計算它們的對數)。

當然,不同的項目總有不同的變化,但總體的過程是相似的。

在為機器學習演算法準備數據之前,可能要做最後一件事:嘗試各種屬性組合。

例如,如果你不知道有多少個家庭,一個地區的房間總數就不是很有用,而真正想要的是每個家庭的房間數量。

同樣,卧室的總數量也不是很有用,可能想把它和房間的數量進行比較。

每個家庭的人口看起來也是一個有趣的屬性組合。

讓我們創建這些新屬性,並重新看一下相關性:

很不錯,與房間或卧室的總數量相比,新的bedrooms_per_room屬性與房屋價格中位數的相關性要大得多。顯然,擁有較低的卧室/房間比例的房子往往更貴。

每個家庭的房間數量也比一個地區的房間總數更相關,顯然,房子越大,價格就越高。

這一輪的探索並不一定是徹底的,關鍵是要從正確的角度出發,迅速獲得洞察,這將幫助你獲得第一個相當好的原型。

但這也是一個迭代的過程:一旦你得到一個原型並運行,你就可以分析它的輸出來獲得更多的見解,並回到這個探索階段。

準備機器學習演算法的數據

現在是為機器學習演算法準備數據的時候了。

我們應該編寫函數來實現這一點,而不是手工操作,這有幾個很好的理由:

  • 這將允許您輕鬆地在任何數據集上複製這些轉換(例如,下一次您獲得一個新的數據集)。
  • 您將逐步構建一個轉換函數庫,您可以在將來的項目中重用它。
  • 您可以在您的實時系統中使用這些函數來轉換新數據,然後再將其添加到您的演算法中。
  • 這將使您能夠輕鬆地嘗試各種轉換,並查看哪些轉換組合最有效。

接下來先回到一個乾淨的訓練集,並讓特徵值和目標值分開:

數據清洗

大多數機器學習演算法都不能處理遺失的特徵,所以創建一些函數來處理。

我們可以看到,有些數據行有屬性缺失:

我們有三個選擇來處理這個問題:

  • 去掉相應的區域。(去行)
  • 去掉整個屬性。(去列)
  • 將值設置為某個值(0、平均值、中值等)。

可以使用pandas的DataFrame的dropna()、drop()和fillna()輕鬆完成這些操作:

如果選擇了選項3,就需要計算訓練集的均值,並使用它來填充訓練集中的缺失值,同時要記得保存這個均值。

當要評估系統時,需要它來替換測試集中所缺少的值,並且在新的數據中,系統也可以用這個均值實時替換缺失的值。

Scikit-Learn提供了一個方便的類來處理丟失的值:Imputer

創建一個Imputer 實例,指定要將每個屬性的缺失值替換為該屬性的中值。

由於中值只能計算在數字屬性上,所以我們需要創建一個沒有ocean_proximity 特徵的副本

現在,可以使用fit()方法將該Imputer實例與訓練數據相匹配。imputer僅計算每個屬性的中位數,並將結果存儲在其statistics_ 變數中。

目前只有total_bedroom屬性有缺失值,但是我們不能確定系統運行後的新數據中不會有任何缺失值,所以將該屬性應用到所有的數值屬性中是比較安全的。

現在,就可以使用這個訓練過的的imputer 來轉換訓練集,通過學習到的中位數替換丟失的值。其結果是一個包含轉換特徵的普通Numpy數組。如果你想把它轉換成pandas的dataframe中,也很簡單。

處理文本和分類屬性

前面我們省略了類別屬性ocean_proximity,因為它是一個文本屬性,所以我們無法計算它的均值。大多數機器學習演算法都傾向於使用數字,所以我們把這些文本標籤轉換成數字。

我們可以使用Pandas的factorize()方法將字元串分類特徵轉換為數字分類特徵:

但是這個表示會出現一個問題,機器學習演算法會假設兩個相鄰的值比兩個遠的值更相似。

顯然此例情況並非如此。為了解決這個問題,一個常見的解決方案是創建一個二進位類型的屬性:比如其中一個屬性等於1時,類別是「< 1 h海洋」,另一個屬性等於1時,類別是「內陸」等等。

這被稱為one-hot編碼,因為只有一個屬性將等於1(熱),而其他屬性將為0(冷),下面將數字特徵轉換為one-hot特徵:

這兩步還可以合併成一個,其中fit_transform()需要一個2D數組,但實housing_cat_encoded是一個1D數組,所以我們需要對它reshape

注意:上面兩例使用的轉換類與書上不一樣,作者在github已經說明之前版本的方法是針對label而不是輸入特徵,所以將LabelEncoder改成factorize()方法、將LabelBinarizer 類轉為CategoricalEncoder。

注意:如果數據量很大,稀疏矩陣(sparse)比稠密矩陣(dense)的佔用內存更小。

自定義轉換器

雖然Scikit-Learn提供了許多有用的轉換器,但是您需要為諸如自定義清理操作或結合特定屬性等任務編寫自己的任務。

我們需要做的是創建一個類並實現三個方法:fit()(返回self)、transform()和fit_transform()。

可以通過添加TransformerMixin作為基類來獲得最後一個。另外,如果您將BaseEstimator作為基類添加(並且避免在構造函數中使用*args和**kargs),您將得到兩個額外的方法(get_params()和set_params()),這將對自動超參數優化有用。

例如,這裡有一個小的transformer類,它添加了我們前面討論過的組合屬性。

在本例中,transformer有一個超參數add_bedrooms_per_room,默認設置為True(提供合理的默認值通常是有幫助的)。

這個超參數可以讓你很容易地發現添加這個屬性是否有助於機器學習演算法。

更一般的情況是,您可以添加一個超參數來設置您不能100%確定的任何數據準備步驟。

你越自動化這些數據準備步驟,你就可以自動嘗試更多的組合,使你更有可能找到一個完美的組合(並節省你大量的時間)

特徵尺度縮放

我們需要應用於數據的最重要的轉換之一是特徵尺度縮放。

大部分情況下,機器學習演算法在輸入數字屬性有非常不同的尺度時表現不佳。

房子數據的情況是這樣的:房間的總數從6個到39320個不等,而中位數收入僅為0到15個。

注意:通常不需要擴展目標值。

有兩種常見的方法可以使所有屬性具有相同的規模:min-max縮放和標準化。

Min-max縮放(又稱之為規範化):將值縮放到0-1的區間。做法是減去最小值,然後除以最大值減去最小值。Scikit-Learn提供了一個名為MinMaxScaler的轉換器。

它有一個feature_range (特徵範圍)超參數,如果你不想0-1,你可以改變它的範圍。

標準化是完全不同的:首先它減去平均值(因此標準化值總是有一個零均值),然後除以方差,從而得到結果分布的單位方差。

與min-max擴展不同的是,標準化並沒有將值綁定到特定的範圍,這可能引起一些演算法的問題(例如,神經網路通常期望輸入值從0到1),但是,標準化對異常值的影響要小得多。

例如,假設一個地區的收入中值等於100(錯誤),Min-max擴展將會將0-15的所有其他值壓到0-0.15(過分壓縮),而標準化不會受到太大的影響。

Scikit-Learn提供了一個稱為StandardScaler的轉換器,用於標準化。

注意:重要一點是只轉換訓練數據,而不轉換測試數據。

轉換管道

有許多數據轉換步驟需要以正確的順序執行。幸運的是,Scikit-learn提供了管道類來幫助進行這樣的轉換序列。

下面是一個用於數值屬性的小型管道:

管道的構造函數接受一組名稱/轉換器對列表。

除了最後一個估計量外,其他的都必須有一個fit_transform()方法。

當調用管道的fit()方法時,它會對所有的轉換器依次調用fit_transform(),將每個調用的輸出作為參數傳遞給下一個調用,直到最後一個轉換器,最後一個只調用fit()方法。

管道對外暴露了最後一個轉換器的方法。

在本例中,最後一個轉換器是StandardScaler,因此管道有一個transform()方法,依次將轉換應用到數據(它也有一個fit_transform方法,我們可以用它代替調用fit(),然後transform())

因為scikitt-learn無法處理pandas的dataframe,所以我們需要為這個任務編寫一個簡單的自定義轉換器。我們增加一個選擇dataframe的列的子集的選擇轉化器:

現在我們將這些組件組成一個大的管道,得以同時轉換數值類型特徵和分類類型特徵:

每個子管道都從一個選擇轉換器開始:它通過選擇所需的屬性(數值或分類)來轉換數據,丟棄其餘的,並將結果DataFrame轉換為一個NumPy數組。

選擇模型並訓練

終於!我們建立好問題,得到了數據,並進行了探索,抽取了一個訓練集和一個測試集,然後編寫了轉換管道來自動清理和準備機器學習演算法的數據。

現在終於可以選擇機器學習模型並著手訓練它了。

在訓練集上訓練和評估

有一個好消息是:由於前面的步驟,接下來的任務變得非常簡單,現在讓我們來訓練一個線性回歸模型。

完成了!我們從訓練集中取幾個例子嘗試一下:

媽賣批,好像不是很准撒!

不管怎麼樣,先用scikitt-learn的mean_squared_error函數來度量這個回歸模型在整個訓練集上的RMSE(均方根差)。

我擦咧,這顯然不是一個好分數:大多數地區的median_housing_values在120,000到265,000之間,所以一個68374的預測錯誤是不太令人滿意。

其實這就是模型欠擬合了。當這種情況發生時,可能意味著所用特徵沒有提供足夠的信息來做出正確的預測,或者模型不夠強大。

修復欠擬合的主要方法是:選擇一個更強大的模型;為訓練演算法提供更好的特徵;或者減少對模型的限制。這個模型沒有正則化,所以排除最後一個。

我們可以嘗試添加更多的特性(例如,人口日誌),但是首先我們嘗試一個更複雜的模型來看看它的表現如何。

我們訓練一個決策樹回歸模型。

這是一個強大的模型,能夠在數據中找到複雜的非線性關係(決策樹在第6章中給出了更多的細節):

我日,亮瞎我的狗眼!誒,其實這次模型又過擬合了!咋地,你不信是過擬合?接著看

使用交叉驗證進行更好的評估

我們前面所說,在準備好啟動所確信的模型之前,不要接觸測試集,因此需要使用訓練集的一部分進行訓練,並另一部分進行驗證。

評估決策樹模型的一種方法是使用train_test_split函數將訓練集劃分成更小的訓練集和驗證集,然後在小訓練集訓練你的模型,在驗證集上評估模型。這的確多了一個步驟,但沒有什麼太困難,而且會工作得很好。

我們選擇是使用scikitt-learn的交叉驗證功能。

下面的代碼執行K-fold交叉驗證:它隨機將訓練集分成10個不同的子集,稱為folds(摺疊),然後對決策樹模型進行10次訓練和評估,每次都為評估選擇不同的fold項,並對其他9個fold進行訓練。結果是一個包含10個評價分數的數組。

scikitt -learn交叉驗證效果的度量使用效用函數(值越大越好)而不是損失函數(越低越好),所以得分函數實際上與MSE相反。所以代碼在計算平方根之前計算分數並取反。

現在決策樹看起來不像之前那麼好了。事實上,它似乎比線性回歸模型更糟糕!

注意:交叉驗證不僅可以獲得模型性能的估計值,還可以度量這個估計值的精確程度:標準偏差

決策樹大約71844分,一般±1668分。

如果您只使用了一個驗證集,您就不會得到這些信息。但是交叉驗證的代價是對模型進行多次培訓,因此不是總能這樣做(性能問題)。

我們用線性回歸模型再試一下:

現在我們就可以看到,決策樹模型過擬合了,以致於它的性能比線性回歸模型還要差。

這尼瑪怎麼辦呢?不要怕!我們還有更厲害的武器:隨機森林回歸模型!

在第7章中就能知道,隨機森林是通過對各種特徵的隨機子集訓練許多決策樹,然後對它們的預測進行平均。

在許多其他模型之上構建一個模型稱為集成學習,這通常是進一步推進ML演算法的一個好方法。(以後再講解)

哇,這就很靈性了,隨機森林看起來很有前途哦。

但是請注意,訓練集上的分數仍然比驗證集低很多,這意味著模型在訓練集上任然過擬合。對於過度擬合的可能解決方案是簡化模型,約束它(即正則化),或者得到更多的訓練數據。

然而,您深入研究隨機森林之前,應該嘗試各種類型的機器學習演算法(svm、神經網路等),而不是先花費太多的時間來調整超參數。

我們的目標是列出一些(2到5個)比較好的模型。

我們應該保存試驗的每個模型,這樣就可以輕鬆地返回任何想要的模型。

確保既保存了超參數,又保存了訓練參數,以及交叉驗證的分數,或者實際的預測。

這將讓我們能夠比較不同模型類型的分數,並比較它們所犯的錯誤類型。

可以通過使用Python的pickle模塊或使用sklearn.externals.joblib(在序列化的大型NumPy數組時效率更高),輕鬆地保存scikitt-learn模型。

調整模型參數(調優模型)

我們假設有一個有前途的模型的候選名單。

現在需要對它們進行調優,讓我們來看看能做些什麼。

網格搜索

調優的一種方法是手工修改超參數,直到找到超參數值的一個很好的組合。但是這將是非常繁瑣的工作,可能沒有時間去探索足夠多的組合。

我們應該用scikitt - learn的GridSearchCV來代替你的手工搜索。

所需要做的就是告訴它你想讓它實驗哪些超參數,以及嘗試什麼值,它會使用交叉驗證來評估超參數和值的所有可能組合。

例如,下面的代碼搜尋關於隨機森林回歸的超參數值的最佳組合。

當不知道一個超參數應該有什麼值時,一個簡單的方法是嘗試連續的10次冪,或者如果想要更細粒度的搜索,如本例中所示的n_estimators超參數。

這個param_grid告訴Scikit-Learn首先評估3×4 = 12 個的n_estimators組合和超參數,max_features 值中指定的第一個dict(在第7章解釋這些超參數),然後嘗試所有2×3 = 6個的第二超參數的組合值,但這一次bootstrap 超參數的值設置為False,而不是true(true是超參數的默認值)。

因為30是被評估的n_estimator的最大值,所以我們也應該評估更高的值,分數可能會繼續提高。

如果GridSearchCV用refit=True初始化(默認值),那麼一旦它找到了使用交叉驗證的最佳估計數,它就會在整個訓練集中重新訓練它。這通常是一個好主意,因為給它提供更多的數據可能會提高它的性能。

我們再看看超參數的每個組合的得分:

在本例中,我們通過將max_features超參數設置為8,並將n_estimators超參數設置為30來獲得最佳解決方案。這個組合的RMSE評分為49822,比之前使用默認超參數值的分數稍好一點。

祝賀你,你已經成功地調優到最好的模型。

注意:你可以將一些數據準備步驟作為超參數處理。

例如,網格搜索將自動決定是否添加一個不確定的特性(例如,在CombinedAttributesAdder 轉換器中使用add_bedrooms_per_room超參數)。

同樣,它也可以用來自動找到最好的方法去處理異常值、丟失的特徵、特徵的選擇等。

隨機搜索

當你在探索相對較少的組合時,網格搜索方法是可以的,比如在前面的例子中,但是當超參數搜索空間很大時,通常最好使用RandomizedSearchCV 代替:

這個類和GridSearchCV類基本一樣的使用方法,但是它不是嘗試所有可能的組合,而是通過在每次迭代中根據給定的個數隨機組合超參數,每個超參數選擇一個隨機值來評估。

這種方法有兩個主要好處:

如果隨機搜索1000次迭代,這個方法將為每個超參數探索1000個不同的值(而不是用網格搜索方法每一個超參數值幾個值)。

通過設置迭代次數,您可以對要分配給超參數搜索的計算預算進行更多的控制。

集成方法

調整系統的另一種方法是嘗試將性能最好的模型組合起來。

這個組(或「集成」)通常會比最佳的個體模型表現得更好(就像隨機森林比他們所依賴的個體決策樹要好),尤其是當單個模型產生非常不同類型的錯誤時。

我們將在第七章中更詳細地討論這個主題。

分析最好的模型及其錯誤

通過對最好的模型進行查看,你會經常得到關於這個問題的深刻見解。

例如,隨機森林回歸可以指出每個屬性的相對重要性,以便作出準確的預測

讓我們在它們相應的屬性名稱旁邊顯示重要性評分

有了這些信息,我們可能會嘗試刪除一些不太有用的特徵(例如,只有一個海洋接近類別是非常有用的,所以可以嘗試刪除其他的特徵)。

您還應該了解系統所犯的特定錯誤,然後試著理解它為什麼會產生這些錯誤,以及如何解決問題(添加額外的特徵,或者相反,清除那些沒有信息的特徵,清除異常值等等)。

在測試集中評估系統

在對模型進行了一段時間的調整之後,最終會得到一個運行良好的系統。

現在是在測試集評估的最終模型的時候了。只需從測試集中獲取預測值和真實目標值,運行full_pipeline來轉換數據(調用transform(),而不是fit_transform()),並對測試集上的最終模型進行評估。

如果我們進行了大量的超參數調優(因為系統在驗證數據上執行得很好,並且很可能在未知的數據集上執行得不是很好),那麼此性能得分通常會比使用交叉驗證評估到的要差一些。

雖然在本例中不是這樣,但是當發生這種情況時,不能為了使測試集評估更好而修改超參數。

發布解決方案

現在是項目發布前的階段:需要展示你的解決方案(強調你所學到的,什麼做了什麼沒做,做出了哪些假設,你的系統的局限性是什麼),記錄一切,用清晰的可視化的材料和容易記住的語句(例如,「中位數收入是房價的頭號預測指標。」)來準備好你的報告。

啟動、監視和維護系統

太好了,我們的預測系統被批准發布了!

你需要為生產準備好解決方案,特別是將生產輸入數據源插入到系統中並編寫測試。

你還需要編寫監控代碼來定期檢查系統的實時性能,並在它下降時觸發警報。這一點很重要,不僅要捕捉到突然的錯誤,還要注意性能的累積下降。這是很常見的,因為隨著時間的推移,模型往往會「腐爛」,除非模型定期接受新數據的培訓。

評估系統的性能需要對系統的預測進行採樣並對其進行評估。這通常需要人的分析。

這些分析師可能是現場專家,也可能是眾包平台上的員工(比如亞馬遜(Amazon)的土耳其機器人(Amazon Mechanical Turk)或CrowdFlower)。無論哪種方式,都需要將人評估管道插入到系統中。

你還應該確保評估了系統的輸入數據質量。有時性能會因為劣質信號(例如發送隨機值的故障感測器或另一個團隊的輸出變得陳舊)而輕微降級,但在系統性能下降到足以觸發警報之前可能需要一段時間。如果你監視系統的輸入,可能會更早地發現它。監控輸入對在線學習系統尤其重要。

最後,你通常希望使用新的數據定期培訓你的模型。你應該儘可能地自動化這個過程。如果不這樣做,很有可能每六個月更新一次你的模型(最好情況),你的系統的性能可能會隨著時間的推移而大幅波動。

如果你的系統是一個在線學習系統,你應該確保定期保存其狀態的快照,這樣就可以輕鬆地回滾到以前的工作狀態。

試一下

希望這一章能讓你了解機器學習項目是什麼樣子,並向你展示了一些可以用來培訓大型系統的工具。

正如你所看到的,大部分工作都是在數據準備步驟、構建監控工具、建立人工的評估管道和自動化常規模型培訓。

當然,機器學習演算法也很重要,但最好是對整個過程感到滿意,並且知道三到四種演算法,而不是花所有的時間去探索高級演算法而在整個過程中花費的時間不足。

如果你還沒有這樣做,現在是一個很好的時間去拿一台筆記本電腦,選擇一個你感興趣的數據集,並試試完成整個過程。kaggle是一個很好的起點,你將有一個數據集,一個明確的目標,並和很多人們分享經驗。

終於翻譯並整理出第二章,後面的章節還會繼續發出來,並且速度應該更快了。

少年們,說真的,這一篇真的可以點個贊並評論幾句的,這是一個很好的機器學習工程入門教程。如有錯誤或疑問,歡迎指出啊!

最後感謝作者,a great book!

done 2018年2月28日00:01:36

推薦閱讀:

十分種讀懂KNN
關於機器學習、數據科學面試的準備
2018AI學習清單丨150個最好的機器學習和Python教程
複習:NN和BP
引領深度學習革命--CNN架構全解析

TAG:機器學習 |