適合練手的完整機(jī)器學(xué)習(xí)項目-Part 2

禁止一切形式轉(zhuǎn)載

書接上文

在這個系列的筆記中骤铃,我們正在研究一種受監(jiān)督的回歸機(jī)器學(xué)習(xí)問題寒跳。 使用真實的紐約市建筑能源數(shù)據(jù),我們希望預(yù)測建筑物的能源之星得分并確定影響得分的因素。

機(jī)器學(xué)習(xí)的工作的一般流程

1.數(shù)據(jù)清理和格式化
2.探索性數(shù)據(jù)分析
3.特征工程和特征選擇
4.在性能指標(biāo)上比較幾種機(jī)器學(xué)習(xí)模型
5.對最佳模型執(zhí)行超參數(shù)調(diào)整
6.在測試集合中評估最佳模型
7.解釋模型結(jié)果
8.得出結(jié)論

在Part 1 我們進(jìn)行了1-3悔耘,在Part 2 我們 將進(jìn)行4-6查邢。重申一遍蔗崎,在本系列筆記中,我們更多地關(guān)注實現(xiàn)而不是細(xì)節(jié)扰藕,即機(jī)器學(xué)習(xí)項目的整個流程是什么缓苛,對于那些尋求更多機(jī)器學(xué)習(xí)方法背景的人,我推薦 Hands-On Machine Learning with Scikit-Learn and Tensorflow by Aurelien Geron邓深。 這是算法背后的基本理論以及如何在Python中有效使用它們的優(yōu)秀資源未桥!

讀取數(shù)據(jù)

在Part 1 最后,我們已經(jīng)將處理好的數(shù)據(jù)保存到四個.csv文件中:
training_features.csv
testing_features.csv
training_labels.csv
testing_labels.csv
使用如下代碼讀取數(shù)據(jù):

train_features = pd.read_csv('data/training_features.csv')
test_features = pd.read_csv('data/testing_features.csv')
train_labels = pd.read_csv('data/training_labels.csv')
test_labels = pd.read_csv('data/testing_labels.csv')
# Display sizes of data
print('Training Feature Size: ', train_features.shape)
print('Testing Feature Size:  ', test_features.shape)
print('Training Labels Size:  ', train_labels.shape)
print('Testing Labels Size:   ', test_labels.shape)

Training Feature Size: (6622, 64)
Testing Feature Size: (2839, 64)
Training Labels Size: (6622, 1)
Testing Labels Size: (2839, 1)

4. 在性能指標(biāo)上比較幾種機(jī)器學(xué)習(xí)模型

在本節(jié)中芥备,我們將為我們的監(jiān)督回歸任務(wù)構(gòu)建冬耿,訓(xùn)練和評估幾種機(jī)器學(xué)習(xí)方法。 目標(biāo)是確定哪個模型最有希望進(jìn)一步開發(fā)(例如超參數(shù)調(diào)整)门躯。
我們使用平均絕對誤差比較模型淆党。 猜測得分中值的基線模型平均偏離25分。

4.1 輸入缺失值

標(biāo)準(zhǔn)機(jī)器學(xué)習(xí)模型無法處理缺失值讶凉,這意味著我們必須找到一種方法來填充這些缺失值或丟棄任何具有缺失值的特征染乌。 由于我們已經(jīng)刪除了第一部分中缺失值超過50%的要素,因此我們將重點關(guān)注這些缺失值懂讯,即稱為插補(bǔ) (imputation)的過程荷憋。 有許多插補(bǔ)方法,但在這里我們將使用相對簡單的方法用列的中位數(shù)替換缺失值褐望。(Here is a more thorough discussion on imputing missing values)

4.2 特征縮放

