1. 程式人生 > >Python & 機器學習之專案實踐

Python & 機器學習之專案實踐

機器學習是一項經驗技能,經驗越多越好。在專案建立的過程中,實踐是掌握機器學習的最佳手段。在實踐過程中,通過實際操作加深對分類和迴歸問題的每一個步驟的理解,達到學習機器學習的目的。

預測模型專案模板

不能只通過閱讀來掌握機器學習的技能,需要進行大量的練習。本文將介紹一個通用的機器學習的專案模板,建立這個模板總共有六個步驟。通過本文將學到:

  • 端到端地預測(分類與迴歸)模型的專案結構。
  • 如何將前面學到的內容引入到專案中。
  • 如何通過這個專案模板來得到一個高準確度的模板。

機器學習是針對資料進行自動挖掘,找出資料的內在規律,並應用這個規律來預測新資料,如圖19-1所示。

圖片描述

圖19-1

在專案中實踐機器學習

端到端地解決機器學習的問題是非常重要的。可以學習機器學習的知識,可以實踐機器學習的某個方面,但是隻有針對某一個問題,從問題定義開始到模型部署為止,通過實踐機器學習的各個方面,才能真正掌握並應用機器學習來解決實際問題。

在部署一個專案時,全程參與到專案中可以更加深入地思考如何使用模型,以及勇於嘗試用機器學習解決問題的各個方面,而不僅僅是參與到自己感興趣或擅長的方面。一個很好的實踐機器學習專案的方法是,使用從 UCI機器學習倉庫(http://archive.ics.uci.edu/ml/datasets.html) 獲取的資料集開啟一個機器學習專案。如果從一個數據集開始實踐機器學習,應該如何將學到的所有技巧和方法整合到一起來處理機器學習的問題呢?

分類或迴歸模型的機器學習專案可以分成以下六個步驟:

(1)定義問題。
(2)理解資料。
(3)資料準備。
(4)評估演算法。
(5)優化模型。
(6)結果部署。

有時這些步驟可能被合併或進一步分解,但通常是按上述六個步驟來開展機器學習專案的。為了符合Python的習慣,在下面的Python專案模板中,按照這六個步驟分解整個專案,在接下來的部分會明確各個步驟或子步驟中所要實現的功能。

機器學習專案的Python模板

下面會給出一個機器學習專案的Python模板。程式碼如下:

# Python機器學習專案的模板

# 1. 定義問題
# a) 匯入類庫
# b) 匯入資料集
# 2. 理解資料 # a) 描述性統計 # b) 資料視覺化 # 3. 資料準備 # a) 資料清洗 # b) 特徵選擇 # c) 資料轉換 # 4. 評估演算法 # a) 分離資料集 # b) 定義模型評估標準 # c) 演算法審查 # d) 演算法比較 # 5. 優化模型 # a) 演算法調參 # b) 整合演算法 # 6. 結果部署 # a) 預測評估資料集 # b) 利用整個資料集生成模型 # c) 序列化模型

當有新的機器學習專案時,新建一個Python檔案,並將這個模板貼上進去,再按照前面章節介紹的方法將其填充到每一個步驟中。

各步驟的詳細說明

接下來將詳細介紹專案模板的各個步驟。

步驟1:定義問題

主要是匯入在機器學習專案中所需要的類庫和資料集等,以便完成機器學習的專案,包括匯入Python的類庫、類和方法,以及匯入資料。同時這也是所有的配置引數的配置模組。當資料集過大時,可以在這裡對資料集進行瘦身處理,理想狀態是可以在1分鐘內,甚至是30秒內完成模型的建立或視覺化資料集。

步驟2:理解資料

這是加強對資料理解的步驟,包括通過描述性統計來分析資料和通過視覺化來觀察資料。在這一步需要花費時間多問幾個問題,設定假設條件並調查分析一下,這對模型的建立會有很大的幫助。

步驟3:資料準備

資料準備主要是預處理資料,以便讓資料可以更好地展示問題,以及熟悉輸入與輸出結果的關係。包括:

  • 通過刪除重複資料、標記錯誤數值,甚至標記錯誤的輸入資料來清洗資料。
  • 特徵選擇,包括移除多餘的特徵屬性和增加新的特徵屬性。
  • 資料轉化,對資料尺度進行調整,或者調整資料的分佈,以便更好地展示問題。

要不斷地重複這個步驟和下一個步驟,直到找到足夠準確的演算法生成模型。

步驟4:評估演算法

評估演算法主要是為了尋找最佳的演算法子集,包括:

  • 分離出評估資料集,以便於驗證模型。
  • 定義模型評估標準,用來評估演算法模型。
  • 抽樣審查線性演算法和非線性演算法。
  • 比較演算法的準確度。

在面對一個機器學習的問題的時候,需要花費大量的時間在評估演算法和準備資料上,直到找到3~5種準確度足夠的演算法為止。

步驟5:優化模型

當得到一個準確度足夠的演算法列表後,要從中找出最合適的演算法,通常有兩種方法可以提高演算法的準確度:

  • 對每一種演算法進行調參,得到最佳結果。
  • 使用集合演算法來提高演算法模型的準確度。

步驟6:結果部署

一旦認為模型的準確度足夠高,就可以將這個模型序列化,以便有新資料時使用該模型來預測資料。

  • 通過驗證資料集來驗證被優化過的模型。
  • 通過整個資料集來生成模型。
  • 將模型序列化,以便於預測新資料。

做到這一步的時候,就可以將模型展示併發布給相關人員。當有新資料產生時,就可以採用這個模型來預測新資料。

使用模板的小技巧

快速執行一遍:首先要快速地在專案中將模板中的每一個步驟執行一遍,這樣會加強對專案每一部分的理解並給如何改進帶來靈感。

迴圈:整個流程不是線性的,而是迴圈進行的,要花費大量的時間來重複各個步驟,尤其是步驟3或步驟4(或步驟3~步驟5),直到找到一個準確度足夠的模型,或者達到預定的週期。

嘗試每一個步驟:跳過某個步驟很簡單,尤其是不熟悉、不擅長的步驟。堅持在這個模板的每一個步驟中做些工作,即使這些工作不能提高演算法的準確度,但也許在後面的操作就可以改進並提高演算法的準確度。即使覺得這個步驟不適用,也不要跳過這個步驟,而是減少該步驟所做的貢獻。

定向準確度:機器學習專案的目標是得到一個準確度足夠高的模型。每一個步驟都要為實現這個目標做出貢獻。要確保每次改變都會給結果帶來正向的影響,或者對其他的步驟帶來正向的影響。在整個專案的每個步驟中,準確度只能向變好的方向移動。
按需適用:可以按照專案的需要來修改步驟,尤其是對模板中的各個步驟非常熟悉之後。需要把握的原則是,每一次改進都以提高演算法模型的準確度為前提。

總結

本章介紹了預測模型專案的模板,這個模板適用於分類或迴歸問題。接下來將介紹機器學習中的一個迴歸問題的專案,這個專案比前面介紹的鳶尾花的例子更加複雜,會利用到本章介紹的每個步驟。

迴歸專案例項

機器學習是一項經驗技能,實踐是掌握機器學習、提高利用機器學習解決問題的能力的有效方法之一。那麼如何通過機器學習來解決問題呢?本章將通過一個例項來一步一步地介紹一個迴歸問題。本章主要介紹以下內容:

  • 如何端到端地完成一個迴歸問題的模型。
  • 如何通過資料轉換提高模型的準確度。
  • 如何通過調參提高模型的準確度。
  • 如何通過整合演算法提高模型的準確度。

定義問題

在這個專案中將分析研究波士頓房價(Boston House Price)資料集,這個資料集中的每一行資料都是對波士頓周邊或城鎮房價的描述。資料是1978年統計收集的。資料中包含以下14個特徵和506條資料(UCI機器學習倉庫中的定義)。

  • CRIM:城鎮人均犯罪率。
  • ZN:住宅用地所佔比例。
  • INDUS:城鎮中非住宅用地所佔比例。
  • CHAS:CHAS虛擬變數,用於迴歸分析。
  • NOX:環保指數。
  • RM:每棟住宅的房間數。
  • AGE:1940年以前建成的自住單位的比例。
  • DIS:距離5個波士頓的就業中心的加權距離。
  • RAD:距離高速公路的便利指數。
  • TAX:每一萬美元的不動產稅率。
  • PRTATIO:城鎮中的教師學生比例。
  • B:城鎮中的黑人比例。
  • LSTAT:地區中有多少房東屬於低收入人群。
  • MEDV:自住房屋房價中位數。

通過對這些特徵屬性的描述,我們可以發現輸入的特徵屬性的度量單位是不統一的,也許需要對資料進行度量單位的調整。

匯入資料

首先匯入在專案中需要的類庫。程式碼如下:

# 匯入類庫
import numpy as np
from numpy import arange
from matplotlib import pyplot
from pandas import read_csv
from pandas import  set_option
from pandas.plotting import scatter_matrix
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import ElasticNet
from sklearn.tree import DecisionTreeRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.svm import SVR
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.ensemble import ExtraTreesRegressor
from sklearn.ensemble import AdaBoostRegressor
from sklearn.metrics import mean_squared_error

接下來匯入資料集到Python中,這個資料集也可以從UCI機器學習倉庫下載,在匯入資料集時還設定了資料屬性特徵的名字。程式碼如下:

# 匯入資料
filename = 'housing.csv'
names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS',
         'RAD', 'TAX', 'PRTATIO', 'B', 'LSTAT', 'MEDV']
