本文的題目是class prediction(分類預(yù)測),其實就是機(jī)器學(xué)習(xí)硝清,這兩個詞可以互相替代著使用。而本章呢脚囊,其實就是對機(jī)器學(xué)習(xí)進(jìn)行一個簡單的介紹龟糕,如果你想深入學(xué)習(xí),作者給推薦了一本書悔耘,叫《The Elements of Statistical Learning: Data Mining, Inference, and Prediction》讲岁。
簡單的說,機(jī)器學(xué)習(xí)(machine learning,ML)研究的其實就是因變量與協(xié)變量之間的關(guān)系衬以。它與統(tǒng)計推斷其實有很多相似之處缓艳,不同之處在于機(jī)器學(xué)習(xí)的目的是預(yù)測,統(tǒng)計推斷的目的是估計和解釋模型參數(shù)看峻。這篇文章阶淘,作者重點介紹了兩種機(jī)器學(xué)習(xí)的算法:回歸和K臨近算法(KNN)。另外還有一點要知道的是互妓,在ML中溪窒,被稱作predictor或者feature。
訓(xùn)練集和測試集
所謂訓(xùn)練集冯勉,其實就是用于訓(xùn)練模型的一組數(shù)據(jù)澈蚌,而測試集便是用于測試訓(xùn)練后模型的另一組數(shù)據(jù)。至于為啥使用不同的數(shù)據(jù)集去擬合或者訓(xùn)練灼狰,其實是為了檢測過度訓(xùn)練(over-training)的情況宛瞄。
所謂over-training也叫過擬合,指的是模型在訓(xùn)練集上表現(xiàn)的很好交胚,但是在交叉驗證集合測試集上表現(xiàn)一般份汗,也就是說模型對未知樣本的預(yù)測表現(xiàn)一般盈电,泛化(generalization)能力較差。
下面作者用了一個例子來說明使用不同數(shù)據(jù)集去訓(xùn)練和測試模型的重要性裸影,在這個例子中挣轨,自變量是二維數(shù)據(jù),因變量是二進(jìn)制數(shù)據(jù)轩猩,而且二者之間是非線性的關(guān)系卷扮。
- 創(chuàng)建訓(xùn)練集合測試集
library(rafalib)
set.seed(1)
##create covariates and outcomes
##outcomes are alwasy 50 0s and 50 1s
s2=0.15
##pick means to create a non linear conditional expectation
library(MASS)
M0 <- mvrnorm(10,c(1,0),s2*diag(2)) ##generate 10 means
M1 <- rbind(mvrnorm(3,c(1,1),s2*diag(2)),
mvrnorm(3,c(0,1),s2*diag(2)),
mvrnorm(4,c(0,0),s2*diag(2)))
###funciton to generate random pairs
s<- sqrt(1/5)
N=200
makeX <- function(M,n=N,sigma=s*diag(2)){
z <- sample(1:10,n,replace=TRUE) ##pick n at random from above 10
m <- M[z,] ##these are the n vectors (2 components)
return(t(apply(m,1,function(mu) mvrnorm(1,mu,sigma)))) ##the final values
}
###create the training set and the test set
x0 <- makeX(M0)##the final values for y=0 (green)
testx0 <- makeX(M0)
x1 <- makeX(M1)
testx1 <-makeX(M1)
x <- rbind(x0,x1) ##one matrix with everything
test <- rbind(testx0,testx1)
y <- c(rep(0,N),rep(1,N)) #the outcomes
ytest <- c(rep(0,N),rep(1,N))
- 使用線性回歸算法去預(yù)測
若想使用去預(yù)測,可能我們最快想到的辦法就是進(jìn)行線性回歸:
X1 <- x[,1] ##these are the covariates
X2 <- x[,2]
fit1 <- lm(y~X1+X2)
一旦我們計算出了擬合值均践,就可以通過去估計了晤锹,在這里為了簡化,當(dāng)時彤委,都視為1鞭铆。
##prediction on train
yhat <- predict(fit1)
yhat <- as.numeric(yhat>0.5)
cat("Linear regression prediction error in train:",1-mean(yhat==y),"\n")
## Linear regression prediction error in train: 0.295
##prediction on test
yhat <- predict(fit1,newdata=data.frame(X1=test[,1],X2=test[,2]))
yhat <- as.numeric(yhat>0.5)
cat("Linear regression prediction error in test:",1-mean(yhat==ytest),"\n")
## Linear regression prediction error in test: 0.3075
可以看到,使用訓(xùn)練集和測試集去預(yù)測的錯誤率分別是0.295和0.3075焦影,二者相差無幾车遂,也就是沒有出現(xiàn)過擬合的情況。其實這也很正常斯辰,因為本例我們是使用了400個數(shù)據(jù)點擬合一個只有兩個參數(shù)的模型舶担,所以不太會出現(xiàn)過擬合的情況。
線性回歸方法相對來講比較死板彬呻,因為死板所以穩(wěn)定且可以預(yù)防過擬合衣陶,但是線性回歸在那種非線性關(guān)系的例子中就不再適用了。
K臨近算法(kNN)
kNN與bin smoothing有些類似闸氮,都是在數(shù)據(jù)點周圍選擇個最近的點剪况,然后計算他們的均值,從而得到蒲跨,舉例說明:
library(class)
mypar(2,2)
for(k in c(1,100)){
##predict on train
yhat <- knn(x,x,y,k=k)
cat("KNN prediction error in train:",1-mean((as.numeric(yhat)-1)==y),"\n") ##predict on test
yhat <- knn(x,test,y,k=k)
cat("KNN prediction error in test:",1-mean((as.numeric(yhat)-1)==ytest),"\n")
}
## KNN prediction error in train: 0
## KNN prediction error in test: 0.375
## KNN prediction error in train: 0.2425
## KNN prediction error in test: 0.2825
從上述結(jié)果中可以看到译断,當(dāng)時,使用訓(xùn)練集無錯誤财骨、使用測試集卻有很多錯誤镐作,而當(dāng)時,使用兩種數(shù)據(jù)集得到的結(jié)果卻很穩(wěn)定隆箩,作者畫了幾幅圖:
library(class)
library(RColorBrewer)
hmcol <- colorRampPalette(rev(brewer.pal(11, "Spectral")))(100)
mycols=c(hmcol[1],hmcol[100])
cols <- mycols[c(rep(1,N),rep(2,N))]
colstest <- cols
GS <- 150 ##grid size is GS x GS
XLIM <- c(min(c(x[,1],test[,1])),max(c(x[,1],test[,1])))
tmpx <- seq(XLIM[1],XLIM[2],len=GS)
YLIM <- c(min(c(x[,2],test[,2])),max(c(x[,2],test[,2])))
tmpy <- seq(YLIM[1],YLIM[2],len=GS)
newx <- expand.grid(tmpx,tmpy) #grid used to show color contour of predictions
mypar(2,2)
for(k in c(1,100)){
##predict on train
yhat <- knn(x,x,y,k=k)
##make plot
yhat <- knn(x,newx,y,k=k)
colshat <- mycols[as.numeric(yhat)]
plot(x,type="n",xlab="X1",ylab="X2",xlim=XLIM,ylim=YLIM)
points(newx,col=colshat,cex=0.35,pch=16)
#contour()是畫等值線圖的一種函數(shù)
contour(tmpx,tmpy,matrix(as.numeric(yhat),GS,GS),levels=c(1,2),
add=TRUE,drawlabels=FALSE)
points(x,bg=cols,pch=21)
title(paste("Train: KNN (",k,")",sep=""))
plot(test,type="n",xlab="X1",ylab="X2",xlim=XLIM,ylim=YLIM)
points(newx,col=colshat,cex=0.35,pch=16)
contour(tmpx,tmpy,matrix(as.numeric(yhat),GS,GS),levels=c(1,2),
add=TRUE,drawlabels=FALSE)
points(test,bg=cols,pch=21)
title(paste("Test: KNN (",k,")",sep=""))
}
在上圖中该贾,背景中的紅藍(lán)底色區(qū)分的是使用測試集預(yù)測到的,而紅色及藍(lán)色的數(shù)據(jù)點則區(qū)分的是數(shù)據(jù)集本身的值捌臊。
使用訓(xùn)練集訓(xùn)練模型時杨蛋,若,那么離自身最近的那個點就是其自身,所以就相當(dāng)于用自身去預(yù)測自身逞力,那預(yù)測結(jié)果肯定是不會出錯的曙寡;但是從上圖第一行的兩幅圖上我們可以看到,在紅色區(qū)域中有很多藍(lán)色的小島寇荧,因此將測試集帶入用訓(xùn)練出的模型中的話錯誤率就會增大举庶。而當(dāng)時就不會有這種問題,相比揩抡,我們的錯誤率還有所下降户侥。
最后作者繪制了一幅橫坐標(biāo)為k值、縱坐標(biāo)為錯誤率的直線圖:
其中上圖中的黃色水平線是使用貝葉斯規(guī)則預(yù)測得到的錯誤率峦嗤,從圖中可知錯誤率其實是個隨機(jī)變量并且具有標(biāo)準(zhǔn)誤蕊唐,而且當(dāng)k小于20時,訓(xùn)練出的模型存在過擬合問題烁设,而當(dāng)k大于100時又出現(xiàn)了欠擬合問題替梨。
閱讀原文請戳