您好,登錄后才能下訂單哦!
該項(xiàng)目通過算法識(shí)別圖像的數(shù)字,圖像由783個(gè)像素特征即灰度值組成,范圍一般從0到255,白色為255,黑色為0,選擇算法依據(jù)據(jù)783個(gè)特征判斷圖像是哪一個(gè)數(shù)字(標(biāo)簽),因?yàn)榫毩?xí)賽,難度還是比較低的。https://www.kaggle.com/c/digit-recognizer
提供數(shù)據(jù)集(在鏈接的data中可下載)有,train.csv(包含1列l(wèi)abel 和783列pixelx,數(shù)據(jù)大小為42001785)、test.csv(含7834列pixelx,數(shù)據(jù)大小為28001784)
此處選擇的算法是python的sklearn庫中的K近鄰算法,當(dāng)然大家也可以嘗試用其他算法,比如樸素貝葉斯、支持向量SVC等,最后K近鄰算法的準(zhǔn)確率最高所以選擇此
K近鄰算法KNN原理是:根據(jù)與待測(cè)試樣本距離最近的k個(gè)訓(xùn)練樣本的大概率分類來判斷待測(cè)樣本所歸屬的類別
過程是:
1)計(jì)算測(cè)試數(shù)據(jù)與各個(gè)訓(xùn)練數(shù)據(jù)之間的距離;
2)按照距離的遞增關(guān)系進(jìn)行排序;
3)選取距離最小的K個(gè)點(diǎn);
4)確定前K個(gè)點(diǎn)所在類別的出現(xiàn)頻率;
5)返回前K個(gè)點(diǎn)中出現(xiàn)頻率最高的類別作為測(cè)試數(shù)據(jù)的預(yù)測(cè)分類。
1. 預(yù)處理
讀取訓(xùn)練數(shù)據(jù)集,拆分為trainlabel 和traindata兩個(gè)矩陣,同時(shí)數(shù)值化和歸一化
train = pd.read_csv("train.csv")
trainlabel = ravel(toint(train.iloc[:, 0]).transpose())
traindata = toint(train.iloc[:, 1:])
test = pd.read_csv("test.csv")
testdata = toint(test.values)
# 對(duì)traindata和testdata歸一化,將所有不為0的數(shù)值全部轉(zhuǎn)換為1
train_rows = traindata.shape[0]
train_columns = traindata.shape[1]
test_rows = testdata.shape[0]
test_columns = testdata.shape[1]
traindata = nomalizing(traindata, train_rows, train_columns)
testdata = nomalizing(testdata, test_rows, test_columns)
此處解釋一下以上提到的兩個(gè)預(yù)處理方法:
①數(shù)值化是指原數(shù)據(jù)集的數(shù)據(jù)類型可能是字符串,由于后面會(huì)做是否為0的判斷,所以需要將數(shù)據(jù)類型轉(zhuǎn)換為數(shù)值型,由toint()函數(shù)完成
def toint(array):
"""轉(zhuǎn)為數(shù)值型數(shù)據(jù)"""
array = mat(array)# 生成矩陣
m, n = shape(array)
newArray = zeros((m, n))
for i in range(m):
for j in range(n):
newArray[i, j] = int(array[i, j])
return newArray
②歸一化是指將所有不為0的數(shù)都轉(zhuǎn)變?yōu)?,目的是簡(jiǎn)化操作,由nomalizing函數(shù)實(shí)現(xiàn)
def nomalizing(data,r,l):
"""一個(gè)標(biāo)簽對(duì)應(yīng)784個(gè)特征,特征值為0-255的灰度值,0代表黑色,255代表白色,此處將所有不為0的值都以1轉(zhuǎn)換,簡(jiǎn)化工作量"""
for i in range(r):
for j in range(l):
if data[i,j] != 0:
data[i,j] = 1
return data
2. 交叉檢驗(yàn)
使用交叉檢驗(yàn),目的是評(píng)估n_neighbors參數(shù)的最佳取值,減少過擬合。
因?yàn)榇颂幹豢刂埔粋€(gè)參數(shù)k,即n_neighbors參數(shù),所以用模型選擇庫中的cross_val_score(),若有多個(gè)參數(shù)則需使用GridSearchCV()
scores_list = []
k_range = range(1,10)
for k in k_range:
knnclf = KNeighborsClassifier(k)
? ? scores = cross_val_score(knnclf,traindata,trainlabel,cv=10,scoring="accuracy")
? ? scores_list.append(mean(scores))
plt.plot(k_range,scores_list)
plt.show()
print(max(scores_list)) # 最大精準(zhǔn)度
k = argsort(array(scores_list))[-1] # 最大精準(zhǔn)度對(duì)應(yīng)的k值
此處將k值得范圍鎖定到1-9,cv=10設(shè)定為十折交叉驗(yàn)證,score ="accuracy"評(píng)分標(biāo)準(zhǔn)采用精確率,默認(rèn)是以 scoring=’f1_macro’
取得k值和對(duì)應(yīng)準(zhǔn)確率的折線圖,可得到最佳k值和最大準(zhǔn)確率
3. 算法實(shí)現(xiàn)
def knnClassify(k,data,label,test):
"""KNN算法"""
knnclf = KNeighborsClassifier(k)
knnclf.fit(data,ravel(label)) # label降維一維數(shù)據(jù)
testlabel = knnclf.predict(test)
save_result(testlabel,"testlabel.csv")
def save_result(data,filename):
"""保存預(yù)測(cè)結(jié)果"""
# newline參數(shù)是控制文本模式之下,一行的結(jié)束字符
with open(filename,'w',newline="") as f:
w = csv.writer(f)
for d in data:
tmp = []
tmp.append(d)
w.writerow(tmp)
lavel()的作用是將多維數(shù)組降為一維,由于label只有一列數(shù)值,每一行特征對(duì)應(yīng)一個(gè)label,需要將shape轉(zhuǎn)變?yōu)椋?2000,)的形式,所以必須降維
擴(kuò)展:lavel()和flatten()有一樣的效果,不過唯一區(qū)別是flatten返回的是副本,而如果改變lavel會(huì)改變?cè)瓟?shù)據(jù)
最后得到預(yù)測(cè)的標(biāo)簽testlabel.csv文件,提交kaggle的準(zhǔn)確率為96.4%
這個(gè)項(xiàng)目還有很多解法,這邊介紹的較基礎(chǔ),如果有余力和興趣可以去[https://blog.csdn.net/weixin_39655021/article/details/86763519神經(jīng)網(wǎng)絡(luò)識(shí)別]
看看更高深的解法
同時(shí)本文還參考了[https://blog.csdn.net/hermito/article/details/51862733Kaggle入門(數(shù)字識(shí)別為例)]
敬禮
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。