在我們構(gòu)建模型之前要采取的最后一步是特征縮放(scale the features)勒庄。這是必要的串前,因為要素具有不同的單位,我們希望對要素進(jìn)行標(biāo)準(zhǔn)化实蔽,以使單位不影響算法荡碾。線性回歸和隨機(jī)森林不需要特征縮放(Linear Regression and Random Forest do not require feature scaling),但其他方法(例如支持向量機(jī)和k-最近鄰)確實需要它局装,因為它們考慮了觀測之間的歐氏距離坛吁。因此,在比較多個算法時铐尚,最佳做法是特征縮放拨脉。
有兩種特征縮放的方法( normalization and standardization.):

  • 對于每個值,減去特征的平均值并除以特征的標(biāo)準(zhǔn)偏差宣增。這稱為標(biāo)準(zhǔn)化玫膀,并且導(dǎo)致每個特征具有0的均值和1的標(biāo)準(zhǔn)偏差。
  • 對于每個值爹脾,減去要素的最小值并除以最大值減去要素的最小值(范圍)帖旨。這可以確保要素的所有值都在0到1之間,并稱為縮放到范圍或標(biāo)準(zhǔn)化誉简。
    這是一篇關(guān)于規(guī)范化和標(biāo)準(zhǔn)化的好文章碉就。
    與插補(bǔ)一樣,當(dāng)我們訓(xùn)練縮放對象時闷串,我們只想使用訓(xùn)練集瓮钥。當(dāng)我們轉(zhuǎn)換特征時,我們將轉(zhuǎn)換訓(xùn)練集和測試集烹吵。
4.3 要評估的模型

我們將使用偉大的Scikit-Learn庫比較五種不同的機(jī)器學(xué)習(xí)模型:

  • 線性回歸
  • 支持向量機(jī)回歸
  • 隨機(jī)森林回歸
  • Gradient Boosting 回歸
  • K-Nearest Neighbors回歸

同樣碉熄,在這里,我專注于實現(xiàn)肋拔,而不是解釋這些是如何工作的锈津。 除了Hands-On Machine Learning之外,另一個用于閱讀機(jī)器學(xué)習(xí)模型的優(yōu)秀資源 An Introduction to Statistical Learning
為了比較模型凉蜂,我們將主要使用Scikit-Learn默認(rèn)的模型超參數(shù)值琼梆。 通常這些將表現(xiàn)得很好,但應(yīng)該在實際使用模型之前進(jìn)行優(yōu)化窿吩。 首先茎杂,我們只想確定每個模型的baseline性能,然后我們可以選擇性能最佳的模型纫雁,以便使用超參數(shù)調(diào)整進(jìn)行進(jìn)一步優(yōu)化煌往。 請記住,默認(rèn)的超參數(shù)將啟動并運行模型轧邪,但幾乎總是應(yīng)該使用某種搜索來調(diào)整以找到問題的最佳設(shè)置刽脖!

Here is what the Scikit-learn documentation says about the defaults:

__Sensible defaults__: Whenever an operation requires a user-defined parameter,
an appropriate default value is defined by the library. The default value
should cause the operation to be performed in a sensible way (giving a baseline
solution for the task at hand.)

關(guān)于scikit-learn的最好的一點是所有模型都以相同的方式實現(xiàn):一旦你知道如何構(gòu)建一個模型羞海,你就可以實現(xiàn)一系列極其多樣化的模型。 在這里曲管,我們將在幾行代碼中實現(xiàn)許多模型的整個訓(xùn)練和測試程序却邓。

# Function to calculate mean absolute error
def mae(y_true, y_pred):
    return np.mean(abs(y_true - y_pred))
# Takes in a model, trains the model, and evaluates the model on the test set
def fit_and_evaluate(model):
    # Train the model
    model.fit(X, y)
    # Make predictions and evalute
    model_pred = model.predict(X_test)
    model_mae = mae(y_test, model_pred)
    # Return the performance metric
    return model_mae
4.3.1 線性回歸
lr = LinearRegression()
lr_mae = fit_and_evaluate(lr)

print('Linear Regression Performance on the test set: MAE = %0.4f' % lr_mae)
4.3.2 支持向量機(jī)
svm = SVR(C = 1000, gamma = 0.1)
svm_mae = fit_and_evaluate(svm)

print('Support Vector Machine Regression Performance on the test set: MAE = %0.4f' % svm_mae)
4.3.3 隨機(jī)森林
random_forest = RandomForestRegressor(random_state=60)
random_forest_mae = fit_and_evaluate(random_forest)

print('Random Forest Regression Performance on the test set: MAE = %0.4f' % random_forest_mae)
4.3.4 Gradient Boosting Regression
gradient_boosted = GradientBoostingRegressor(random_state=60)
gradient_boosted_mae = fit_and_evaluate(gradient_boosted)

print('Gradient Boosted Regression Performance on the test set: MAE = %0.4f' % gradient_boosted_mae)
4.3.5 K-Nearest Neighbors Regression
knn = KNeighborsRegressor(n_neighbors=10)
knn_mae = fit_and_evaluate(knn)

