首先本文參考了點擊打開鏈接 這篇博客,然後可能時間有點久遠,Kaggle的這道題給的數據文檔和之前的不一樣了,以及還有一些注意點這篇文章裏沒有突出。因此這裏重新做個總結,希望大家能早點入個門。
這裏我使用的sklearn中的支持向量機來解決手寫識別問題。這裏的svm是可以解決多分類問題的。核函數使用的是高斯核(rbf),鬆弛變量c選擇的是5.
kaggle這道題一共提供了3個文件:train.csv,test.csv,sample_submission.csv 。 分別表示訓練集,測試集,提交樣例。
下面上python代碼。本人的macbook pro16,運行時間爲575秒。svm的準確率在這個問題上可能不及knn,但是運行的效率要比knn高了許多。。。
#!/usr/bin/python
# -*- coding: utf-8 -*-
from numpy import *
from sklearn import svm
import csv
import datetime
#把數組中的字符串轉換成整數
def toInt(array):
array=mat(array)
m,n=shape(array)
#使用xrange不會生成list,性能要優於range
for i in xrange(m):
for j in xrange(n):
array[i,j]=int(array[i,j])
return array
#把大於0的數都置爲1
def nomalizing(array):
m,n=shape(array)
for i in xrange(m):
for j in xrange(n):
if array[i,j]!="0": #注意原csv文件中的數字也是字符串
array[i,j]=1
else:
array[i,j]=0
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]) #移除第0行,第0行是數據列名
l=array(l) #將l由list型轉化爲numpy下的array型
label=l[:,0] #label賦值爲l的第0列
data=l[:,1:] #data賦值爲l的第1至最後一列
return nomalizing(data),toInt(label)
def loadTestData():
l=[]
with open('test.csv') as file:
lines=csv.reader(file)
for line in lines:
l.append(line)
l.remove(l[0])
data=array(l)
return nomalizing(data)
def saveResult(result,csvName):
with open(csvName,'wb') as myFile:
myWriter=csv.writer(myFile)
num = 1
arr=[]
arr.append("ImageId")
arr.append("Label")
myWriter.writerow(arr) #先將列名插入第0行
for i in result:
tmp=[]
tmp.append(num)
num = num + 1
tmp.append(int(i)) ##不能是浮點數
myWriter.writerow(tmp)
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
def main():
starttime = datetime.datetime.now()
trainData,trainLabel=loadTrainData()
print "訓練集讀取完畢"
testData=loadTestData()
print "測試集讀取完畢"
svcClassify(trainData,trainLabel,testData)
endtime = datetime.datetime.now()
print "預測結束--程序總運行時間:"+str((endtime - starttime).seconds)+"秒"
main() #主函數
ps:本人一開始在kaggle上提交結果,總是返回的準確率爲0.00000,後來用文本編輯器打開了csv,才發現自己生成的label都是浮點數,而在excel中看不出來,坑。
kaggle提交注意事項:
- 每道題目一天最多交5次,大家珍惜每天的提交機會
- 提交的csv要嚴格遵循sample_submission.csv中的格式,也就是在提交文件中第一行的列名也是需要加的,且列名不能出錯。
- 提交的數據一定要弄清是整數還是浮點數。否則提交後是會被判斷爲預測錯誤的。