接下來我們開始構(gòu)建簡(jiǎn)單的回歸模型妇斤,并使用sklearn中自帶的數(shù)據(jù)集進(jìn)行演示。我們會(huì)介紹三種常用的回歸模型丹拯,分別是線性回歸站超,回歸樹和SVM支持向量機(jī)模型。
對(duì)于任何一個(gè)機(jī)器學(xué)習(xí)模型乖酬,我們都可以從三個(gè)方面來進(jìn)行解剖死相,即:
- 模型(Model)
機(jī)器學(xué)習(xí)問題通常都要都要轉(zhuǎn)化為一個(gè)數(shù)學(xué)模型來求解。模型是從數(shù)據(jù)里抽象出來的咬像。在進(jìn)行數(shù)據(jù)分析時(shí)算撮,我們通常手上只有數(shù)據(jù)生宛,從數(shù)據(jù)中抽取的規(guī)律就是模型。一般情況肮柜,該模型表達(dá)了從特征到標(biāo)簽(數(shù)值)的映射關(guān)系陷舅。給定一個(gè)輸入,經(jīng)過模型后就可以得到一個(gè)輸出审洞。模型可以是確定性的莱睁,也可以是隨機(jī)的,無所謂芒澜,總之用數(shù)學(xué)可以描述缩赛,只要數(shù)學(xué)可以描述的,就可以進(jìn)行預(yù)測(cè)分析撰糠。從這點(diǎn)上來說,機(jī)器學(xué)習(xí)辩昆,就是讓機(jī)器通過數(shù)據(jù)產(chǎn)生模型阅酪。
- 模型(Model)
-
- 策略(Strategy)
知道了模型的概念,那么如何通過數(shù)據(jù)來構(gòu)造模型呢? 如何構(gòu)造就是我們所謂的策略汁针。
不同的策略术辐,對(duì)應(yīng)不同的模型的比較標(biāo)準(zhǔn)和選擇標(biāo)準(zhǔn)。就跟選班干部一樣施无,選帥的辉词,好,那就讓吳彥祖當(dāng)班長(zhǎng)猾骡,選逗比的瑞躺,也許選出來的就是王寶強(qiáng),選會(huì)唱歌的兴想,沒準(zhǔn)是周杰倫…好幢哨,所以最終確定的模型是什么,實(shí)際上就跟兩件事兒有關(guān):
- 我們拿到的數(shù)據(jù)是什么嫂便?
- 我們選擇模型的策略是什么捞镰?
- 策略(Strategy)
說道策略,一般會(huì)講到毙替,經(jīng)驗(yàn)風(fēng)險(xiǎn)最小化作為常用的標(biāo)準(zhǔn)岸售。經(jīng)驗(yàn)風(fēng)險(xiǎn)最小是指,用這個(gè)模型厂画,套到已有的觀測(cè)數(shù)據(jù)上凸丸,基本上是靠譜的。這也是大多數(shù)時(shí)候我們?cè)跈C(jī)器學(xué)習(xí)時(shí)候有意或無意就用到的準(zhǔn)側(cè)袱院。經(jīng)驗(yàn)風(fēng)險(xiǎn)最小化是一個(gè)參數(shù)優(yōu)化的過程甲雅,我們需要構(gòu)造一個(gè)損失函數(shù)來描述經(jīng)驗(yàn)風(fēng)險(xiǎn)解孙,損失函數(shù)可以理解為我們預(yù)測(cè)一個(gè)數(shù)據(jù)錯(cuò)了給我們帶來的代價(jià)。每個(gè)人對(duì)損失函數(shù)的定義都不同抛人,所以優(yōu)化出來的結(jié)果也不同弛姜,這也導(dǎo)致最終我們學(xué)習(xí)到的模型會(huì)各種各樣,解決一個(gè)問題的方案有多種多樣…
- 3 算法(Algorithm)
我們通過策略實(shí)現(xiàn)模型的方法就是算法
我們有了數(shù)據(jù)妖枚,有了學(xué)習(xí)模型的策略廷臼,然后就要開始去構(gòu)造模型了,如果模型的基本形式有了绝页,就是一個(gè)優(yōu)化模型參數(shù)的問題了荠商。如果學(xué)習(xí)過確定性模型的朋友,優(yōu)化并不陌生续誉,但是優(yōu)化過程往往是復(fù)雜的莱没,面對(duì)復(fù)雜的數(shù)學(xué)優(yōu)化問題我們通常難以通過簡(jiǎn)單的求導(dǎo)獲得最終的結(jié)果,所以就要構(gòu)造一系列的算法酷鸦。
我們的目標(biāo)是讓算法盡量高效饰躲,更少的計(jì)算機(jī)內(nèi)存代價(jià)臼隔,更快的運(yùn)算速度嘹裂,更有效的參數(shù)優(yōu)化結(jié)果…
模型、策略和算法這三樣?xùn)|西好比打開機(jī)器學(xué)習(xí)模型的三把金鑰匙摔握,明白了這三把鑰匙的含義寄狼,也就能深入理解這個(gè)模型了。下面分別闡述
1. 線性回歸
模型:對(duì)于線性回歸的模型氨淌,一般可以用如下的矩陣來描述:
假設(shè):數(shù)據(jù)集泊愧,
,
假設(shè)X和Y之間存在線性關(guān)系盛正,模型的具體形式為:
策略:
我們采用真實(shí)值與線性回歸模型的預(yù)測(cè)值
之間的差距拼卵,在這里我們和使用二范數(shù)的平方和L(w)來描述這種差距,即:
我們需要找到使得L(w)最小時(shí)對(duì)應(yīng)的參數(shù)w蛮艰,即:
所以腋腮,我們策略就是尋找最小的w組合,使得最小壤蚜。
如何尋找呢即寡?這就是算法了。
一般我們采用梯度下降算法來解決袜刷,及對(duì)求導(dǎo)聪富。
線性模型形式簡(jiǎn)單、易于建模著蟹。但是卻蘊(yùn)含著機(jī)器學(xué)習(xí)中一些重要的基本思想墩蔓。許多功能更為強(qiáng)大的非線性模型可以在線性模型的基礎(chǔ)上通過引入層級(jí)結(jié)構(gòu)或高維映射而得梢莽。此外,由于w直觀表達(dá)了各屬性在預(yù)測(cè)中的重要性奸披,因此線性模型有很好的可解釋性昏名。并且經(jīng)常作為各個(gè)系統(tǒng)的基線模型。
2. 回歸樹
決策樹(Decision Tree)是一種基本的分類與回歸方法阵面,當(dāng)決策樹用于分類時(shí)稱為分類樹轻局,用于回歸時(shí)稱為回歸樹。
基于樹的回歸方法主要是依據(jù)分層和分割的方式將特征空間劃分為一系列簡(jiǎn)單的區(qū)域样刷。對(duì)某個(gè)給定的待預(yù)測(cè)的自變量仑扑,用他所屬區(qū)域中訓(xùn)練集的平均數(shù)或者眾數(shù)對(duì)其進(jìn)行預(yù)測(cè)。由于劃分特征空間的分裂規(guī)則可以用樹的形式進(jìn)行概括置鼻,因此這類方法稱為決策樹方法镇饮。決策樹由結(jié)點(diǎn)(node)和有向邊(diredcted edge)組成。結(jié)點(diǎn)有兩種類型:內(nèi)部結(jié)點(diǎn)(internal node)和葉結(jié)點(diǎn)(leaf node)箕母。內(nèi)部結(jié)點(diǎn)表示一個(gè)特征或?qū)傩源⒚辏~結(jié)點(diǎn)表示一個(gè)類別或者某個(gè)值。區(qū)域 ??1,??2R1,R2 等稱為葉節(jié)點(diǎn)司蔬,將特征空間分開的點(diǎn)為內(nèi)部節(jié)點(diǎn)。
建立回歸樹的過程大致可以分為以下兩步:
- 1. 將自變量的特征空間(即)的可能取值構(gòu)成的集合分割成J個(gè)互不重疊的區(qū)域
姨蝴。
- 2. 對(duì)落入?yún)^(qū)域的每個(gè)觀測(cè)值作相同的預(yù)測(cè)俊啼,預(yù)測(cè)值等于
上訓(xùn)練集的因變量的簡(jiǎn)單算術(shù)平均。
具體來說左医,就是:
a. 選擇最優(yōu)切分特征j以及該特征上的最優(yōu)點(diǎn)s:
遍歷特征j以及固定j后遍歷切分點(diǎn)s授帕,選擇使得下式最小的(j,s)
b. 按照(j,s)分裂特征空間:
c. 繼續(xù)調(diào)用步驟1,2直到滿足停止條件浮梢,就是每個(gè)區(qū)域的樣本數(shù)小于等于5跛十。
d. 將特征空間劃分為J個(gè)不同的區(qū)域,生成回歸樹:
樹模型的優(yōu)缺點(diǎn):
- 樹模型的解釋性強(qiáng)秕硝,在解釋性方面可能比線性回歸還要方便芥映。
- 樹模型更接近人的決策方式。
- 樹模型可以用圖來表示远豺,非專業(yè)人士也可以輕松解讀奈偏。
- 樹模型可以直接做定性的特征而不需要像線性回歸一樣啞元化。
- 樹模型能很好處理缺失值和異常值躯护,對(duì)異常值不敏感惊来,但是這個(gè)對(duì)線性模型來說卻是致命的。
- 樹模型的預(yù)測(cè)準(zhǔn)確性一般無法達(dá)到其他回歸模型的水平棺滞,但是改進(jìn)的方法很多裁蚁。
3. 支持向量機(jī)回歸(SVR)
支持向量機(jī)模型可以之前的文章: http://www.reibang.com/p/b6b8ae283471
下面通過sklearn中的數(shù)據(jù)集進(jìn)行演示矢渊,我們還是用之前房?jī)r(jià)預(yù)測(cè)數(shù)據(jù)集
from sklearn import datasets
boston = datasets.load_boston()
X = boston.data
y = boston.target
features = boston.feature_names
boston_data = pd.DataFrame(X,columns=features)
boston_data["Price"] = y
boston_data.head()
下面分別導(dǎo)入線性回歸、決策樹枉证、和SVR模型進(jìn)行訓(xùn)練和預(yù)測(cè):
from sklearn.tree import DecisionTreeRegressor # 導(dǎo)入回歸樹模型
from sklearn.svm import SVR # 支持向量機(jī)模型
lin_reg = linear_model.LinearRegression() # 創(chuàng)建線性回歸的類
lin_reg.fit(X,y) # 輸入特征X和因變量y進(jìn)行訓(xùn)練
print('使用線性回歸模型:')
print("模型系數(shù):",lin_reg.coef_) # 輸出模型的系數(shù)
print("模型得分:",lin_reg.score(X,y)) # 輸出模型的決定系數(shù)R^2
print('-' * 20)
reg_tree = DecisionTreeRegressor(criterion = "mse",min_samples_leaf = 5)
reg_tree.fit(X,y)
print('使用決策樹回歸模型:')
print('模型的得分為:', reg_tree.score(X,y))
print('-' * 20)
from sklearn.preprocessing import StandardScaler # 標(biāo)準(zhǔn)化數(shù)據(jù)
from sklearn.pipeline import make_pipeline # 使用管道矮男,把預(yù)處理和模型形成一個(gè)流程
print('使用SVR回歸模型:')
reg_svr = make_pipeline(StandardScaler(), SVR(C=1.0, epsilon=0.2))
reg_svr.fit(X, y)
print("使用SVR模型的分?jǐn)?shù) :" , reg_svr.score(X,y))
>>>
使用線性回歸模型:
模型系數(shù): [-1.08011358e-01 4.64204584e-02 2.05586264e-02 2.68673382e+00
-1.77666112e+01 3.80986521e+00 6.92224640e-04 -1.47556685e+00
3.06049479e-01 -1.23345939e-02 -9.52747232e-01 9.31168327e-03
-5.24758378e-01]
模型得分: 0.7406426641094095
--------------------
使用決策樹回歸模型:
模型的得分為: 0.9376307599929274
--------------------
使用SVR回歸模型:
使用SVR模型的分?jǐn)?shù) : 0.7024525421955277
- 模型優(yōu)化
當(dāng)完成一個(gè)完整的模型構(gòu)建訓(xùn)練并預(yù)測(cè)出結(jié)果后,相當(dāng)與我們完成了一個(gè)機(jī)器學(xué)習(xí)的baseline刽严,剩下的部分就是如何優(yōu)化提高模型分?jǐn)?shù)了昂灵。這一部分一般可以從兩個(gè)方面著手:
- 輸入數(shù)據(jù)的處理,包含歸一化以及更好的特征工程
- 模型超參數(shù)的優(yōu)化
下面簡(jiǎn)要說說明一下超參數(shù)優(yōu)化
首先要明白參數(shù)和超參數(shù)的意義 - 參數(shù)與超參數(shù):
我們很自然的問題就是嶺回歸中的參數(shù)和參數(shù)w之間有什么不一樣舞萄?事實(shí)上眨补,參數(shù)w是我們通過設(shè)定某一個(gè)具體的
后使用類似于最小二乘法、梯度下降法等方式優(yōu)化出來的倒脓,我們總是設(shè)定了
是多少后才優(yōu)化出來的參數(shù)w撑螺。因此,類似于參數(shù)w一樣崎弃,使用最小二乘法或者梯度下降法等最優(yōu)化算法優(yōu)化出來的數(shù)我們稱為參數(shù)甘晤,類似于
一樣,我們無法使用最小二乘法或者梯度下降法等最優(yōu)化算法優(yōu)化出來的數(shù)我們稱為超參數(shù)饲做。
模型參數(shù)是模型內(nèi)部的配置變量线婚,其值可以根據(jù)數(shù)據(jù)進(jìn)行估計(jì)。- 進(jìn)行預(yù)測(cè)時(shí)需要參數(shù)盆均。
- 它參數(shù)定義了可使用的模型塞弊。
- 參數(shù)是從數(shù)據(jù)估計(jì)或獲悉的。
- 參數(shù)通常不由編程者手動(dòng)設(shè)置泪姨。
- 參數(shù)通常被保存為學(xué)習(xí)模型的一部分游沿。
- 參數(shù)是機(jī)器學(xué)習(xí)算法的關(guān)鍵,它們通常由過去的訓(xùn)練數(shù)據(jù)中總結(jié)得出 肮砾。
模型超參數(shù)是模型外部的配置诀黍,其值無法從數(shù)據(jù)中估計(jì)。 - 超參數(shù)通常用于幫助估計(jì)模型參數(shù)仗处。
- 超參數(shù)通常由人工指定眯勾。
- 超參數(shù)通常可以使用啟發(fā)式設(shè)置婆誓。
- 超參數(shù)經(jīng)常被調(diào)整為給定的預(yù)測(cè)建模問題咒精。
我們前面(4)部分的優(yōu)化都是基于模型本身的具體形式的優(yōu)化,那本次(5)調(diào)整的內(nèi)容是超參數(shù)旷档,也就是取不同的超參數(shù)的值對(duì)于模型的性能有不同的影響模叙。
- 網(wǎng)格搜索GridSearchCV():
網(wǎng)格搜索:https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html?highlight=gridsearchcv#sklearn.model_selection.GridSearchCV
網(wǎng)格搜索結(jié)合管道:https://scikit-learn.org/stable/auto_examples/compose/plot_compare_reduction.html?highlight=gridsearchcv
網(wǎng)格搜索的思想非常簡(jiǎn)單,比如你有2個(gè)超參數(shù)需要去選擇鞋屈,那你就把所有的超參數(shù)選擇列出來分別做排列組合范咨。舉個(gè)例子:和
,你可以做一個(gè)排列組合故觅,即:{[0.01,0.01],[0.01,0.1],[0.01,1],[0.1,0.01],[0.1,0.1],[0.1,1.0],[1,0.01],[1,0.1],[1,1]} ,然后針對(duì)每組超參數(shù)分別建立一個(gè)模型渠啊,然后選擇測(cè)試誤差最小的那組超參數(shù)输吏。換句話說,我們需要從超參數(shù)空間中尋找最優(yōu)的超參數(shù)替蛉,很像一個(gè)網(wǎng)格中找到一個(gè)最優(yōu)的節(jié)點(diǎn)贯溅,因此叫網(wǎng)格搜索。
- 隨機(jī)搜索 RandomizedSearchCV() :
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.html?highlight=randomizedsearchcv#sklearn.model_selection.RandomizedSearchCV
網(wǎng)格搜索相當(dāng)于暴力地從參數(shù)空間中每個(gè)都嘗試一遍躲查,然后選擇最優(yōu)的那組參數(shù)它浅,這樣的方法顯然是不夠高效的,因?yàn)殡S著參數(shù)類別個(gè)數(shù)的增加镣煮,需要嘗試的次數(shù)呈指數(shù)級(jí)增長(zhǎng)姐霍。有沒有一種更加高效的調(diào)優(yōu)方式呢?那就是使用隨機(jī)搜索的方式典唇,這種方式不僅僅高校镊折,而且實(shí)驗(yàn)證明,隨機(jī)搜索法結(jié)果比稀疏化網(wǎng)格法稍好(有時(shí)候也會(huì)極差介衔,需要權(quán)衡)恨胚。參數(shù)的隨機(jī)搜索中的每個(gè)參數(shù)都是從可能的參數(shù)值的分布中采樣的。與網(wǎng)格搜索相比炎咖,這有兩個(gè)主要優(yōu)點(diǎn):- 可以獨(dú)立于參數(shù)數(shù)量和可能的值來選擇計(jì)算成本赃泡。
- 添加不影響性能的參數(shù)不會(huì)降低效率。
# 我們先來對(duì)未調(diào)參的SVR進(jìn)行評(píng)價(jià):
from sklearn.svm import SVR # 引入SVR類
from sklearn.pipeline import make_pipeline # 引入管道簡(jiǎn)化學(xué)習(xí)流程
from sklearn.preprocessing import StandardScaler # 由于SVR基于距離計(jì)算塘装,引入對(duì)數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化的類
from sklearn.model_selection import GridSearchCV # 引入網(wǎng)格搜索調(diào)優(yōu)
from sklearn.model_selection import cross_val_score # 引入K折交叉驗(yàn)證
from sklearn import datasets
boston = datasets.load_boston() # 返回一個(gè)類似于字典的類
X = boston.data
y = boston.target
features = boston.feature_names
pipe_SVR = make_pipeline(StandardScaler(),
SVR())
score1 = cross_val_score(estimator=pipe_SVR,
X = X,
y = y,
scoring = 'r2',
cv = 10) # 10折交叉驗(yàn)證
print("CV accuracy: %.3f +/- %.3f" % ((np.mean(score1)),np.std(score1)))
>>>
CV accuracy: 0.187 +/- 0.649
下面我們使用網(wǎng)格搜索來對(duì)SVR調(diào)參:
# 下面我們使用網(wǎng)格搜索來對(duì)SVR調(diào)參:
from sklearn.pipeline import Pipeline
pipe_svr = Pipeline([("StandardScaler",StandardScaler()),
("svr",SVR())])
param_range = [0.0001,0.001,0.01,0.1,1.0,10.0,100.0,1000.0]
param_grid = [{"svr__C":param_range,"svr__kernel":["linear"]}, # 注意__是指兩個(gè)下劃線急迂,一個(gè)下劃線會(huì)報(bào)錯(cuò)的
{"svr__C":param_range,"svr__gamma":param_range,"svr__kernel":["rbf"]}]
gs = GridSearchCV(estimator=pipe_svr,
param_grid = param_grid,
scoring = 'r2',
cv = 10) # 10折交叉驗(yàn)證
gs = gs.fit(X,y)
print("網(wǎng)格搜索最優(yōu)得分:",gs.best_score_)
print("網(wǎng)格搜索最優(yōu)參數(shù)組合:\n",gs.best_params_)
>>>
網(wǎng)格搜索最優(yōu)得分: 0.6081303070817233
網(wǎng)格搜索最優(yōu)參數(shù)組合:
{'svr__C': 1000.0, 'svr__gamma': 0.001, 'svr__kernel': 'rbf'}