print('K-Nearest Neighbors Regression Performance on the test set: MAE = %0.4f' % knn_mae)
4.4 模型比較
plt.style.use('fivethirtyeight')
figsize(8, 6)

# Dataframe to hold the results
model_comparison = pd.DataFrame({'model': ['Linear Regression', 'Support Vector Machine',
                                           'Random Forest', 'Gradient Boosted',
                                            'K-Nearest Neighbors'],
                                 'mae': [lr_mae, svm_mae, random_forest_mae, 
                                         gradient_boosted_mae, knn_mae]})

# Horizontal bar chart of test mae
model_comparison.sort_values('mae', ascending = False).plot(x = 'model', y = 'mae', kind = 'barh',
                                                           color = 'red', edgecolor = 'black')

# Plot formatting
plt.ylabel(''); plt.yticks(size = 14); plt.xlabel('Mean Absolute Error'); plt.xticks(size = 14)
plt.title('Model Comparison on Test MAE', size = 20);

image.png

根據(jù)運行情況(每次精確結(jié)果略有變化),梯度增強(qiáng)回歸量表現(xiàn)最佳翘地,其次是隨機(jī)森林申尤。 我不得不承認(rèn)這不是最公平的比較癌幕,因為我們主要使用默認(rèn)的超參數(shù)衙耕。 特別是對于支持向量回歸器,超參數(shù)對性能有重要影響勺远。 (隨機(jī)森林和梯度增強(qiáng)方法非常適合開始橙喘,因為性能較少依賴于模型設(shè)置)。 盡管如此胶逢,從這些結(jié)果中厅瞎,我們可以得出結(jié)論:機(jī)器學(xué)習(xí)是適用的,因為所有模型都明顯優(yōu)于基線初坠!

從這里開始和簸,我將專注于使用超參數(shù)調(diào)優(yōu)來優(yōu)化最佳模型。 鑒于此處的結(jié)果碟刺,我將專注于使用GradientBoostingRegressor锁保。 這是Gradient Boosted Trees的Scikit-Learn實現(xiàn),在過去的幾年中贏得了許多Kaggle competitions半沽。 Scikit-Learn版本通常比XGBoost版本慢爽柒,但在這里我們將堅持使用Scikit-Learn,因為語法更為熟悉者填。 這是在XGBoost包中使用實現(xiàn)的指南Here's a guide浩村。

5. 對最佳模型執(zhí)行超參數(shù)調(diào)整--Model Optimization

在機(jī)器學(xué)習(xí)中,優(yōu)化模型意味著為特定問題找到最佳的超參數(shù)集

5.1 Hyperparameters

首先占哟,我們需要了解與模型參數(shù)相比心墅,模型超參數(shù)是如何定義的:

  • 模型超參數(shù)被認(rèn)為最好通過機(jī)器學(xué)習(xí)算法來進(jìn)行設(shè)置,在訓(xùn)練之前由數(shù)據(jù)科學(xué)家調(diào)整榨乎。 例如怎燥,隨機(jī)森林中的樹木數(shù)量,或者K-Nearest Neighbors Regression中使用的鄰居數(shù)量谬哀。
  • 模型參數(shù)是模型在訓(xùn)練期間學(xué)習(xí)的內(nèi)容刺覆,例如線性回歸中的權(quán)重。

我們作為數(shù)據(jù)科學(xué)家通過選擇超參數(shù)來控制模型史煎,這些選擇會對模型的最終性能產(chǎn)生顯著影響(盡管通常不會像獲取更多數(shù)據(jù)或工程特征那樣有效)谦屑。

調(diào)整模型超參數(shù)(Tuning the model hyperparameters)可以控制模型中欠擬合與過擬合的平衡驳糯。 我們可以嘗試通過制作更復(fù)雜的模型來校正欠擬合,例如在隨機(jī)森林中使用更多樹或在深度神經(jīng)網(wǎng)絡(luò)中使用更多層氢橙。 當(dāng)我們的模型沒有足夠的容量(自由度)來學(xué)習(xí)特征和目標(biāo)之間的關(guān)系時酝枢,模型會發(fā)生欠擬合并且具有高偏差。 我們可以通過限制模型的復(fù)雜性和應(yīng)用正則化來嘗試糾正過度擬合悍手。 這可能意味著降低多項式回歸的程度帘睦,或?qū)⑺ネ藢犹砑拥缴疃壬窠?jīng)網(wǎng)絡(luò)。 過擬合的模型具有高方差并且實際上記住了訓(xùn)練集坦康。 欠擬合和過擬合導(dǎo)致模型在測試集上的泛化性能變差*竣付。

