Tensorflow實現K近鄰分類器
1. K近鄰分類模型基本原理
如果一個樣本在特徵空間中的k個最相似(即特徵空間中最鄰近)的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別,其中K通常是不大於20的整數。KNN算法中,所選擇的鄰居都是已經正確分類的對象。該方法在定類決策上只依據最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。
2. K近鄰分類模型的三個基本要素
(a) 距離度量 (b) K值的選擇 (c)分類決策規則
2.1 距離度量
假定特徵空間是M維實向量空間: ,任意兩個樣本()的特徵向量記爲:和,和之間的距離定義爲:
時爲歐式距離:
時爲歐式距離:
時爲歐式距離:
在這裏選擇距離
2.2 K值的選擇
上圖中測試樣本爲五角星,其餘均爲訓練樣本,上面三張圖分別是K=1,K=3時測試樣本所屬的類別,當K=1時根據最近鄰分類原則把測試樣本化分爲心狀類別,K=3時也屬於心狀。所以對於K值的選擇,會影響到最終的分類。一般而言K值選擇的越小,整體模型越複雜,容易發生過擬合,K值越大,模型越簡單,i尼斯誤差會增大,但容易發生誤分類。
2.3 分類決策規則
-
多數表決規則:
五角星屬於心狀 -
距離加權規則:
五角星屬於圓臉
3. 計算步驟
- 算距離:給定測試樣本特徵向量,計算它與訓練集中每個樣本特徵向量的距離
- 找鄰居:圈定距離最近的K個訓練樣本,作爲測試樣本的近鄰
- 做分類:根據這K個近鄰歸屬的主要類別,來對測試樣本分類
4. TensorFlow實現
import tensorflow as tf
import os
import numpy as np
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets('mnist_data/',one_hot=True)
Xtrain,Ytrain=mnist.train.next_batch(5000) #限制訓練樣本的個數
Xtest,Ytest=mnist.test.next_batch(200) #測試樣本的個數
print('Xtrain.shape:',Xtrain.shape,'Xtest.shape:',Xtest.shape)
print('Ytrain.shape:',Ytrain.shape,'Ytest.shape:',Ytest.shape)
xtrain=tf.placeholder('float',[None,784],name='X_train') #不知道訓練樣本的個數用None來表示,特證數是28*28=784
xtest=tf.placeholder('float',[784],name='X_test')
distance=tf.reduce_sum(tf.abs(tf.add(xtrain,tf.negative(xtest))),axis=1) #逐行進行縮減運算,最終得到一個行向量
pred=tf.arg_min(distance,0) #獲取最小距離的索引
init=tf.global_variables_initializer()
accuracy=0.
with tf.Session() as sess:
sess.run(init)
Ntest=len(Xtest) #測試樣本數量
for i in range(Ntest):
nn_index=sess.run(pred,feed_dict={xtrain:Xtrain,xtest:Xtest[i,:]}) #每次只傳入一個測試樣本
pred_class_label=np.argmax(Ytrain[nn_index])
true_class_label=np.argmax(Ytest[i])
print('Test',i,'Prediction Class Label:',pred_class_label,'True Class Label:',true_class_label)
if pred_class_label==true_class_label:
accuracy+=1
print('Done!')
accuracy=accuracy/Ntest
print('Accuracy:',accuracy)
writer=tf.summary.FileWriter(logdir='logs_KNN',graph=tf.get_default_graph())
writer.flush()
得出最終訓練結果,可以看到準確率是92%