Kaggle案例——使用scikit-learn解决DigitRecognition问题

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

2、使用scikit-learn解决DigitRecognition

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

1、处理数据。

2、调用算法。

(1)处理数据

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

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

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

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

kNN算法

#调用scikit的knn算法包
from sklearn.neighbors import KNeighborsClassifier  
def knnClassify(trainData,trainLabel,testData): 
    knnClf=KNeighborsClassifier()#default:k = 5,defined by yourself:KNeighborsClassifier(n_neighbors=10)
    knnClf.fit(trainData,ravel(trainLabel))
    testLabel=knnClf.predict(testData)
    saveResult(testLabel,'sklearn_knn_Result.csv')
    return testLabel

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

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

SVM算法

#调用scikit的SVM算法包
from sklearn import svm   
def svcClassify(trainData,trainLabel,testData): 
    svcClf=svm.SVC(C=5.0) #default:C=1.0,kernel = 'rbf'. you can try kernel:‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’  
    svcClf.fit(trainData,ravel(trainLabel))
    testLabel=svcClf.predict(testData)
    saveResult(testLabel,'sklearn_SVC_C=5.0_Result.csv')
    return testLabel

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

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

朴素贝叶斯算法

#调用scikit的朴素贝叶斯算法包,GaussianNB和MultinomialNB
from sklearn.naive_bayes import GaussianNB      #nb for 高斯分布的数据
def GaussianNBClassify(trainData,trainLabel,testData): 
    nbClf=GaussianNB()          
    nbClf.fit(trainData,ravel(trainLabel))
    testLabel=nbClf.predict(testData)
    saveResult(testLabel,'sklearn_GaussianNB_Result.csv')
    return testLabel
    
from sklearn.naive_bayes import MultinomialNB   #nb for 多项式分布的数据    
def MultinomialNBClassify(trainData,trainLabel,testData): 
    nbClf=MultinomialNB(alpha=0.1)      #default alpha=1.0,Setting alpha = 1 is called Laplace smoothing, while alpha < 1 is called Lidstone smoothing.       
    nbClf.fit(trainData,ravel(trainLabel))
    testLabel=nbClf.predict(testData)
    saveResult(testLabel,'sklearn_MultinomialNB_alpha=0.1_Result.csv')
    return testLabel

上面我尝试了两种朴素贝叶斯算法:高斯分布的和多项式分布的。多项式分布的函数有参数alpha可以自设定。

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

使用方法总结:

第一步:首先确定使用哪种分类器,这一步可以设置各种参数,比如:

svcClf=svm.SVC(C=5.0)

第二步:接这个分类器要使用哪些训练数据?调用fit方法,比如:

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()函数的原因。

第三步:使用分类器预测测试样本,比如:

 testLabel=svcClf.predict(testData)

调用predict方法。

第四步:保存结果,这一步是取决于我们解决问题的要求,因为本文以DigitRecognition为例,所以有:

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、工程文件

下载:回复本公众号“kaggle”可获取。

贴一下代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 16 21:59:00 2014

@author: wepon

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

from numpy import *
import csv

def toInt(array):
    array=mat(array)
    m,n=shape(array)
    newArray=zeros((m,n))
    for i in xrange(m):
        for j in xrange(n):
                newArray[i,j]=int(array[i,j])
    return newArray
    
def nomalizing(array):
    m,n=shape(array)
    for i in xrange(m):
        for j in xrange(n):
            if array[i,j]!=0:
                array[i,j]=1
    return array
    
def loadTrainData():
    l=[]
    with open('train.csv') as file:
         lines=csv.reader(file)
         for line in lines:
             l.append(line) #42001*785
    l.remove(l[0])
    l=array(l)
    label=l[:,0]
    data=l[:,1:]
    return nomalizing(toInt(data)),toInt(label)  #label 1*42000  data 42000*784
    #return trainData,trainLabel
    
def loadTestData():
    l=[]
    with open('test.csv') as file:
         lines=csv.reader(file)
         for line in lines:
             l.append(line)#28001*784
    l.remove(l[0])
    data=array(l)
    return nomalizing(toInt(data))  #  data 28000*784
    #return testData
    
def loadTestResult():
    l=[]
    with open('knn_benchmark.csv') as file:
         lines=csv.reader(file)
         for line in lines:
             l.append(line)#28001*2
    l.remove(l[0])
    label=array(l)
    return toInt(label[:,1])  #  label 28000*1
    
#result是结果列表 
#csvName是存放结果的csv文件名
def saveResult(result,csvName):
    with open(csvName,'wb') as myFile:    
        myWriter=csv.writer(myFile)
        for i in result:
            tmp=[]
            tmp.append(i)
            myWriter.writerow(tmp)
            
            
