書上的代碼看不懂,自己寫了一個,就是太麻煩,書上才15行,我用了26行代碼,,可是我爲什麼看不懂別人的代碼啊!哭唧唧
主要是思路,這裏我用的數據特別簡單,就是自己寫了四個點,然後給他們標籤,來一個新的數據,通過計算該點與已知數據點(帶有標籤的那種)的距離,選取K個最近的點,統計這K個點的標籤,選取最多類別的那一個作爲最後該新輸入數據集的標籤,其實原理類似於說,你周圍的點是什麼樣子,其實大概率決定了你以後是什麼樣子。
接下來直接附上代碼。
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 29 13:55:48 2018
@author: xuanxuan
"""
import numpy as np
#計算兩點之間的距離,把距離作爲key以及訓練數據的標籤作爲value存成一個字典
def comp_dis(X,L,Y): #這裏傳的參數都是數組類型的
D={} #存儲計算的距離
for i in range(len(X)):
d=np.sqrt((X[i][0]-Y[0][0])**2+(X[i][1]-Y[0][1])**2)
D[d]=L[i][0]
#將存成的字典按照Key進行排序 返回一個數組,每一項第一個元素都是距離,另一個是相應的標籤;
#只不過第一項是已經排好序的
D_sorted=sorted(D.items(),key=lambda x:x[0])
#print(D_sorted)
return D_sorted
def Knn(D_sorted,k=2):
d={}
for i in range(k):
key=D_sorted[i][1]
if key not in d:
d[key]=0
else:
d[key]+=1
d_sorted=sorted(d.items(),key=lambda x:x[1],reverse=True)
label=d_sorted[0][0]
return label
if __name__=="__main__":
train_data=np.array([[10,1],[10,2],[1,10],[1,8]])
train_label=np.array([['A'],['A'],['B'],['B']])
test_data=np.array([[5,1]])
D_sorted=comp_dis(train_data,train_label,test_data)
label=Knn(D_sorted,3)
print("對該輸入數據的分類爲:\n{}".format(label))
************************下面是一個約會網站預測的例子**********************
這個數據集是機器學習實戰裏面的數據集。我看了一遍書,有了思路之後,然後用自己的方法實現了一下,其實主要還是對算法理解了才行,實現方式可以有很多種,還有就是對於書上的代碼順着敲一遍是沒有任何意義的,嘻嘻
可是,書上預測的錯誤率才0.024,我的竟然0.36,,,,哭唧唧
還有就是參數我選的80%訓練,20%測試,然後K選的10,好像是最好的了,按照課本的90%訓練 10%測試,K=3更不忍直視,能怎麼辦,寶寶也很絕望啊
下面是代碼:
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 29 18:57:19 2018
@author: xuanxuan
"""
#knn算法應用在約會網站上
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cross_validation import train_test_split
#首先導入數據
def getdata():
dataarr=[]
labelarr=[]
file=open("E:/pyhtonworkspace/py3-pratice/book_practice_python/mechinelearning_in_action/chapter02/datingTestSet2.txt")
for line in file:
linearr=line.strip().split()
L=[]
for s in linearr:
L.append(float(s))
dataarr.append(L[:-1])
labelarr.append(L[-1])
datamat=np.mat(dataarr) #把訓練數據轉變爲1000*3的矩陣
labelmat=np.mat(labelarr).T #把測試數據轉變爲1000*1的矩陣
return datamat,labelmat
def draw(datamat,labelmat):
m=np.shape(datamat)[0]
for i in range(m):
plt.scatter(datamat[i,0],datamat[i,1],10*labelmat[i,0],4*labelmat[i,0])
plt.show()
#主要是對數據進行歸一化處理
def norm(datamat0):
m,n=np.shape(datamat0)
max=datamat0.max(0) #1*3的矩陣
min=datamat0.min(0) #1*3的矩陣
#print(max,min)
dataarr=[]
for i in range(m):
L=[]
for j in range(n):
a=(datamat0[i,j]-min[0,j])/(max[0,j]-min[0,j])
L.append(float(a))
dataarr.append(L)
datamat=np.mat(dataarr)
#print(datamat[:10])
return datamat #返回歸一化之後的數據矩陣
def predict(d_new,k): #這裏的d_new是一個列表 裏邊的元素是tuple!!
d={}
for i in range(k):
key=d_new[i][1]
if key not in d:
d[key]=0
else:
d[key]+=1
#現在的d是key-value:標籤-個數的字典,現在需要按照value進行排序(降序主要是多數表決着最多的類別數作爲該測試點最終的樣本標籤)
d_sorted=sorted(d.items(),key=lambda x:x[1],reverse=True)
return d_sorted[0][0] #返回的是最終對該樣本預測的標籤
def KNN(train_data,train_label,test_data,test_label,k=15):
m=np.shape(test_data)[0] #測試數據集的維度 m*3
n=np.shape(train_data)[0] #訓練數據集的維度 n*3
num=0 #用來統計預測錯誤率的
for i in range(m):
d={} #用來存放測試集中該樣本與訓練集中相應點之間的距離,以及相應的標籤
for j in range(n):
dis=np.sqrt((test_data[i,0]-train_data[j,0])**2+(test_data[i,1]-train_data[j,1])**2+(test_data[i,2]-train_data[j,2]**2))
d[dis]=train_label[j,0] #存成一個字典,key-value:距離,標籤
d_new=sorted(d.items(),key=lambda x:x[0]) #對字典的key進行排序(升序,主要是着距離最近的k個點) 返回一個tuple!!!而不再是字典了不過對應的仍然是距離-標籤 的形式
pre=predict(d_new,k)
if pre!=test_label[i]:
num+=1
error=num/m
return error
if __name__=="__main__":
datamat0,labelmat=getdata()
datamat=norm(datamat0) #將數據及逆行歸一化之後返回的數據矩陣
#draw(datamat,labelmat)
train_data,test_data,train_label,test_label=train_test_split(datamat,labelmat,test_size=0.25,random_state=33)
error=KNN(train_data,train_label,test_data,test_label,10)
print("使用KNN算法預測的錯誤率爲:\n{}".format(error))
還有就是,我實現一個算法要好久,三個小時,怎麼肥si?
明天也要加油鴨~~~
******************************KNN算法識別手寫數字**********************
看完書之後按照自己的理解實現了一下,可是爲什麼我運行不出來啊,是我的電腦有問題,嗯,我邏輯是對的~~~
是電腦配置太低了嘛,,,
接下來直接附上代碼啦~~
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 29 21:56:21 2018
@author: xuanxuan
"""
#識別手寫數字,使用K近鄰算法
import numpy as np
from os import listdir
#讀取其中一個文件比如0_0.txt 把該文件作爲一個樣本,共有1024個特徵
def openfile(filename):
file=open(filename)
dataarr=[]
for i in range(32):
line=file.readline()
for j in range(32):
dataarr.append(int(line[j]))
return dataarr #返回的是一個列表 裏面由1024個元素,代表一個文件樣本的1024個特徵
def get_data1():
filenames=listdir("E:/pyhtonworkspace/py3-pratice/book_practice_python/mechinelearning_in_action/chapter02/digits/trainingDigits" )
m=len(filenames) #訓練數據集中文件個數(樣本數)
labels=[]
datas=[]
for i in range(m):
L=[]
filename=filenames[i]
filenamenum=filename.split('.')[0]
label=filenamenum.split('_')[0]
L.append(label) #對於每一個樣本都有一個label標籤,把所有的label存在一個列表labels
labels.append(L)
data=openfile("E:/pyhtonworkspace/py3-pratice/book_practice_python/mechinelearning_in_action/chapter02/digits/trainingDigits" +'/'+filename)
datas.append(data)
datamat=np.mat(datas)
labelmat=np.mat(labels)
#print(np.shape(labelmat)) #維度是(1934,1)
#print(np.shape(datamat)) #維度是(1934,1024)
return datamat,labelmat
#get_data()
def get_data2():
filenames=listdir("E:/pyhtonworkspace/py3-pratice/book_practice_python/mechinelearning_in_action/chapter02/digits/testDigits" )
m=len(filenames) #訓練數據集中文件個數(樣本數)
labels=[]
datas=[]
for i in range(m):
L=[]
filename=filenames[i]
filenamenum=filename.split('.')[0]
label=filenamenum.split('_')[0]
L.append(label) #對於每一個樣本都有一個label標籤,把所有的label存在一個列表labels
labels.append(L)
data=openfile("E:/pyhtonworkspace/py3-pratice/book_practice_python/mechinelearning_in_action/chapter02/digits/testDigits" +'/'+filename)
datas.append(data)
datamat=np.mat(datas)
labelmat=np.mat(labels)
#print(np.shape(labelmat)) #維度是(946,1)
#print(np.shape(datamat)) #維度是(946,1024)
return datamat,labelmat
def predict(D,K):
D_list=sorted(D.items(),key=lambda x:x[0]) #對D按照key(距離)進行排序(升序) 得到的結果是一個列表!!列表中每一個元素都是一個tuple對應着距離和標籤
D1={}
for i in range(K):
key=D_list[i][1]
if key not in D1:
D1[key]=0
else:
D1[key]+=1 #D2是一個字典 key-value 是標籤-該標籤出現的次數
D1_list=sorted(D1.items(),key=lambda x:x[1],reverse=True) #對D1按照value進行排序 ,也就是距離最小的k個訓練樣本中出現標籤最多的那個作爲該測試樣本的標籤
pred=D1_list[0][0] #作爲最終的預測標籤
return pred
def KNN(test_datamat,test_labelmat,train_datamat,train_labelmat,K=9):
m1,n=np.shape(test_datamat) #測試樣本數和特徵數
m2=np.shape(train_datamat)[0] #訓練樣本數
num_error=0
for i in range(m1):
D={}
for j in range(m2):
d=0
for k in range(n):
d+=(test_datamat[i,k]-train_datamat[j,k])**2
d=d**0.5
D[d]=train_labelmat[j,0] #D字典key-value:測試集合中的一個樣本和訓練集中每一個樣本的距離-和訓練集中對應樣本的標籤
pred=predict(D,K)
if pred!=test_labelmat[i,0]:
num_error+=1
error=num_error/m1
return error
if __name__=="__main__":
train_datamat,train_labelmat=get_data1()
test_datamat,test_labelmat=get_data2()
error=KNN(test_datamat,test_labelmat,train_datamat,train_labelmat)
print("使用KNN算法的錯誤率爲:\n{}".format(error))
明天也要加油鴨~~
今天不開心。