尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️
文章節選自《機器學習——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實踐》非常適合於項目經理、有意從事機器學習開發的工程師,以及高校相關專業在的讀學生閱讀。
《機器學習——Python實踐》訂購鏈接(點擊閱讀原文訂購):https://item.jd.com/12252293.html
長按下圖,識別小程序參與抽獎,本次送出5本新書,歡迎參與!
友情提醒:
結束後不用索要中獎者的地址,中獎者可直接填寫即可,發起人即刻收到,一鍵復制全部信息;中獎後別忘了填寫地址。