由於選修了數據挖掘課程,課程作業是完成Kaggle上的一個比賽,所以在機緣巧合下就知道了Kaggle這個平臺,事實上我認爲這是用來練手數據挖掘的一個絕佳場所。這篇文章適合和我一樣剛接觸Kaggle的朋友,對於已經熟悉這個平臺的朋友,歡迎指出我的錯誤,必定虛心受教。本文分爲兩個部分,第一部分簡單介紹在上面完成比賽的流程,第二部分以手寫數字識別爲例子詳細描述完成比賽的整個過程。
1、Kaggle簡介
Kaggle是一個數據分析的競賽平臺,網址:https://www.kaggle.com/首先進入Kaggle網站,註冊登陸後拉下來會看到進行中的比賽
其中對於我們新手而言更關心的是101練習賽先用來熟悉整個流程
點擊digit Recognizer進入比賽,我們可以看到主要有三個部分是我們關心的,比賽介紹,數據獲取和提交答案,如下圖是剛點擊進去就能夠看到的比賽描述
點擊Get the data跳轉到一下頁面就可以獲取數據
點擊Make a submission就會跳轉到提交界面,在此界面點擊click or drop your submission here,將我們跑出來的答案文件上傳,再點擊submit提交即可,然後就會跳轉到排名版(learder board),我們就可以看到自己的排名以及準確率了。
關於比賽的細節:
1、我們下載得到的數據都是csv格式的數據,因爲最後只需要提交結果,所以這中間我們使用任何語言任何算法都是可以的,沒有任何限制
2、初始數據中訓練集是有Label的,而測試數據是沒有Label的,我們要做的是用訓練集來訓練模型,然後推測出測試集每個元組的Label,這些推測出來的Label組成的文件就是我們最後要提交的文件,必須以規定的形式,而且必須是csv格式。
3、系統會從最終數據中選25%的數據作爲初評,也就是我們一提交看到的準確率和排名都是根據這25%的數據得出的。準確率的計算時,比如10個Label你的預測對了9個,那麼準確率就是90%。並不是初評排名高就好,因爲比賽結束後終評是使用剩下的75%的數據進行評測,所以最後準確率還是有可能有很大的變化。
2、競賽項目解題全過程
(2)Digit Recognition解題過程
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
由於從文件中讀出的Label是字符,所以我們需要將它轉化爲數字(toInt函數)。另外,我們都知道圖像可以表示成灰度矩陣,而題目給我們的數據就是手寫數字圖像的灰度矩陣,對於灰度級我們是不關心的,即我們不關心字跡的深淺,我們關心的是字的有無,所以可以使用二值化的方法對原始數據進行處理(nomalizing函數)。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
有了訓練集和測試集的數據,下一步就是用訓練集訓練模型並預測測試集。調用sklearn庫的隨機森林函數,建立分類器nbClf,參數n_estimators是設置決策樹的棵數,一般不要小於100,然後用fit函數訓練,用predict函數預測,則testLable是一個28000行的數組,每行存儲對應的Label。from sklearn.ensemble import RandomForestClassifier
def RFClassify(trainData,trainLabel,testData):
nbClf=RandomForestClassifier(n_estimators=100)
nbClf.fit(trainData,ravel(trainLabel))
testLabel=nbClf.predict(testData)
saveResult(testLabel,'RF_Result.csv')
return testLabel
最後一步就是將數據寫入csv文件,注意並不能直接每行一個數字這樣地寫,要按照要求的格式,即添加第一行的屬性名,還有添加一列序號,調用saveResult進行寫入def saveResult(result,csvName):
with open(csvName,'wb') as myFile:
myWriter=csv.writer(myFile)
myWriter.writerow(["ImageId","Label"])
index=0;
for i in result:
tmp=[]
index=index+1
tmp.append(index)
tmp.append(i)
#tmp.append(int(i))
myWriter.writerow(tmp)
將得到的csv文件提交上去後得到的準確率是0,爲什麼呢?首先看一下文件內部