Kaggle入门——使用scikit-learn解决DigitRecognition问题


@author: wepon

@blog: http://blog.csdn.net/u012162613


1、scikit-learn简介


scikit-learn是一个基于NumPy、SciPy、Matplotlib的开源机器学习工具包,采用Python语言编写,主要涵盖分类、

归和聚类等算法,例如knn、SVM、逻辑回归、朴素贝叶斯、随机森林、k-means等等诸多算法,官网上代码和文档

都非常不错,对于机器学习开发者来说,是一个使用方便而强大的工具,节省不少开发时间。


scikit-learn官网指南:http://scikit-learn.org/stable/user_guide.html



上一篇文章《大数据竞赛平台—Kaggle入门》  我分两部分内容介绍了Kaggle,在第二部分中,我记录了解决Kaggle上的竞赛项目DigitRecognition的整个过程,当时我是用自己写的kNN算法,尽管自己写歌kNN算法并不会花很多时间,但是当我们想尝试更多、更复杂的算法,如果每个算法都自己实现的话,会很浪费时间,这时候scikit-learn就发挥作用了,我们可以直接调用scikit-learn的算法包。当然,对于初学者来说,最好还是在理解了算法的基础上,来调用这些算法包,如果有时间,自己完整地实现一个算法相信会让你对算法掌握地更深入。

OK,话休絮烦,下面进入第二部分。

2、使用scikit-learn解决DigitRecognition

我发现自己很喜欢用DigitRecognition这个问题来练习分类算法,因为足够简单。如果你还不知道DigitRecognition问题是什么,请先简单了解一下:Kaggle DigitRecognition ,在我上一篇文章中也有描述:《大数据竞赛平台—Kaggle入门》 。下面我使用scikit-learn中的算法包kNN(k近邻)、SVM(支持向量机)、NB(朴素贝叶斯)来解决这个问题,解决问题的关键步骤有两个:1、处理数据。2、调用算法。

(1)处理数据

这一部分与上一篇文章《大数据竞赛平台—Kaggle入门》 中第二部分的数据处理是一样的,本文不打算重复,下面只简单地罗列各个函数及其功能,在本文最后部分也有详细的代码。

[python]  view plain  copy
  1. def loadTrainData():  
  2.     #这个函数从train.csv文件中获取训练样本:trainData、trainLabel  
  3. def loadTestData():  
  4.     #这个函数从test.csv文件中获取测试样本:testData  
  5. def toInt(array):  
  6. def nomalizing(array):  
  7.     #这两个函数在loadTrainData()和loadTestData()中被调用  
  8.     #toInt()将字符串数组转化为整数,nomalizing()归一化整数  
  9. def loadTestResult():  
  10.     #这个函数加载测试样本的参考label,是为了后面的比较  
  11. def saveResult(result,csvName):  
  12.     #这个函数将result保存为csv文件,以csvName命名  


“处理数据”部分,我们从train.csv、test.csv文件中获取了训练样本的feature、训练样本的label、测试样本的feature,在程序中我们用trainData、trainLabel、testData表示。


(2)调用scikit-learn中的算法

kNN算法
[python]  view plain  copy
  1. #调用scikit的knn算法包  
  2. from sklearn.neighbors import KNeighborsClassifier    
  3. def knnClassify(trainData,trainLabel,testData):   
  4.     knnClf=KNeighborsClassifier()#default:k = 5,defined by yourself:KNeighborsClassifier(n_neighbors=10)  
  5.     knnClf.fit(trainData,ravel(trainLabel))  
  6.     testLabel=knnClf.predict(testData)  
  7.     saveResult(testLabel,'sklearn_knn_Result.csv')  
  8.     return testLabel  

kNN算法包可以自己设定参数k,默认k=5,上面的comments有说明。

更加详细的使用,推荐上官网查看:http://scikit-learn.org/stable/modules/neighbors.html