data = read_csv(filename, names=names, delim_whitespace=True)

在這裡對每一個特徵屬性設定了一個名稱,以便於在後面的程式中使用它們。因為CSV檔案是使用空格鍵做分隔符的,因此讀入CSV檔案時指定分隔符為空格鍵(delim_whitespace=True)。

理解資料

對匯入的資料進行分析,便於構建合適的模型。

首先看一下資料維度,例如資料集中有多少條記錄、有多少個數據特徵。程式碼如下:

# 資料維度
print(dataset.shape)

執行之後我們可以看到總共有506條記錄和14個特徵屬性,這與UCI提供的資訊一致。

(506, 14)

再檢視各個特徵屬性的欄位型別。程式碼如下:

# 特徵屬性的欄位型別
print(dataset.dtypes)

可以看到所有的特徵屬性都是數字,而且大部分特徵屬性都是浮點數,也有一部分特徵屬性是整數型別的。執行結果如下:

CRIM       float64
ZN         float64
INDUS      float64
CHAS         int64
NOX        float64
RM         float64
AGE        float64
DIS        float64
RAD          int64
TAX        float64  
PRTATIO    float64
B          float64
LSTAT      float64
MEDV       float64
dtype: object

接下來對資料進行一次簡單的檢視,在這裡我們檢視一下最開始的30條記錄。程式碼如下:

