|
最近一周,下班后都在kaggle上玩。kaggle現(xiàn)在做的越來越好,對于我們這種搞機(jī)器學(xué)習(xí)的新手來說,這個網(wǎng)站提供了很多實際數(shù)據(jù)。關(guān)注這個網(wǎng)站也有快一年時間了,這里不僅傳遞著數(shù)據(jù)和算法,更多的是傳遞著全球數(shù)據(jù)愛好者們對數(shù)據(jù)的信仰。 最近在做的是手寫數(shù)字識別的那道題。手寫數(shù)字識別,是機(jī)器學(xué)習(xí)用于解決實際問題的一個相當(dāng)成功的案例。幾乎所有機(jī)器學(xué)習(xí)的書籍中都會提到這個例子,國內(nèi)甚至還有人專門利用各種算法解決該問題而寫成了一本不薄的書。這個問題的解決,涉及到很多內(nèi)容,除去機(jī)器學(xué)習(xí)中的一些分類算法之外,更多的是工程上的一些問題。比如如何收集大量的手寫數(shù)字樣本,如何提取圖像中的信息,在諸多的學(xué)習(xí)算法中如何找出一個最合適的(未必是預(yù)測準(zhǔn)確度最高的,也許還要考慮時間,成本等其他的因素)。工程師的思維和一個理科學(xué)生的思維之間的差別,在于,工程師往往需要綜合考慮很多因素,得出一個最適宜的解決問題的方案,而一個理科學(xué)生,可能會對自己所掌握的算法數(shù)量和難度引以為傲,但是卻會忽視算法之外的一些事。 關(guān)于手寫數(shù)字識別這個例子,數(shù)據(jù)情況是,訓(xùn)練樣本量73.2M,測試集48.7M。每一個觀測,是一個28*28像素的手寫數(shù)字的圖片,該圖片用長度為28*28的向量來表示,在訓(xùn)練集中,人工標(biāo)識出了每一個觀測對應(yīng)的數(shù)字標(biāo)簽。這是一個典型的有指導(dǎo)學(xué)習(xí)問題。目的是從訓(xùn)練集中學(xué)習(xí)出數(shù)字識別的規(guī)則,然后在測試集上進(jìn)行檢驗。目前kaggle上的最好成績(測試集上的識別準(zhǔn)確率)已經(jīng)達(dá)到了99.47%。 我也嘗試了幾種不同算法來做這個問題,這個過程中也遇到了很多不可避免的工程方面的問題。 我依然是使用最為順手的R作為工具,但是由于32位版本最多只能分配2g內(nèi)存,而很多算法需要儲存大矩陣,因此總會出現(xiàn)“無法分配xx內(nèi)存的矢量”這樣的錯誤提示,令人吐血不止。關(guān)于R語言對大數(shù)據(jù)的處理,目前已經(jīng)有些解決方案,R本身也有bigmemory包之類的。但是內(nèi)存依然無法滿足需要。這也是R語言最為人所詬病的一點。 我所采用的解決方法比較簡單,每次隨機(jī)從訓(xùn)練樣本中抽出三分之一的數(shù)據(jù)作為訓(xùn)練集,訓(xùn)練完成得到模型之后便把所用的訓(xùn)練數(shù)據(jù)刪掉(騰出內(nèi)存來),然后用模型在檢測集上進(jìn)行分類,將分類結(jié)果輸出寫到硬盤上,然后刪除內(nèi)存上的相應(yīng)結(jié)果。重復(fù)多次這樣的過程,得到多組結(jié)果,然后再按照少數(shù)服從多數(shù)的原則在多組結(jié)果中進(jìn)行投票,得到最終的預(yù)測結(jié)果。這樣的方法,顯得很不靠譜。也很令人心痛,因為明明有那么多數(shù)據(jù)可以用,但是由于計算機(jī)和自身水平的限制無法利用,只能提取一小部分來利用。這是令人氣郁的。然而,即便只用了三分之一的數(shù)據(jù),可是當(dāng)你還是發(fā)現(xiàn),訓(xùn)練依然需要消耗大量的時間時,你也只能遺憾的接受這樣殘酷的現(xiàn)實了。 算法方面,我選取了naive bayes,k-nearest neighborhood(k=10),generalized linear model(with lasso regularization),randomForest以及support vector machine。這些方法都是最為基本(常用)的機(jī)器學(xué)習(xí)算法。除了naive bayes算法預(yù)測準(zhǔn)確度較低,60%左右之外,剩下幾種算法的預(yù)測準(zhǔn)確度都在92%到96%。其中SVM算法精度最高,這個結(jié)果是預(yù)料之中的。令我感到比較意外的是加了L1范數(shù)懲罰項的廣義線性模型的效果也比較出色。這個模型使用了cross-validation,因此整個過程非常耗時,這個模型僅使用了三分之一的樣本,并不似其他算法,我都做了model average,但是還是得到了比較滿意的預(yù)測效果。讓我又一次對Efron,hastie,freedman他們充滿了敬仰。 照例,代碼將共享。 #####prepare the data#####setwd("F:/kaggle/numRecognition") training=read.csv("train.csv",header=TRUE) test=read.csv("test.csv",header=TRUE) #Check the data set #head(training) #head(test) label=training[,1] label.f <- as.factor(label) train=as.matrix(training[,-1]) test=as.matrix(test) ###in order to run the code on my computer,i have to split the train set and make ###model average,what a fuck!! #####KNN##### library(FNN) idx.1=sample(c(1:42000),size=42000/3,replace=TRUE) train.1=train[idx.1,] label.1=label[idx.1] res.KNN.1 =knn(train.1, test, label.1, k = 10, algorithm="cover_tree") write(res.KNN.1, file="RESKNN1.csv", ncolumns=1) rm(train.1) rm(label.1) rm(res.KNN.1) rm(idx.1) idx.2=sample(c(1:42000),size=42000/3,replace=TRUE) train.2=train[idx.2,] label.2=label[idx.2] res.KNN.2 =knn(train.2, test, label.2, k = 10, algorithm="cover_tree") write(res.KNN.2, file="RESKNN2.csv", ncolumns=1) rm(train.2) rm(label.2) rm(res.KNN.2) rm(idx.2) idx.3=sample(c(1:42000),size=42000/3,replace=TRUE) train.3=train[idx.3,] label.3=label[idx.3] res.KNN.3 =knn(train.3, test, label.3, k = 10, algorithm="cover_tree") write(res.KNN.3, file="RESKNN3.csv", ncolumns=1) rm(train.3) rm(label.3) rm(res.KNN.3) rm(idx.3) idx.4=sample(c(1:42000),size=42000/3,replace=TRUE) train.4=train[idx.4,] label.4=label[idx.4] res.KNN.4 =knn(train.4, test, label.4, k = 10, algorithm="cover_tree") write(res.KNN.4, file="RESKNN4.csv", ncolumns=1) rm(train.4) rm(label.4) rm(res.KNN.4) rm(idx.4) idx.5=sample(c(1:42000),size=42000/3,replace=TRUE) train.5=train[idx.5,] label.5=label[idx.5] res.KNN.5 =knn(train.5, test, label.5, k = 10, algorithm="cover_tree") write(res.KNN.5, file="RESKNN5.csv", ncolumns=1) rm(train.5) rm(label.5) rm(res.KNN.5) rm(idx.5) res.knn.1=read.csv("RESKNN1.csv",header=FALSE) res.knn.2=read.csv("RESKNN2.csv",header=FALSE) res.knn.3=read.csv("RESKNN3.csv",header=FALSE) res.knn.4=read.csv("RESKNN4.csv",header=FALSE) res.knn.5=read.csv("RESKNN5.csv",header=FALSE) res=data.frame(res.knn.1,res.knn.2,res.knn.3,res.knn.4,res.knn.5) res=as.matrix(res) res.knn=vector() for(i in 1:length(res.knn.1[,1])) { res.knn[i]=names(sort(table(as.vector(res[i,])),decreasing=TRUE)[1]) } res.knn=as.numeric(res.knn) write(res.knn, file="resknn_submit.csv", ncolumns=1) #####randomForest##### library(randomForest) idx.1=sample(c(1:42000),size=42000/3,replace=TRUE) train.1=train[idx.1,] label.1=label.f[idx.1] model1.randomforest = randomForest(train.1, label.1, xtest=test, ntree=1000) pred1.randomforest = levels(label.1)[model.randomforest$test$predicted] write(pred1.randomforest, file="predRandF1.csv", ncolumns=1) rm(train.1) rm(label.1) rm(model1.randomforest) rm(pred1.randomforest) idx.2=sample(c(1:42000),size=42000/3,replace=TRUE) train.2=train[idx.2,] label.2=label.f[idx.2] model2.randomforest = randomForest(train.2, label.2, xtest=test, ntree=1000) pred2.randomforest = levels(label.2)[model.randomforest$test$predicted] write(pred2.randomforest, file="predRandF2.csv", ncolumns=1) rm(train.2) rm(label.2) rm(model2.randomforest) rm(pred2.randomforest) idx.1=sample(c(1:42000),size=42000/3,replace=TRUE) train.1=train[idx.1,] label.1=label.f[idx.1] model1.randomforest = randomForest(train.1, label.1, xtest=test, ntree=1000) pred1.randomforest = levels(label.1)[model.randomforest$test$predicted] write(pred1.randomforest, file="predRandF1.csv", ncolumns=1) rm(train.1) rm(label.1) rm(model1.randomforest) rm(pred1.randomforest) idx.1=sample(c(1:42000),size=42000/3,replace=TRUE) train.1=train[idx.1,] label.1=label.f[idx.1] model1.randomforest = randomForest(train.1, label.1, xtest=test, ntree=1000) pred1.randomforest = levels(label.1)[model.randomforest$test$predicted] write(pred1.randomforest, file="predRandF1.csv", ncolumns=1) rm(train.1) rm(label.1) rm(model1.randomforest) rm(pred1.randomforest) idx.1=sample(c(1:42000),size=42000/3,replace=TRUE) train.1=train[idx.1,] label.1=label.f[idx.1] model1.randomforest = randomForest(train.1, label.1, xtest=test, ntree=1000) pred1.randomforest = levels(label.1)[model.randomforest$test$predicted] write(pred1.randomforest, file="predRandF1.csv", ncolumns=1) rm(train.1) rm(label.1) rm(model1.randomforest) rm(pred1.randomforest) #####naive bayes###### library(e1071) rm(training) rm(label) model.nb=naiveBayes(train,label.f) pred.nb=predict(model.nb,test) head(pred.nb) #####lasso#####library(glmnet) idx.1=sample(c(1:42000),size=42000/3,replace=TRUE) train.1=train[idx.1,] label.f.1=label.f[idx.1] fit.glmnet.1=cv.glmnet(train.1,label.f.1,family="multinomial") pred.glmnet.1=predict(fit.glmnet.1,newx=test,type="class",s="lambda.min") #print(fit.glmnet.1) #plot... |
|
|