#调用scikit的knn算法包
from sklearn.neighbors import KNeighborsClassifier  
def knnClassify(trainData,trainLabel,testData): 
    knnClf=KNeighborsClassifier()#default:k = 5,defined by yourself:KNeighborsClassifier(n_neighbors=10)
    knnClf.fit(trainData,ravel(trainLabel))
    testLabel=knnClf.predict(testData)
    saveResult(testLabel,'sklearn_knn_Result.csv')
    return testLabel
    
#调用scikit的SVM算法包
from sklearn import svm   
def svcClassify(trainData,trainLabel,testData): 
    svcClf=svm.SVC(C=5.0) #default:C=1.0,kernel = 'rbf'. you can try kernel:‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’  
    svcClf.fit(trainData,ravel(trainLabel))
    testLabel=svcClf.predict(testData)
    saveResult(testLabel,'sklearn_SVC_C=5.0_Result.csv')
    return testLabel
    
#调用scikit的朴素贝叶斯算法包,GaussianNB和MultinomialNB
from sklearn.naive_bayes import GaussianNB      #nb for 高斯分布的数据
def GaussianNBClassify(trainData,trainLabel,testData): 
    nbClf=GaussianNB()          
    nbClf.fit(trainData,ravel(trainLabel))
    testLabel=nbClf.predict(testData)
    saveResult(testLabel,'sklearn_GaussianNB_Result.csv')
    return testLabel
    
from sklearn.naive_bayes import MultinomialNB   #nb for 多项式分布的数据    
def MultinomialNBClassify(trainData,trainLabel,testData): 
    nbClf=MultinomialNB(alpha=0.1)      #default alpha=1.0,Setting alpha = 1 is called Laplace smoothing, while alpha < 1 is called Lidstone smoothing.       
    nbClf.fit(trainData,ravel(trainLabel))
    testLabel=nbClf.predict(testData)
    saveResult(testLabel,'sklearn_MultinomialNB_alpha=0.1_Result.csv')
    return testLabel


def digitRecognition():
    trainData,trainLabel=loadTrainData()
    testData=loadTestData()
    #使用不同算法
    result1=knnClassify(trainData,trainLabel,testData)
    result2=svcClassify(trainData,trainLabel,testData)
    result3=GaussianNBClassify(trainData,trainLabel,testData)
    result4=MultinomialNBClassify(trainData,trainLabel,testData)
    
    #将结果与跟给定的knn_benchmark对比,以result1为例
    resultGiven=loadTestResult()
    m,n=shape(testData)
    different=0      #result1中与benchmark不同的label个数,初始化为0
    for i in xrange(m):
        if result1[i]!=resultGiven[0,i]:
            different+=1
    print different

原文发布于微信公众号 - 大数据挖掘DT数据分析(datadw)

原文发表时间:2015-12-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏linux驱动个人学习

高通Audio中ASOC的machine驱动

ASoC被分为Machine、Platform和Codec三大部分,其中的Machine驱动负责Platform和Codec之间的耦合以及部分和设备或板子特定的...

9784
来自专栏菩提树下的杨过

linq to sql取出随机记录/多表查询/将查询出的结果生成xml

在手写sql的年代,如果想从sqlserver数据库随机取几条数据,可以利用order by NewId()轻松实现,要实现多表查询也可以用select * f...

2196
来自专栏码匠的流水账

聊聊HystrixThreadPool

hystrix-core-1.5.12-sources.jar!/com/netflix/hystrix/HystrixThreadPool.java

781
来自专栏一个会写诗的程序员的博客

java.sql.SQLException: connection holder is null

java.sql.SQLException: connection holder is null

1341
来自专栏MelonTeam专栏

Bitmap 源码阅读笔记

导语: Android 系统上的图片的处理,跟Bitmap 这个类脱不了关系,我们有必要去深入阅读里面的源码,以便在工作中能更好的处理Bitmap相关的问题...

2518
来自专栏专知

2018年SCI期刊最新影响因子排行,最高244,人工智能TPAMI9.455

2018年6月26日,最新的SCI影响因子正式发布,涵盖1万2千篇期刊。CA-Cancer J Clin 依然拔得头筹,其影响因子今年再创新高,达244.585...

1282
来自专栏码匠的流水账

聊聊spring cloud的HystrixAutoConfiguration

本文主要研究一下spring cloud的HystrixAutoConfiguration

992
来自专栏c#开发者

XML Encryption in .Net

XML Encryption in .Net One of the new features being introduced with the Whidbey...

4377
来自专栏JMCui

MongoDB系列五(地理空间索引与查询).

Volvo Today, Volvo announced i...

2722
来自专栏码匠的流水账

spring security reactive获取security context

本文主要研究下reactive模式下的spring security context的获取。

1792

扫码关注云+社区