選擇超參數(shù)的問題在于,沒有放之四海而皆準(zhǔn)的超參數(shù)滞欠。 因此古胆,對于每個新數(shù)據(jù)集,我們必須找到最佳設(shè)置筛璧。 這可能是一個耗時的過程逸绎,但幸運的是,在Scikit-Learn中執(zhí)行此過程有多種選擇夭谤。 更好的是棺牧,新的libraries,如epistasis實驗室的TPOT朗儒,旨在為您自動完成此過程颊乘! 目前,我們將堅持在Scikit-Learn中手動(有點)這樣做采蚀,但請繼續(xù)關(guān)注自動模型選擇的文章疲牵!

5.2 隨機(jī)搜索和交叉驗證的超參數(shù)調(diào)整

我們可以通過隨機(jī)搜索和交叉驗證為模型選擇最佳超參數(shù)。

  • 隨機(jī)搜索是指我們選擇超參數(shù)來評估的方法:我們定義一系列選項榆鼠,然后隨機(jī)選擇要嘗試的組合纲爸。這與網(wǎng)格搜索形成對比,在網(wǎng)格搜索評估妆够,我們指定每個組合识啦。通常,當(dāng)我們對最佳模型超參數(shù)的知識有限時神妹,隨機(jī)搜索會更好颓哮,我們可以使用隨機(jī)搜索縮小選項范圍,然后使用更有限的選項范圍進(jìn)行網(wǎng)格搜索鸵荠。

  • 交叉驗證是用于評估超參數(shù)性能的方法冕茅。我們使用K-Fold交叉驗證,而不是將訓(xùn)練設(shè)置拆分為單獨的訓(xùn)練和驗證集,以減少我們可以使用的訓(xùn)練數(shù)據(jù)量姨伤。這意味著將訓(xùn)練數(shù)據(jù)劃分為K個折疊哨坪,然后進(jìn)行迭代過程,我們首先在折疊的K-1上進(jìn)行訓(xùn)練乍楚,然后評估第K個折疊的性能当编。我們重復(fù)這個過程K次,所以最終我們將測試訓(xùn)練數(shù)據(jù)中的每個例子徒溪,關(guān)鍵是每次迭代我們都在測試我們之前沒有訓(xùn)練過的數(shù)據(jù)忿偷。在K-Fold交叉驗證結(jié)束時,我們將每個K次迭代的平均誤差作為最終性能度量臊泌,然后立即在所有訓(xùn)練數(shù)據(jù)上訓(xùn)練模型鲤桥。然后,我們記錄的性能用于比較超參數(shù)的不同組合缺虐。

A picture of k-fold cross validation using k = 5 is shown below:
image.png

在這里芜壁,我們將使用交叉驗證實現(xiàn)隨機(jī)搜索,以選擇gradient boosting regressor的最佳超參數(shù)高氮。 我們首先定義一個網(wǎng)格然后執(zhí)行迭代過程:從網(wǎng)格中隨機(jī)抽樣一組超參數(shù),使用4倍交叉驗證評估超參數(shù)顷牌,然后選擇具有最佳性能的超參數(shù)剪芍。
Loss function to be optimized
Number of trees used in the boosting process
Maximum depth of each tree
Minimum number of samples per leaf
Minimum number of samples to split a node
Maximum number of features to consider for making splits
我們選擇了6個不同的超參數(shù)來調(diào)整梯度增強(qiáng)回歸量。 這些都將以不同的方式影響模型窟蓝,這些方法很難提前確定罪裹,找到特定問題的最佳組合的唯一方法是測試它們! 要了解超參數(shù)运挫,我建議您查看(Scikit-Learn documentation)文檔状共。 現(xiàn)在,只要知道我們正在努力尋找超參數(shù)的最佳組合谁帕,并且因為沒有理論告訴我們哪種方法效果最好峡继,我們只需要評估它們,就像運行實驗一樣匈挖!
這部分剩下的內(nèi)容可以去看jupyter notebook, 上面給出了詳細(xì)步驟

6. 在測試集合中評估最佳模型