# 檢視最開始的30條記錄
set_option('display.line_width', 120)
print(dataset.head(30))

這裡指定輸出的寬度為120個字元,以確保將所有特徵屬性值顯示在一行內。而且這些資料不是用相同的單位儲存的,進行後面的操作時,也許需要將資料整理為相同的度量單位。執行結果如圖20-1所示。

圖片描述
圖20-1

接下來看一下資料的描述性統計資訊。程式碼如下:

# 描述性統計資訊
set_option('precision', 1)
print(dataset.describe())

在描述性統計資訊中包含資料的最大值、最小值、中位值、四分位值等,分析這些資料能夠加深對資料分佈、資料結構等的理解。結果如圖20-2所示。

圖片描述

圖20-2

接下來看一下資料特徵之間的兩兩關聯關係,這裡檢視資料的皮爾遜相關係數。程式碼如下:

# 關聯關係
set_option('precision', 2)
print(dataset.corr(method='pearson'))

執行結果如圖20-3所示。

圖片描述

圖20-3

通過上面的結果可以看到,有些特徵屬性之間具有強關聯關係(>0.7或<-0.7),如:

  • NOX與INDUS之間的皮爾遜相關係數是0.76。
  • DIS與INDUS之間的皮爾遜相關係數是-0.71。
  • TAX與INDUS之間的皮爾遜相關係數是0.72。
  • AGE與NOX之間的皮爾遜相關係數是0.73。
  • DIS與NOX之間的皮爾遜相關係數是-0.77。

資料視覺化

單一特徵圖表

首先檢視每一個數據特徵單獨的分佈圖,多檢視幾種不同的圖表有助於發現更好的方法。我們可以通過檢視各個資料特徵的直方圖,來感受一下資料的分佈情況。程式碼如下:

# 直方圖
dataset.hist(sharex=False, sharey=False, xlabelsize=1, ylabelsize=1)
pyplot.show()

執行結果如圖20-4所示,從圖中可以看到有些資料呈指數分佈,如CRIM、ZN、AGE和B;有些資料特徵呈雙峰分佈,如RAD和TAX。

圖片描述

圖20-4

通過密度圖可以展示這些資料的特徵屬性,密度圖比直方圖更加平滑地展示了這些資料特徵。程式碼如下:

# 密度圖
dataset.plot(kind='density', subplots=True, layout=(4,4), sharex=False, fontsize=1)
pyplot.show()

在密度圖中,指定layout=(4, 4),這說明要畫一個四行四列的圖形。執行結果如圖20-5所示。

