k近鄰演算法:
或者說k最近鄰(knn,k-nearestneighbor)
在乙個空間中有許多樣本,這時候來了乙個新的樣本即測試點,那麼如何判斷這個樣本的類別。做法就是求測試點和空間中每個樣本的距離,用距離最近的前k個判斷。
比如下圖新來了乙個點,這時候k=3,離它最近的3個點就是乙個為正方形,兩個為三角形,那麼就把新的點判定為三角形。
再比如:
訓練集是二維陣列[1.0,1.1],[1.0,1.0],[0.1,0],[0,0.1]
標籤 labels=[『a』,『a』,『b』,『b』]
測試集[0.2,0.1]
k=3首先計算測試集和訓練集之間的距離
點[0.2,0.1]與[1.0,1.1]之間的距離計算為:
計算完所有點之間的距離之後從小到大排序,選取前k個距離,對進行遍歷,將對應標籤加一。如[a:1,b:2]這裡就輸出a
演算法的優點:
1、簡單,易於理解,易於實現,無需估計引數,無需訓練
2、適合對稀有事件進行分類
3、特別適合於多分類問題(multi-modal,物件具有多個類別標籤), knn比svm的表現要好
演算法的缺點:
1、該演算法在分類時有個主要的不足是,當樣本不平衡時,如乙個類的樣本容量很大,而其他類樣本容量很小時,有可能導致當輸入乙個新樣本時,該樣本的k個鄰居中大容量類的樣本占多數。 該演算法只計算「最近的」鄰居樣本,某一類的樣本數量很大,那麼或者這類樣本並不接近目標樣本,或者這類樣本很靠近目標樣本。無論怎樣,數量並不能影響執行結果。
2、該方法的另乙個不足之處是計算量較大,因為對每乙個待分類的文字都要計算它到全體已知樣本的距離,才能求得它的k個最近鄰點。
程式實現:
from numpy import *
import operator
def createdataset(): #建立標籤和資料
group=array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels=['a','a','b','b']
return group,labels
def classifify0(inx,dataset,labels,k):
datasetsize=dataset.shape[0] # datasetsize=4 計算距離
diffmat=tile(inx,(datasetsize,1))-dataset #tile(inx,(datasetsize,1)),讓inx變為和dataset一樣的型別
sqdiffmat=diffmat**2 #
sqdistances=sqdiffmat.sum(axis=1)
distances=sqdistances**0.5
sorteddistindicies=distances.argsort()
classcount={}
for i in range(k): #選擇距離最小的k個節點
voteilabel=labels[sorteddistindicies[i]]
classcount[voteilabel]=classcount.get(voteilabel,0)+1
sortedcalsscount=sorted(classcount.items(),
key=operator.itemgetter(1),reverse=true)
return sortedcalsscount[0][0]
group,labels=createdataset()
print(classifify0([1, 0.5], group, labels, 3))
from numpy import *
import operator
from keras.datasets import mnist
import numpy as np
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train=x_train[0:10000] #取10000個訓練
y_train=y_train[0:10000]
x_test=x_test[0:100] #取100個測試
y_test=y_test[0:100]
aa=x_train[1].reshape(1,784)
def classifify0(inx,dataset,labels,k):
datasetsize=dataset.shape[0] # datasetsize=4
diffmat=tile(inx,(datasetsize,1))-dataset #tile(inx,(datasetsize,1)),讓inx變為和dataset一樣的型別
sqdiffmat=diffmat**2 #
sqdistances=sqdiffmat.sum(axis=1)
distances=sqdistances**0.5
sorteddistindicies=distances.argsort()
classcount={}
for i in range(k):
voteilabel=labels[sorteddistindicies[i]]
classcount[voteilabel]=classcount.get(voteilabel,0)+1
sortedcalsscount=sorted(classcount.items(),
key=operator.itemgetter(1),reverse=true)
return sortedcalsscount[0][0]
def handwriting(x_train,y_train,x_test,k):
hwlabels=
m=len(x_train)
trainingmat=zeros((m,784))
for i in range(m):
trainingmat[i,:]=x_train[i].reshape(1,784) #將轉換為向量形式
mtest=len(x_test)
for i in range(mtest):
wordtest=x_test[i].reshape(1,784)
classresult=classifify0(wordtest,trainingmat,y_train,k)
#print("result:{},true{}".format(classresult,y_test[i]))
return hwlabels
k=[10,50,100,150] #取前k個
總結:k近鄰演算法比較簡單和有效,但是需要大量的儲存空間,比較耗時
機器學習實戰之K 近鄰演算法
k 近鄰演算法工作原理 存在乙個樣本資料集合,也稱作訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道每一資料與所屬分類的對應關係。輸入沒有標籤的新資料後,將新資料的每個特徵與樣本集中資料對應的資料進行比較,然後演算法提取樣本集中特徵最相似資料 最鄰近 的分類標籤。一般來說,我們只選取樣本資料集...
機器學習實戰之 k 近鄰演算法
k 近鄰演算法 knn 採用測量不同特徵值之間的距離方法進行分類。優點 精度高 對異常值不敏感 無資料輸入假定。缺點 計算複雜度高 空間複雜度高。適用資料範圍 數值型和標稱型。描述 存在乙個樣本資料集合,樣本集中每個資料都存在標籤,即我們知道樣本集中每一資料與所屬分類的對應關係。輸人沒有標籤的新資料...
《機器學習實戰》之K 近鄰演算法
k 近鄰演算法實現 from numpy import import operator from os import listdir 資料集 defcreatedataset group array 1.0,1.1 1.0,1.0 0,0 0,0.1 labels a a b b return gr...