我們將使用超參數(shù)調(diào)整中的最佳模型來對測試集進(jìn)行預(yù)測碾牌。 請記住,我們的模型之前從未見過測試集儡循,所以這個性能應(yīng)該是模型在現(xiàn)實世界中部署時的表現(xiàn)的一個很好的指標(biāo)舶吗。

最終的模型比基線模型的性能提高了大約10%,但代價是顯著增加了運行時間(在我的機(jī)器上慢了大約12倍)择膝。 機(jī)器學(xué)習(xí)通常是一個權(quán)衡領(lǐng)域:偏差與方差誓琼,準(zhǔn)確性與可解釋性,準(zhǔn)確性與運行時間,以及使用哪種模型的最終決定取決于具體情況腹侣。 這里呵扛,運行時間的增加不是障礙,因為雖然相對差異很大筐带,但訓(xùn)練時間的絕對量值并不顯著今穿。 在不同的情況下,平衡可能不一樣伦籍,因此我們需要考慮我們正在優(yōu)化的內(nèi)容以及我們必須使用的限制蓝晒。

總結(jié)

在個筆記中,我們介紹了機(jī)器學(xué)習(xí)流程中的關(guān)鍵概念:

  • 輸入缺失值
  • 評估和比較幾種機(jī)器學(xué)習(xí)方法
  • 超參數(shù)使用隨機(jī)搜索和交叉驗證來調(diào)整機(jī)器學(xué)習(xí)模型
  • 評估測試集上的最佳模型

結(jié)果表明帖鸦,機(jī)器學(xué)習(xí)適用于我們的問題芝薇,最終模型能夠?qū)⒔ㄖ锏哪茉粗堑梅诸A(yù)測到9.1分以內(nèi)。我們還看到作儿,超級參數(shù)調(diào)整能夠改善模型的性能洛二,盡管在投入的時間方面成本相當(dāng)高。這是一個很好的提醒攻锰,正確的特征工程和收集更多數(shù)據(jù)(如果可能A浪弧)比微調(diào)模型有更大的回報。我們還觀察了運行時與精度之間的權(quán)衡娶吞,這是我們在設(shè)計機(jī)器學(xué)習(xí)模型時必須考慮的眾多因素之一垒迂。

我們知道我們的模型是準(zhǔn)確的,但我們知道為什么它能做出預(yù)測妒蛇?機(jī)器學(xué)習(xí)過程的下一步至關(guān)重要:嘗試?yán)斫饽P腿绾芜M(jìn)行預(yù)測机断。實現(xiàn)高精度是很好的,但如果我們能夠找出模型能夠準(zhǔn)確預(yù)測的原因绣夺,那么我們也可以使用這些信息來更好地理解問題吏奸。例如,模型依靠哪些功能來推斷能源之星得分陶耍?可以使用此模型進(jìn)行特征選擇奋蔚,并實現(xiàn)更易于解釋的更簡單模型嗎?

在下一個也是最后一個筆記中物臂,我們將嘗試回答這些問題并從項目中得出最終結(jié)論旺拉!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市棵磷,隨后出現(xiàn)的幾起案子蛾狗,更是在濱河造成了極大的恐慌,老刑警劉巖仪媒,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沉桌,死亡現(xiàn)場離奇詭異谢鹊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)留凭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門佃扼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蔼夜,你說我怎么就攤上這事兼耀。” “怎么了求冷?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵瘤运,是天一觀的道長。 經(jīng)常有香客問我匠题,道長拯坟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任韭山,我火速辦了婚禮郁季,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钱磅。我一直安慰自己梦裂,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布续搀。 她就那樣靜靜地躺著塞琼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪禁舷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天毅往,我揣著相機(jī)與錄音牵咙,去河邊找鬼。 笑死攀唯,一個胖子當(dāng)著我的面吹牛洁桌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播侯嘀,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼另凌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了戒幔?” 一聲冷哼從身側(cè)響起吠谢,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诗茎,沒想到半個月后工坊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年王污,在試婚紗的時候發(fā)現(xiàn)自己被綠了罢吃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡昭齐,死狀恐怖尿招,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阱驾,我是刑警寧澤就谜,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站啊易,受9級特大地震影響吁伺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜租谈,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一篮奄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧割去,春花似錦窟却、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至咖城,卻和暖如春茬腿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宜雀。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工切平, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人辐董。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓悴品,卻偏偏與公主長得像,于是被迫代替她去往敵國和親简烘。 傳聞我的和親對象是個殘疾皇子苔严,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容