圖片描述

圖20-5

通過箱線圖可以檢視每一個數據特徵的狀況,也可以很方便地看出資料分佈的偏態程度。程式碼如下:

#箱線圖
dataset.plot(kind='box', subplots=True, layout=(4,4), sharex=False, sharey=False, fontsize=8)
pyplot.show()

執行結果如圖20-6所示。

圖片描述`

圖20-6

多重資料圖表

接下來利用多重資料圖表來檢視不同資料特徵之間的相互影響關係。首先看一下散點矩陣圖。程式碼如下:

# 散點矩陣圖
scatter_matrix(dataset)
pyplot.show()

通過散點矩陣圖可以看到,雖然有些資料特徵之間的關聯關係很強,但是這些資料分佈結構也很好。即使不是線性分佈結構,也是可以很方便進行預測的分佈結構,執行結果如圖20-7所示。

圖片描述

圖20-7

再看一下資料相互影響的相關矩陣圖。程式碼如下:

# 相關矩陣圖
fig = pyplot.figure()
ax = fig.add_subplot(111)
cax = ax.matshow(dataset.corr(), vmin=-1, vmax=1, interpolation='none')
fig.colorbar(cax)
ticks = np.arange(0, 14, 1)
ax.set_xticks(ticks)
ax.set_yticks(ticks)
ax.set_xticklabels(names)
ax.set_yticklabels(names)
pyplot.show()

執行結果如圖20-8所示,根據圖例可以看到,資料特徵屬性之間的兩兩相關性,有些屬性之間是強相關的,建議在後續的處理中移除這些特徵屬性,以提高演算法的準確度。

圖片描述

圖20-8

思路總結

通過資料的相關性和資料的分佈等發現,資料集中的資料結構比較複雜,需要考慮對資料進行轉換,以提高模型的準確度。可以嘗試從以下幾個方面對資料進行處理:

  • 通過特徵選擇來減少大部分相關性高的特徵。
  • 通過標準化資料來降低不同資料度量單位帶來的影響。
  • 通過正態化資料來降低不同的資料分佈結構,以提高演算法的準確度。

可以進一步檢視資料的可能性分級(離散化),它可以幫助提高決策樹演算法的準確度。

分離評估資料集

分離出一個評估資料集是一個很好的主意,這樣可以確保分離出的資料集與訓練模型的資料集完全隔離,有助於最終判斷和報告模型的準確度。在進行到專案的最後一步處理時,會使用這個評估資料集來確認模型的準確度。這裡分離出20%的資料作為評估資料集,80%的資料作為訓練資料集。程式碼如下:

# 分離資料集
array = dataset.values
X = array[:, 0:13]
Y = array[:, 13]
validation_size = 0.2
seed = 7
X_train, X_validation, Y_train, Y_validation = train_test_split(X, Y,test_size=validation_size, random_state=seed)

評估演算法

評估演算法——原始資料

分析完資料不能立刻選擇出哪個演算法對需要解決的問題最有效。我們直觀上認為,由於部分資料的線性分佈,線性迴歸演算法和彈性網路迴歸演算法對解決問題可能比較有效。另外,由於資料的離散化,通過決策樹演算法或支援向量機演算法也許可以生成高準確度的模型。到這裡,依然不清楚哪個演算法會生成準確度最高的模型,因此需要設計一個評估框架來選擇合適的演算法。我們採用10折交叉驗證來分離資料,通過均方誤差來比較演算法的準確度。均方誤差越趨近於0,演算法準確度越高。程式碼如下:

# 評估演算法 —— 評估標準
num_folds = 10
seed = 7
scoring = 'neg_mean_squared_error'

對原始資料不做任何處理,對演算法進行一個評估,形成一個演算法的評估基準。這個基準值是對後續演算法改善優劣比較的基準值。我們選擇三個線性演算法和三個非線性演算法來進行比較。

線性演算法:線性迴歸(LR)、套索迴歸(LASSO)和彈性網路迴歸(EN)。
非線性演算法:分類與迴歸樹(CART)、支援向量機(SVM)和K近鄰演算法(KNN)。

演算法模型初始化的程式碼如下:

# 評估演算法 - baseline
models = {}
models['LR'] = LinearRegression()
models['LASSO'] = Lasso()
models['EN'] = ElasticNet()
models['KNN']  = KNeighborsRegressor()
models['CART'] = DecisionTreeRegressor()
models['SVM'] = SVR()

對所有的演算法使用預設引數,並比較演算法的準確度,此處比較的是均方誤差的均值和標準方差。程式碼如下:

# 評估演算法
results = []
for key in models:
    kfold = KFold(n_splits=num_folds, random_state=seed)
    cv_result = cross_val_score(models[key], X_train, Y_train, cv=kfold, scoring=scoring)
    results.append(cv_result)
    print('%s: %f (%f)' % (key, cv_result.mean(), cv_result.std()))

從執行結果來看,線性迴歸(LR)具有最優的MSE,接下來是分類與迴歸樹 (CART)演算法。執行結果如下:

LR: -21.379856 (9.414264)
LASSO: -26.423561 (11.651110)
EN: -27.502259 (12.305022)
KNN: -41.896488 (13.901688)
CART: -26.608476 (12.250800)
SVM: -85.518342 (31.994798)

再檢視所有的10折交叉分離驗證的結果。程式碼如下:

#評估演算法——箱線圖
fig = pyplot.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results)
ax.set_xticklabels(models.keys())
pyplot.show()

執行結果如圖20-9所示,從圖中可以看到,線性演算法的分佈比較類似,並且K近鄰演算法的結果分佈非常緊湊。

圖片描述

圖20-9

不同的資料度量單位,也許是K近鄰演算法和支援向量機演算法表現不佳的主要原因。下面將對資料進行正態化處理,再次比較演算法的結果。

評估演算法——正態化資料

在這裡猜測也許因為原始資料中不同特徵屬性的度量單位不一樣,導致有的演算法的結果不是很好。接下來通過對資料進行正態化,再次評估這些演算法。在這裡對訓練資料集進行資料轉換處理,將所有的資料特徵值轉化成“0”為中位值、標準差為“1”的資料。對資料正態化時,為了防止資料洩露,採用Pipeline來正態化資料和對模型進行評估。為了與前面的結果進行比較,此處採用相同的評估框架來評估演算法模型。程式碼如下:

# 評估演算法——正態化資料
pipelines = {}
pipelines['ScalerLR'] = Pipeline([('Scaler', StandardScaler()), ('LR', LinearRegression())])
pipelines['ScalerLASSO'] = Pipeline([('Scaler', StandardScaler()), ('LASSO', Lasso())])
pipelines['ScalerEN'] = Pipeline([('Scaler', 
StandardScaler()), ('EN', ElasticNet())])
pipelines['ScalerKNN'] = Pipeline([('Scaler', 
StandardScaler()), ('KNN', KNeighborsRegressor())])
pipelines['ScalerCART'] = Pipeline([('Scaler', 
StandardScaler()), ('CART', DecisionTreeRegressor())])
pipelines['ScalerSVM'] = Pipeline([('Scaler', 
StandardScaler()), ('SVM', SVR())])
results = []
for key in pipelines:
    kfold = KFold(n_splits=num_folds, random_state=seed)
    cv_result = cross_val_score(pipelines[key], X_train, Y_train, cv=kfold, scoring=scoring)
    results.append(cv_result)
    print('%s: %f (%f)' % (key, cv_result.mean(), cv_result.std()))

執行後發現K近鄰演算法具有最優的MSE。執行結果如下:

ScalerLR: -21.379856 (9.414264)
ScalerLASSO: -26.607314 (8.978761)
ScalerEN: -27.932372 (10.587490)
ScalerKNN: -20.107620 (12.376949)
ScalerCART: -26.978716 (12.164366)
ScalerSVM: -29.633086 (17.009186)

接下來看一下所有的10折交叉分離驗證的結果。程式碼如下:

#評估演算法——箱線圖
fig = pyplot.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results)
ax.set_xticklabels(models.keys())
pyplot.show()

執行結果,生成的箱線圖如圖20-10所示,可以看到K近鄰演算法具有最優的MSE和最緊湊的資料分佈。

圖片描述

調參改善演算法

目前來看,K近鄰演算法對做過資料轉換的資料集有很好的結果,但是是否可以進一步對結果做一些優化呢?K近鄰演算法的預設引數近鄰個數(n_neighbors)是5,下面通過網格搜尋演算法來優化引數。程式碼如下:

# 調參改善演算法——KNN
scaler = StandardScaler().fit(X_train)
rescaledX = scaler.transform(X_train)
param_grid = {'n_neighbors': [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]}
model = KNeighborsRegressor()
kfold = KFold(n_splits=num_folds, random_state=seed)
grid = GridSearchCV(estimator=model, 
param_grid=param_grid, scoring=scoring, cv=kfold)
grid_result = grid.fit(X=rescaledX, y=Y_train)

print('最優:%s 使用%s' % (grid_result.best_score_, grid_result.best_params_))
cv_results = 
zip(grid_result.cv_results_['mean_test_score'],

grid_result.cv_results_['std_test_score'],
                 grid_result.cv_results_['params'])
for mean, std, param in cv_results:
    print('%f (%f) with %r' % (mean, std, param))

最優結果——K近鄰演算法的預設引數近鄰個數(n_neighbors)是3。執行結果如下:

最優:-18.1721369637 使用{'n_neighbors': 3}
-20.208663 (15.029652) with {'n_neighbors': 1}
-18.172137 (12.950570) with {'n_neighbors': 3}
-20.131163 (12.203697) with {'n_neighbors': 5}
-20.575845 (12.345886) with {'n_neighbors': 7}
-20.368264 (11.621738) with {'n_neighbors': 9}
-21.009204 (11.610012) with {'n_neighbors': 11}
-21.151809 (11.943318) with {'n_neighbors': 13}
-21.557400 (11.536339) with {'n_neighbors': 15}
-22.789938 (11.566861) with {'n_neighbors': 17}
-23.871873 (11.340389) with {'n_neighbors': 19}
-24.361362 (11.914786) with {'n_neighbors': 21}

整合演算法

除調參之外,提高模型準確度的方法是使用整合演算法。下面會對錶現比較好的線性迴歸、K近鄰、分類與迴歸樹演算法進行整合,來看看演算法能否提高。

裝袋演算法:隨機森林(RF)和極端隨機樹(ET)。
提升演算法:AdaBoost(AB)和隨機梯度上升(GBM)。

依然採用和前面同樣的評估框架和正態化之後的資料來分析相關的演算法。程式碼如下:

# 整合演算法
ensembles = {}
ensembles['ScaledAB'] = Pipeline([('Scaler',
StandardScaler()), ('AB', AdaBoostRegressor())])
ensembles['ScaledAB-KNN'] = Pipeline([('Scaler', 
StandardScaler()), ('ABKNN', AdaBoostRegressor
(base_estimator= KNeighborsRegressor(n_neighbors=3)))])
ensembles['ScaledAB-LR'] = Pipeline([('Scaler', 
StandardScaler()), ('ABLR',
AdaBoostRegressor(LinearRegression()))])
ensembles['ScaledRFR'] = Pipeline([('Scaler', 
StandardScaler()), ('RFR', RandomForestRegressor())])
ensembles['ScaledETR'] = Pipeline([('Scaler', 
StandardScaler()), ('ETR', ExtraTreesRegressor())])
ensembles['ScaledGBR'] = Pipeline([('Scaler', 
StandardScaler()), ('RBR', GradientBoostingRegressor())])

results = []
for key in ensembles:
    kfold = KFold(n_splits=num_folds, random_state=seed)
    cv_result = cross_val_score(ensembles[key], X_train, Y_train, cv=kfold, scoring=scoring)
    results.append(cv_result)
    print('%s: %f (%f)' % (key, cv_result.mean(), cv_result.std()))

與前面的線性演算法和非線性演算法相比,這次的準確度都有了較大的提高。執行結果如下:

ScaledAB: -15.244803 (6.272186)
ScaledAB-KNN: -15.794844 (10.565933)
ScaledAB-LR: -24.108881 (10.165026)
ScaledRFR: -13.279674 (6.724465)
ScaledETR: -10.464980 (5.476443)
ScaledGBR: -10.256544 (4.605660)

接下來通過箱線圖看一下整合演算法在10折交叉驗證中均方誤差的分佈狀況。程式碼如下:

# 整合演算法——箱線圖
fig = pyplot.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results)
ax.set_xticklabels(ensembles.keys())
pyplot.show()

執行結果如圖20-11所示,隨機梯度上升演算法和極端隨機樹演算法具有較高的中位值和分佈狀況。

圖片描述

圖20-11

整合演算法調參

整合演算法都有一個引數n_estimators,這是一個很好的可以用來調整的引數。對於整合引數來說,n_estimators會帶來更準確的結果,當然這也有一定的限度。下面對隨機梯度上升(GBM)和極端隨機樹(ET)演算法進行調參,再次比較這兩個演算法模型的準確度,來確定最終的演算法模型。程式碼如下:

# 整合演算法GBM——調參
caler = StandardScaler().fit(X_train)
rescaledX = scaler.transform(X_train)
param_grid = {'n_estimators': [10, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900]}
model = GradientBoostingRegressor()
kfold = KFold(n_splits=num_folds, random_state=seed)
grid = GridSearchCV(estimator=model, 
param_grid=param_grid, scoring=scoring, cv=kfold)
grid_result = grid.fit(X=rescaledX, y=Y_train)
print('最優:%s 使用%s' % (grid_result.best_score_, 
grid_result.best_params_))

# 整合演算法ET——調參
scaler = StandardScaler().fit(X_train)
rescaledX = scaler.transform(X_train)
param_grid = {'n_estimators': [5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]}
model = ExtraTreesRegressor()
kfold = KFold(n_splits=num_folds, random_state=seed)
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring=scoring, cv=kfold)
grid_result = grid.fit(X=rescaledX, y=Y_train)
print('最優:%s 使用%s' % (grid_result.best_score_, grid_result.best_params_))

對於隨機梯度上升(GBM)演算法來說,最優的n_estimators是500;對於極端隨機樹(ET)演算法來說,最優的n_estimators是80。執行結果,極端隨機樹(ET)演算法略優於隨機梯度上升(GBM)演算法,因此採用極端隨機樹(ET)演算法來訓練最終的模型。執行結果如下:

最優:-9.3078229754 使用{'n_estimators': 500}
最優:-8.99113433246 使用{'n_estimators': 80}

也許需要執行多次這個過程才能找到最優引數。這裡有一個技巧,當最優引數是param_grid的邊界值時,有必要調整param_grid進行下一次調參。

確定最終模型

我們已經確定了使用極端隨機樹(ET)演算法來生成模型,下面就對該演算法進行訓練和生成模型,並計算模型的準確度。程式碼如下:

#訓練模型
caler = StandardScaler().fit(X_train)
rescaledX = scaler.transform(X_train)
gbr = ExtraTreesRegressor(n_estimators=80)
gbr.fit(X=rescaledX, y=Y_train)

再通過評估資料集來評估演算法的準確度。

# 評估演算法模型
rescaledX_validation = scaler.transform(X_validation)
predictions = gbr.predict(rescaledX_validation)
print(mean_squared_error(Y_validation, predictions))

執行結果如下:

14.077038511

總結

本專案例項從問題定義開始,直到最後的模型生成為止,完成了一個完整的機器學習專案。通過這個專案,理解了上一章中介紹的機器學習專案的模板,以及整個機器學習模型建立的流程。接下來會介紹一個機器學習的二分類問題,以進一步加深對這個模板的理解。

編者按:《機器學習——Python實踐》不同於很多講解機器學習的書籍,本書以實踐為導向,使用 scikit-learn 作為程式設計框架,強調簡單、快速地建立模型,解決實際專案問題。讀者通過對《機器學習——Python實踐》的學習,可以迅速上手實踐機器學習,並利用機器學習解決實際問題。《機器學習——Python實踐》非常適合於專案經理、有意從事機器學習開發的程式設計師,以及高校相關專業在的讀學生閱讀。訂購連結:https://item.jd.com/12252293.html

這裡寫圖片描述

相關推薦

Python & 機器學習專案實踐

機器學習是一項經驗技能,經驗越多越好。在專案建立的過程中,實踐是掌握機器學習的最佳手段。在實踐過程中,通過實際操作加深對分類和迴歸問題的每一個步驟的理解,達到學習機器學習的目的。 預測模型專案模板 不能只通過閱讀來掌握機器學習的技能,需要進行大量的練習。

Python 機器學習開發環境

sta HR nta 命令行 make 語言 anaconda 使用總結 2.6 Python 數據分析庫 Python 編程語言 Pythong Tutorial: https://docs.python.org/3/tutorial/ NumPy 提供常用的數值數組、矩

Python機器學習梯度提升樹

pri () 糾正 ensemble depth del gbrt 1.5 cer #和隨機森林一樣,基於決策樹,采用連續的方式構建樹,深度很小max_depth<5.重要的參數n_estimate和learning_rate,這兩個參數的y作用在於對模型過擬合化得調

Python機器學習資料預處理

# -*- coding: utf-8 -*- """ Created on Sat Sep 29 22:39:26 2018 @author: Lxiao217 email:[email protected] """ #資料預處理 #CSV(comma-srpared values,

Python機器學習實戰專案--預測紅酒質量(超詳細)

用Scikit-Learn(sklearn)建立模型 1 環境搭建  Python 3+NumPy+Pandas+Scikit-Learn (sklearn) 2 匯入庫和模組 Numpy是比Python自身的巢狀列表(nested list structure)結構要高效的多的一

十大Python機器學習開源專案

1、Scikit-learn 用於資料探勘和資料分析的簡單而有效的工具,基於NumPy,SciPy和matplotlib,開源,商業可用的BSD許可證。 2、Tensorflow  最初由Google機器智慧研究機構的Google Brain小組的研究人員和工程師開發

Python機器學習特徵工程

import numpy as np import matplotlib.pyplot as plt import pandas as pd import seaborn as sns from sklearn.model_selection import

python機器學習SMO演算法

SVM演算法計算到後面是一個帶約束條件的優化問題 這裡的SMO(Sequential Minimal Optimization)序列最小化演算法就是一個二次規劃優化演算法,可以用來解決上面的問題。SMO演算法是由John C.Platt在1998年提出的。SMO演算法的目

python機器學習--用凝聚層次聚類進行資料分組

1.什麼是層次聚類def perfrom_clustering(X,connectivity,title,num_clusters=3,linkage='ward'): plt.figure() model = AgglomerativeClustering(

20 個頂尖的 Python 機器學習開源專案

1. Scikit-learn www.github.com/scikit-learn/scikit-learn Scikit-learn 是基於Scipy為機器學習建造的的一個Python模組,他的特色就是多樣化的分類,迴歸和聚類的演算法包括支援向量機,邏輯迴歸,樸

python機器學習神經網路(二)

來自:http://blog.csdn.net/cui134/article/details/26823101 由於Rosenblatt感知器的侷限性,對於非線性分類的效果不理想。為了對線性分類無法區分的資料進行分類,需要構建多層感知器結構對資料進行分類,多層感

Python機器學習決策樹案例

# -*- coding: utf-8 -*- __author__ = 'gerry' # 先匯入所有的class import xgboost from numpy import * from s

python機器學習10分鐘掌握pandas

微信公眾號:資料探勘與分析學習 1.建立物件 通過傳遞值列表來建立Series,讓pandas建立一個預設的整數索引: 通過傳遞帶有日期時間索引和標記列的NumPy陣列來建立DataFrame: 通過傳遞可以轉換為類似series的物件的dict來建立Data

Python機器學習XGBoost從入門到實戰(基本理論說明)

Xgboost從基礎到實戰 XGBoost:eXtreme Gradient Boosting * 應用機器學習領域的一個強有力的工具 * Gradient Booting Machines(GBM)的優化表現,快速有效 —深盟

Python機器學習資料探索視覺化庫yellowbrick

背景介紹 從學sklearn時,除了演算法的坎要過,還得學習matplotlib視覺化,對我的實踐應用而言,視覺化更重要一些,然而

Python機器學習資料探索視覺化庫yellowbrick-tutorial

背景介紹 從學sklearn時,除了演算法的坎要過,還得學習matplotlib視覺化,對我的實踐應用而言,視覺化更重要一些,然而matplotlib的易用性和美觀性確實不敢恭維。陸續使用過plotly、seaborn,最終定格在了Bokeh,因為它可以與Flask完美的結合,資料看板的開發難度降低了很多。

機器學習路: python 實踐 word2vec 詞向量技術

fetch 分離 ext .com work bsp re.sub 最終 mat git: https://github.com/linyi0604/MachineLearning 詞向量技術 Word2Vec 每個連續詞匯片段都會對後面有一定制約 稱為上下

機器學習路: python 實踐 提升樹 XGBoost 分類器

git mac class form 樹模型 機器 AS sta imp git: https://github.com/linyi0604/MachineLearning 數據集被我下載到本地,可以去我的git上拿數據集 XGBoost提升分類器 屬於集成學習模型

PYTHON機器學習實踐_從零開始通往KAGGLE競賽路pdf

【下載地址】 本書面向所有對機器學習與資料探勘的實踐及競賽感興趣的讀者,從零開始,以Python程式語言為基礎,在不涉及大量數學模型與複雜程式設計知識的前提下,逐步帶領讀者熟悉並且掌握當下最流行的機器學習、數learn作為基礎機器學習工具;第3章進階篇,涉及怎樣藉助高階技術或者模型進一步提升既有機器學習系統的

Python機器學習實踐》----無監督學習資料聚類

本片部落格是根據《Python機器學習及實踐》一書中的例項,所有程式碼均在本地編譯通過。資料為從該書指定的百度網盤上下載的,或者是sklearn自帶資料下載到本地使用的。 程式碼片段: # coding: utf-8 # 分別匯入numpy、matplot