正則化(Regularization)
成都創(chuàng)新互聯(lián)公司專注于景洪企業(yè)網(wǎng)站建設(shè),響應式網(wǎng)站建設(shè),電子商務商城網(wǎng)站建設(shè)。景洪網(wǎng)站建設(shè)公司,為景洪等地區(qū)提供建站服務。全流程定制網(wǎng)站建設(shè),專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務
機器學習中幾乎都可以看到損失函數(shù)后面會添加一個額外項,常用的額外項一般有兩種,一般英文稱作 ?1-norm 和 ?2-norm ,中文稱作 L1正則化 和 L2正則化 ,或者 L1范數(shù) 和 L2范數(shù) 。
L1正則化和L2正則化可以看做是損失函數(shù)的懲罰項。所謂『懲罰』是指對損失函數(shù)中的某些參數(shù)做一些限制。對于線性回歸模型,使用L1正則化的模型建叫做Lasso回歸,使用L2正則化的模型叫做Ridge回歸(嶺回歸)。下圖是Python中Lasso回歸的損失函數(shù),式中加號后面一項α||w||1即為L1正則化項。
下圖是Python中Ridge回歸的損失函數(shù),式中加號后面一項α||w||22即為L2正則化項。
一般回歸分析中回歸w表示特征的系數(shù),從上式可以看到正則化項是對系數(shù)做了處理(限制)。 L1正則化和L2正則化的說明如下:
L1正則化是指權(quán)值向量w中各個元素的 絕對值之和 ,通常表示為||w||1
L2正則化是指權(quán)值向量w中各個元素的 平方和然后再求平方根 (可以看到Ridge回歸的L2正則化項有平方符號),通常表示為||w||2
一般都會在正則化項之前添加一個系數(shù),Python中用α表示,一些文章也用λ表示。這個系數(shù)需要用戶指定。
那添加L1和L2正則化有什么用? 下面是L1正則化和L2正則化的作用 ,這些表述可以在很多文章中找到。
L1正則化可以產(chǎn)生稀疏權(quán)值矩陣,即產(chǎn)生一個稀疏模型,可以用于特征選擇
L2正則化可以防止模型過擬合(overfitting);一定程度上,L1也可以防止過擬合
稀疏模型與特征選擇
上面提到L1正則化有助于生成一個稀疏權(quán)值矩陣,進而可以用于特征選擇。為什么要生成一個稀疏矩陣?
稀疏矩陣指的是很多元素為0,只有少數(shù)元素是非零值的矩陣,即得到的線性回歸模型的大部分系數(shù)都是0.
通常機器學習中特征數(shù)量很多,例如文本處理時,如果將一個詞組(term)作為一個特征,那么特征數(shù)量會達到上萬個(bigram)。在預測或分類時,那么多特征顯然難以選擇,但是如果代入這些特征得到的模型是一個稀疏模型,表示只有少數(shù)特征對這個模型有貢獻,絕大部分特征是沒有貢獻的,或者貢獻微小(因為它們前面的系數(shù)是0或者是很小的值,即使去掉對模型也沒有什么影響),此時我們就可以只關(guān)注系數(shù)是非零值的特征。這就是稀疏模型與特征選擇的關(guān)系。
L1和L2正則化的直觀理解
這部分內(nèi)容將解釋 為什么L1正則化可以產(chǎn)生稀疏模型(L1是怎么讓系數(shù)等于零的) ,以及 為什么L2正則化可以防止過擬合 。
L1正則化和特征選擇
假設(shè)有如下帶L1正則化的損失函數(shù):
J=J0+α∑w|w|(1)
其中J0是原始的損失函數(shù),加號后面的一項是L1正則化項,α是正則化系數(shù)。注意到L1正則化是權(quán)值的 絕對值之和 ,J是帶有絕對值符號的函數(shù),因此J是不完全可微的。機器學習的任務就是要通過一些方法(比如梯度下降)求出損失函數(shù)的最小值。當我們在原始損失函數(shù)J0后添加L1正則化項時,相當于對J0做了一個約束。令L=α∑w|w|,則J=J0+L,此時我們的任務變成 在L約束下求出J0取最小值的解 ??紤]二維的情況,即只有兩個權(quán)值w1和w2,此時L=|w1|+|w2|對于梯度下降法,求解J0的過程可以畫出等值線,同時L1正則化的函數(shù)L也可以在w1w2的二維平面上畫出來。如下圖:
圖1? L1正則化
圖中等值線是J0的等值線,黑色方形是L函數(shù)的圖形。在圖中,當J0等值線與L圖形首次相交的地方就是最優(yōu)解。上圖中J0與L在L的一個頂點處相交,這個頂點就是最優(yōu)解。注意到這個頂點的值是(w1,w2)=(0,w)??梢灾庇^想象,因為L函數(shù)有很多『突出的角』(二維情況下四個,多維情況下更多),J0與這些角接觸的機率會遠大于與L其它部位接觸的機率,而在這些角上,會有很多權(quán)值等于0,這就是為什么L1正則化可以產(chǎn)生稀疏模型,進而可以用于特征選擇。
而正則化前面的系數(shù)α,可以控制L圖形的大小。α越小,L的圖形越大(上圖中的黑色方框);α越大,L的圖形就越小,可以小到黑色方框只超出原點范圍一點點,這是最優(yōu)點的值(w1,w2)=(0,w)中的w可以取到很小的值。
類似,假設(shè)有如下帶L2正則化的損失函數(shù):
J=J0+α∑ww2(2)
同樣可以畫出他們在二維平面上的圖形,如下:
圖2? L2正則化
二維平面下L2正則化的函數(shù)圖形是個圓,與方形相比,被磨去了棱角。因此J0與L相交時使得w1或w2等于零的機率小了許多,這就是為什么L2正則化不具有稀疏性的原因。
L2正則化和過擬合
擬合過程中通常都傾向于讓權(quán)值盡可能小,最后構(gòu)造一個所有參數(shù)都比較小的模型。因為一般認為參數(shù)值小的模型比較簡單,能適應不同的數(shù)據(jù)集,也在一定程度上避免了過擬合現(xiàn)象??梢栽O(shè)想一下對于一個線性回歸方程,若參數(shù)很大,那么只要數(shù)據(jù)偏移一點點,就會對結(jié)果造成很大的影響;但如果參數(shù)足夠小,數(shù)據(jù)偏移得多一點也不會對結(jié)果造成什么影響,專業(yè)一點的說法是『抗擾動能力強』。
那為什么L2正則化可以獲得值很小的參數(shù)?
以線性回歸中的梯度下降法為例。假設(shè)要求的參數(shù)為θ,hθ(x)是我們的假設(shè)函數(shù),那么線性回歸的代價函數(shù)如下:
J(θ)=12m∑i=1m(hθ(x(i))?y(i))(3)
那么在梯度下降法中,最終用于迭代計算參數(shù)θ的迭代式為:
θj:=θj?α1m∑i=1m(hθ(x(i))?y(i))x(i)j(4)
其中α是learning rate. 上式是沒有添加L2正則化項的迭代公式,如果在原始代價函數(shù)之后添加L2正則化,則迭代公式會變成下面的樣子:
θj:=θj(1?αλm)?α1m∑i=1m(hθ(x(i))?y(i))x(i)j(5)
其中 λ就是正則化參數(shù) 。從上式可以看到,與未添加L2正則化的迭代公式相比,每一次迭代,θj都要先乘以一個小于1的因子,從而使得θj不斷減小,因此總得來看,θ是不斷減小的。
最開始也提到L1正則化一定程度上也可以防止過擬合。之前做了解釋,當L1的正則化系數(shù)很小時,得到的最優(yōu)解會很小,可以達到和L2正則化類似的效果。
正則化參數(shù)的選擇
L1正則化參數(shù)
通常越大的λ可以讓代價函數(shù)在參數(shù)為0時取到最小值。下面是一個簡單的例子,這個例子來自 Quora上的問答 。為了方便敘述,一些符號跟這篇帖子的符號保持一致。
假設(shè)有如下帶L1正則化項的代價函數(shù):
F(x)=f(x)+λ||x||1
其中x是要估計的參數(shù),相當于上文中提到的w以及θ. 注意到L1正則化在某些位置是不可導的,當λ足夠大時可以使得F(x)在x=0時取到最小值。如下圖:
圖3 L1正則化參數(shù)的選擇
分別取λ=0.5和λ=2,可以看到越大的λ越容易使F(x)在x=0時取到最小值。
L2正則化參數(shù)
從公式5可以看到,λ越大,θj衰減得越快。另一個理解可以參考圖2,λ越大,L2圓的半徑越小,最后求得代價函數(shù)最值時各參數(shù)也會變得很小。
Reference
過擬合的解釋:
正則化的解釋:
正則化的解釋:
正則化的數(shù)學解釋(一些圖來源于這里):
原文參考:blog.csdn.net/jinping_shi/article/details/52433975
平滑函數(shù)。
交叉熵損失函數(shù),也稱為對數(shù)損失或者logistic損失。當模型產(chǎn)生了預測值之后,將對類別的預測概率與真實值(由0或1組成)進行不比較,計算所產(chǎn)生的損失,然后基于此損失設(shè)置對數(shù)形式的懲罰項。
在神經(jīng)網(wǎng)絡(luò)中,所使用的Softmax函數(shù)是連續(xù)可導函數(shù),這使得可以計算出損失函數(shù)相對于神經(jīng)網(wǎng)絡(luò)中每個權(quán)重的導數(shù)(在《機器學習數(shù)學基礎(chǔ)》中有對此的完整推導過程和案例,這樣就可以相應地調(diào)整模型的權(quán)重以最小化損失函數(shù)。
擴展資料:
注意事項:
當預測類別為二分類時,交叉熵損失函數(shù)的計算公式如下圖,其中y是真實類別(值為0或1),p是預測類別的概率(值為0~1之間的小數(shù))。
計算二分類的交叉熵損失函數(shù)的python代碼如下圖,其中esp是一個極小值,第五行代碼clip的目的是保證預測概率的值在0~1之間,輸出的損失值數(shù)組求和后,就是損失函數(shù)最后的返回值。
參考資料來源:百度百科-交叉熵
參考資料來源:百度百科-損失函數(shù)
可以
最近項目中涉及基于Gradient Boosting Regression 算法擬合時間序列曲線的內(nèi)容,利用python機器學習包?scikit-learn 中的GradientBoostingRegressor完成
因此就學習了下Gradient Boosting算法,在這里分享下我的理解
Boosting 算法簡介
Boosting算法,我理解的就是兩個思想:
1)“三個臭皮匠頂個諸葛亮”,一堆弱分類器的組合就可以成為一個強分類器;
2)“知錯能改,善莫大焉”,不斷地在錯誤中學習,迭代來降低犯錯概率
當然,要理解好Boosting的思想,首先還是從弱學習算法和強學習算法來引入:
1)強學習算法:存在一個多項式時間的學習算法以識別一組概念,且識別的正確率很高;
2)弱學習算法:識別一組概念的正確率僅比隨機猜測略好;
Kearns Valiant證明了弱學習算法與強學習算法的等價問題,如果兩者等價,只需找到一個比隨機猜測略好的學習算法,就可以將其提升為強學習算法。
那么是怎么實現(xiàn)“知錯就改”的呢?
Boosting算法,通過一系列的迭代來優(yōu)化分類結(jié)果,每迭代一次引入一個弱分類器,來克服現(xiàn)在已經(jīng)存在的弱分類器組合的shortcomings
在Adaboost算法中,這個shortcomings的表征就是權(quán)值高的樣本點
而在Gradient Boosting算法中,這個shortcomings的表征就是梯度
無論是Adaboost還是Gradient Boosting,都是通過這個shortcomings來告訴學習器怎么去提升模型,也就是“Boosting”這個名字的由來吧
Adaboost算法
Adaboost是由Freund 和 Schapire在1997年提出的,在整個訓練集上維護一個分布權(quán)值向量W,用賦予權(quán)重的訓練集通過弱分類算法產(chǎn)生分類假設(shè)(基學習器)y(x),然后計算錯誤率,用得到的錯誤率去更新分布權(quán)值向量w,對錯誤分類的樣本分配更大的權(quán)值,正確分類的樣本賦予更小的權(quán)值。每次更新后用相同的弱分類算法產(chǎn)生新的分類假設(shè),這些分類假設(shè)的序列構(gòu)成多分類器。對這些多分類器用加權(quán)的方法進行聯(lián)合,最后得到?jīng)Q策結(jié)果。
其結(jié)構(gòu)如下圖所示:
前一個學習器改變權(quán)重w,然后再經(jīng)過下一個學習器,最終所有的學習器共同組成最后的學習器。
如果一個樣本在前一個學習器中被誤分,那么它所對應的權(quán)重會被加重,相應地,被正確分類的樣本的權(quán)重會降低。
這里主要涉及到兩個權(quán)重的計算問題:
1)樣本的權(quán)值
1 沒有先驗知識的情況下,初始的分布應為等概分布,樣本數(shù)目為n,權(quán)值為1/n
2 每一次的迭代更新權(quán)值,提高分錯樣本的權(quán)重
2)弱學習器的權(quán)值
1 最后的強學習器是通過多個基學習器通過權(quán)值組合得到的。
2 通過權(quán)值體現(xiàn)不同基學習器的影響,正確率高的基學習器權(quán)重高。實際上是分類誤差的一個函數(shù)
Gradient Boosting
和Adaboost不同,Gradient Boosting 在迭代的時候選擇梯度下降的方向來保證最后的結(jié)果最好。
損失函數(shù)用來描述模型的“靠譜”程度,假設(shè)模型沒有過擬合,損失函數(shù)越大,模型的錯誤率越高
如果我們的模型能夠讓損失函數(shù)持續(xù)的下降,則說明我們的模型在不停的改進,而最好的方式就是讓損失函數(shù)在其梯度方向上下降。
下面這個流程圖是Gradient Boosting的經(jīng)典圖了,數(shù)學推導并不復雜,只要理解了Boosting的思想,不難看懂
這里是直接對模型的函數(shù)進行更新,利用了參數(shù)可加性推廣到函數(shù)空間。
訓練F0-Fm一共m個基學習器,沿著梯度下降的方向不斷更新ρm和am
GradientBoostingRegressor實現(xiàn)
python中的scikit-learn包提供了很方便的GradientBoostingRegressor和GBDT的函數(shù)接口,可以很方便的調(diào)用函數(shù)就可以完成模型的訓練和預測
GradientBoostingRegressor函數(shù)的參數(shù)如下:
class sklearn.ensemble.GradientBoostingRegressor(loss='ls', learning_rate=0.1, n_estimators=100, subsample=1.0, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3, init=None, random_state=None, max_features=None, alpha=0.9, verbose=0, max_leaf_nodes=None, warm_start=False, presort='auto')[source]?
loss: 選擇損失函數(shù),默認值為ls(least squres)
learning_rate: 學習率,模型是0.1
n_estimators: 弱學習器的數(shù)目,默認值100
max_depth: 每一個學習器的最大深度,限制回歸樹的節(jié)點數(shù)目,默認為3
min_samples_split: 可以劃分為內(nèi)部節(jié)點的最小樣本數(shù),默認為2
min_samples_leaf: 葉節(jié)點所需的最小樣本數(shù),默認為1
……
可以參考
官方文檔里帶了一個很好的例子,以500個弱學習器,最小平方誤差的梯度提升模型,做波士頓房價預測,代碼和結(jié)果如下:
1 import numpy as np 2 import matplotlib.pyplot as plt 3 ?4 from sklearn import ensemble 5 from sklearn import datasets 6 from sklearn.utils import shuffle 7 from sklearn.metrics import mean_squared_error 8 ?9 ###############################################################################10 # Load data11 boston = datasets.load_boston()12 X, y = shuffle(boston.data, boston.target, random_state=13)13 X = X.astype(np.float32)14 offset = int(X.shape[0] * 0.9)15 X_train, y_train = X[:offset], y[:offset]16 X_test, y_test = X[offset:], y[offset:]17 18 ###############################################################################19 # Fit regression model20 params = {'n_estimators': 500, 'max_depth': 4, 'min_samples_split': 1,21 ? ? ? ? ? 'learning_rate': 0.01, 'loss': 'ls'}22 clf = ensemble.GradientBoostingRegressor(**params)23 24 clf.fit(X_train, y_train)25 mse = mean_squared_error(y_test, clf.predict(X_test))26 print("MSE: %.4f" % mse)27 28 ###############################################################################29 # Plot training deviance30 31 # compute test set deviance32 test_score = np.zeros((params['n_estimators'],), dtype=np.float64)33 34 for i, y_pred in enumerate(clf.staged_predict(X_test)):35 ? ? test_score[i] = clf.loss_(y_test, y_pred)36 37 plt.figure(figsize=(12, 6))38 plt.subplot(1, 2, 1)39 plt.title('Deviance')40 plt.plot(np.arange(params['n_estimators']) + 1, clf.train_score_, 'b-',41 ? ? ? ? ?label='Training Set Deviance')42 plt.plot(np.arange(params['n_estimators']) + 1, test_score, 'r-',43 ? ? ? ? ?label='Test Set Deviance')44 plt.legend(loc='upper right')45 plt.xlabel('Boosting Iterations')46 plt.ylabel('Deviance')47 48 ###############################################################################49 # Plot feature importance50 feature_importance = clf.feature_importances_51 # make importances relative to max importance52 feature_importance = 100.0 * (feature_importance / feature_importance.max())53 sorted_idx = np.argsort(feature_importance)54 pos = np.arange(sorted_idx.shape[0]) + .555 plt.subplot(1, 2, 2)56 plt.barh(pos, feature_importance[sorted_idx], align='center')57 plt.yticks(pos, boston.feature_names[sorted_idx])58 plt.xlabel('Relative Importance')59 plt.title('Variable Importance')60 plt.show()
可以發(fā)現(xiàn),如果要用Gradient Boosting 算法的話,在sklearn包里調(diào)用還是非常方便的,幾行代碼即可完成,大部分的工作應該是在特征提取上。
感覺目前做數(shù)據(jù)挖掘的工作,特征設(shè)計是最重要的,據(jù)說現(xiàn)在kaggle競賽基本是GBDT的天下,優(yōu)劣其實還是特征上,感覺做項目也是,不斷的在研究數(shù)據(jù)中培養(yǎng)對數(shù)據(jù)的敏感度。