SVM算法
[python]  view plain  copy
  1. #调用scikit的SVM算法包  
  2. from sklearn import svm     
  3. def svcClassify(trainData,trainLabel,testData):   
  4.     svcClf=svm.SVC(C=5.0#default:C=1.0,kernel = 'rbf'. you can try kernel:‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’    
  5.     svcClf.fit(trainData,ravel(trainLabel))  
  6.     testLabel=svcClf.predict(testData)  
  7.     saveResult(testLabel,'sklearn_SVC_C=5.0_Result.csv')  
  8.     return testLabel  

SVC()的参数有很多,核函数默认为'rbf'(径向基函数),C默认为1.0

更加详细的使用,推荐上官网查看:http://scikit-learn.org/stable/modules/svm.html



朴素贝叶斯算法
[python]  view plain  copy
  1. #调用scikit的朴素贝叶斯算法包,GaussianNB和MultinomialNB  
  2. from sklearn.naive_bayes import GaussianNB      #nb for 高斯分布的数据  
  3. def GaussianNBClassify(trainData,trainLabel,testData):   
  4.     nbClf=GaussianNB()            
  5.     nbClf.fit(trainData,ravel(trainLabel))  
  6.     testLabel=nbClf.predict(testData)  
  7.     saveResult(testLabel,'sklearn_GaussianNB_Result.csv')  
  8.     return testLabel  
  9.       
  10. from sklearn.naive_bayes import MultinomialNB   #nb for 多项式分布的数据      
  11. def MultinomialNBClassify(trainData,trainLabel,testData):   
  12.     nbClf=MultinomialNB(alpha=0.1)      #default alpha=1.0,Setting alpha = 1 is called Laplace smoothing, while alpha < 1 is called Lidstone smoothing.         
  13.     nbClf.fit(trainData,ravel(trainLabel))  
  14.     testLabel=nbClf.predict(testData)  
  15.     saveResult(testLabel,'sklearn_MultinomialNB_alpha=0.1_Result.csv')  
  16.     return testLabel  

上面我尝试了两种朴素贝叶斯算法:高斯分布的和多项式分布的。多项式分布的函数有参数alpha可以自设定。
更加详细的使用,推荐上官网查看:http://scikit-learn.org/stable/modules/naive_bayes.html




使用方法总结: 

第一步:首先确定使用哪种分类器,这一步可以设置各种参数,比如:
[python]  view plain  copy
  1. svcClf=svm.SVC(C=5.0)  

第二步:接这个分类器要使用哪些训练数据?调用fit方法,比如:
[python]  view plain  copy
  1. svcClf.fit(trainData,ravel(trainLabel))  

fit(X,y)说明:
X:  对应trainData
array-like, shape = [n_samples, n_features],X是训练样本的特征向量集,n_samples行n_features列,即每个训练样本占一行,每个训练样本有多少特征就有多少列。
y:  对应trainLabel
array-like, shape = [n_samples],y必须是一个行向量,这也是上面为什么使用numpy.ravel()函数的原因。

第三步:使用分类器预测测试样本,比如:
[python]  view plain  copy
  1. testLabel=svcClf.predict(testData)  

调用predict方法。

第四步:保存结果,这一步是取决于我们解决问题的要求,因为本文以DigitRecognition为例,所以有:
[python]  view plain  copy
  1. saveResult(testLabel,'sklearn_SVC_C=5.0_Result.csv')  



(3)make a submission

上面基本就是整个开发过程了,下面看一下各个算法的效果,在Kaggle上make a submission

knn算法的效果,准确率95.871%




朴素贝叶斯,alpha=1.0,准确率81.043%



SVM,linear核,准确率93.943%




3、工程文件




贴一下代码:
[python]  view plain  copy
  1. #!/usr/bin/python  
  2. # -*- coding: utf-8 -*-  
  3. """ 
  4. Created on Tue Dec 16 21:59:00 2014 
  5.  
  6. @author: wepon 
  7.  
  8. @blog:http://blog.csdn.net/u012162613 
  9. """  
  10.   
  11. from numpy import *  
  12. import csv  
  13.   
  14. def toInt(array):  
  15.     array=mat(array)  
  16.     m,n=shape(array)  
  17.     newArray=zeros((m,n))  
  18.     for i in xrange(m):  
  19.         for j in xrange(n):  
  20.                 newArray[i,j]=int(array[i,j])  
  21.     return newArray  
  22.       
  23. def nomalizing(array):  
  24.     m,n=shape(array)  
  25.     for i in xrange(m):  
  26.         for j in xrange(n):  
  27.             if array[i,j]!=0:  
  28.                 array[i,j]=1  
  29.     return array  
  30.       
  31. def loadTrainData():  
  32.     l=[]  
  33.     with open('train.csv') as file:  
  34.          lines=csv.reader(file)  
  35.          for line in lines:  
  36.              l.append(line) #42001*785  
  37.     l.remove(l[0])  
  38.     l=array(l)  
  39.     label=l[:,0]  
  40.     data=l[:,1:]  
  41.     return nomalizing(toInt(data)),toInt(label)  #label 1*42000  data 42000*784  
  42.     #return trainData,trainLabel  
  43.       
  44. def loadTestData():  
  45.     l=[]  
  46.     with open('test.csv') as file:  
  47.          lines=csv.reader(file)  
  48.          for line in lines:  
  49.              l.append(line)#28001*784  
  50.     l.remove(l[0])  
  51.     data=array(l)  
  52.     return nomalizing(toInt(data))  #  data 28000*784  
  53.     #return testData  
  54.       
  55. def loadTestResult():  
  56.     l=[]  
  57.     with open('knn_benchmark.csv') as file:  
  58.          lines=csv.reader(file)  
  59.          for line in lines:  
  60.              l.append(line)#28001*2  
  61.     l.remove(l[0])  
  62.     label=array(l)  
  63.     return toInt(label[:,1])  #  label 28000*1  
  64.       
  65. #result是结果列表   
  66. #csvName是存放结果的csv文件名  
  67. def saveResult(result,csvName):  
  68.     with open(csvName,'wb') as myFile:      
  69.         myWriter=csv.writer(myFile)  
  70.         for i in result:  
  71.             tmp=[]  
  72.             tmp.append(i)  
  73.             myWriter.writerow(tmp)  
  74.               
  75.               
  76. #调用scikit的knn算法包  
  77. from sklearn.neighbors import KNeighborsClassifier    
  78. def knnClassify(trainData,trainLabel,testData):   
  79.     knnClf=KNeighborsClassifier()#default:k = 5,defined by yourself:KNeighborsClassifier(n_neighbors=10)  
  80.     knnClf.fit(trainData,ravel(trainLabel))  
  81.     testLabel=knnClf.predict(testData)  
  82.     saveResult(testLabel,'sklearn_knn_Result.csv')  
  83.     return testLabel  
  84.       
  85. #调用scikit的SVM算法包  
  86. from sklearn import svm     
  87. def svcClassify(trainData,trainLabel,testData):   
  88.     svcClf=svm.SVC(C=5.0#default:C=1.0,kernel = 'rbf'. you can try kernel:‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’    
  89.     svcClf.fit(trainData,ravel(trainLabel))  
  90.     testLabel=svcClf.predict(testData)  
  91.     saveResult(testLabel,'sklearn_SVC_C=5.0_Result.csv')  
  92.     return testLabel  
  93.       
  94. #调用scikit的朴素贝叶斯算法包,GaussianNB和MultinomialNB  
  95. from sklearn.naive_bayes import GaussianNB      #nb for 高斯分布的数据  
  96. def GaussianNBClassify(trainData,trainLabel,testData):   
  97.     nbClf=GaussianNB()            
  98.     nbClf.fit(trainData,ravel(trainLabel))  
  99.     testLabel=nbClf.predict(testData)  
  100.     saveResult(testLabel,'sklearn_GaussianNB_Result.csv')  
  101.     return testLabel  
  102.       
  103. from sklearn.naive_bayes import MultinomialNB   #nb for 多项式分布的数据      
  104. def MultinomialNBClassify(trainData,trainLabel,testData):   
  105.     nbClf=MultinomialNB(alpha=0.1)      #default alpha=1.0,Setting alpha = 1 is called Laplace smoothing, while alpha < 1 is called Lidstone smoothing.         
  106.     nbClf.fit(trainData,ravel(trainLabel))  
  107.     testLabel=nbClf.predict(testData)  
  108.     saveResult(testLabel,'sklearn_MultinomialNB_alpha=0.1_Result.csv')  
  109.     return testLabel  
  110.   
  111.   
  112. def digitRecognition():  
  113.     trainData,trainLabel=loadTrainData()  
  114.     testData=loadTestData()  
  115.     #使用不同算法  
  116.     result1=knnClassify(trainData,trainLabel,testData)  
  117.     result2=svcClassify(trainData,trainLabel,testData)  
  118.     result3=GaussianNBClassify(trainData,trainLabel,testData)  
  119.     result4=MultinomialNBClassify(trainData,trainLabel,testData)  
  120.       
  121.     #将结果与跟给定的knn_benchmark对比,以result1为例  
  122.     resultGiven=loadTestResult()  
  123.     m,n=shape(testData)  
  124.     different=0      #result1中与benchmark不同的label个数,初始化为0  
  125.     for i in xrange(m):  
  126.         if result1[i]!=resultGiven[0,i]:  
  127.             different+=1  
  128.     print different  
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