轉自:http://blog.csdn.net/slade_sha/article/details/53164905
先看一波過擬合:
圖中,紅色的線存在明顯的過擬合,綠色的線才是合理的擬合曲線,為了避免過擬合,我們可以引入正則化。
下面可以利用正則化來解決曲線擬合過程中的過擬合發生,存在均方根誤差也叫標準誤差,即為√[∑di^2/n]=Re,n為測量次數;di為一組測量值與真值的偏差。
實際考慮迴歸的過程中,我們需要考慮到誤差項,
這個和簡單的線性迴歸的公式相似,而在正則化下來最佳化過擬合這件事情的時候,會加入一個約束條件,也就是懲罰函數:
這邊這個懲罰函數有多種形式,比較常用的有l1,l2,大概有如下幾種:
講一下比較常用的兩種情況,q=1和q=2的情況:
q=1,也就是今天想講的lasso迴歸,為什麼lasso可以控制過擬合呢,因為在資料訓練的過程中,可能有幾百個,或者幾千個變數,再過多的變數衡量目標函數的因變數的時候,可能造成結果的過度解釋,而通過q=1下的懲罰函數來限制變數個數的情況,可以優先篩選掉一些不是特別重要的變數,見下圖:
作圖只要不是特殊情況下與正方形的邊相切,一定是與某個頂點優先相交,那必然存在橫垂直軸中的一個係數為0,起到對變數的篩選的作用。
q=2的時候,其實就可以看作是上面這個藍色的圓,在這個圓的限制下,點可以是圓上的任意一點,所以q=2的時候也叫做嶺迴歸,嶺迴歸是起不到壓縮變數的作用的,在這個圖裡也是可以看出來的。
lasso迴歸:
lasso迴歸的特色就是在建立廣義線型模型的時候,這裡廣義線型模型包含一維連續因變數、多維連續因變數、非負次數因變數、二元離散因變數、多元離散因變,除此之外,無論因變數是連續的還是離散的,lasso都能處理,總的來說,lasso對於資料的要求是極其低的,所以應用程度較廣;除此之外,lasso還能夠對變數進行篩選和對模型的複雜程度進行降低。這裡的變數篩選是指不把所有的變數都放入模型中進行擬合,而是有選擇的把變數放入模型從而得到更好的績效參數。 複雜度調整是指通過一系列參數控制模型的複雜度,從而避免過度學習(Overfitting)。 對於線性模型來說,複雜度與模型的變數數有直接關係,變數數越多,模型複雜度就越高。 更多的變數在擬合時往往可以給出一個看似更好的模型,但是同時也面臨過度學習的危險。
lasso的複雜程度由λ來控制,λ越大對變數較多的線性模型的懲罰力度就越大,從而最終獲得一個變數較少的模型。除此之外,另一個參數α來控制應對高相關性(highly correlated)資料時模型的性狀。 LASSO迴歸α=1,Ridge迴歸α=0,這就對應了懲罰函數的形式和目的。我們可以通過嘗試若干次不同值下的λ,來選取最優λ下的參數,還可以結合CV選擇最優秀的模型。
##讀取資料
setwd("~/Desktop")
library(glmnet)
train_origin<-read.table('trian.txt',header = T,fill = T)
test_origin<-read.table('test.txt',header = T,fill = T)
train_test1<-train_origin
train_test1<-train_test1[,-9]
train_test1$tag<-as.factor(train_test1$tag)
train_test1$risk_level<-as.factor(train_test1$risk_level)
x<-train_test1[,3:11]
y<-train_test1[,2]
## one hot encoding
x1<-model.matrix(~., x)
通常資料中會存在離散點,而lasso在R裡面是通過數值矩陣來做輸入的,所以需要對原資料做一步預先處理,不然這邊會拋錯誤;除此之外,如果資料之間差別的數量級較大,還需要進行標準化,R裡面也是可以進行處理的,這邊就不贅述了,glmnet()函數中添加參數standardize = TRUE來實現,scale()函數也可以實現,自行選擇即可。
##模型訓練
model = glmnet(x1, y, family="binomial", nlambda=50, alpha=1)
family裡面是指選擇函數的類型:
| family |
explation |
| gaussian |
univariate |
| mgaussian |
multivariate |
| poisson |
count |
| binomial |
binary |
| multinomial |
category |
lambda是指隨機播放λ,做lambda個模型;alpha是上述講到的α,選擇懲罰函數,正常情況下,1是lasso,0是嶺迴歸
這邊模型拓展可以交叉檢驗一下,有內建的函數:
cvmodel = cv.glmnet(x1, y, family = "binomial", type.measure = "class",nfolds=10)
這邊會多出來一個type.measure,這個type.measure是指期望最小化的目標參量是什麼,換句話說,就是衡量這個模型的指標函數是啥: