kNN分類學習(Tensorflow實現)

kNN算法原理

kNN也就是k-NearestNeighbour的縮寫。從命名上也可大體瞭解到這個算法的精髓了。用一句話歸納而言,kNN分類算法就是‘近朱者赤,近墨者黑’。說得準確一點就是若是一個樣本在特徵空間中的k個最相鄰的樣本大多數屬於某一類別,則該樣本也屬於此類別,並具備相應類別的特徵python

下面這個例子出如今無數講解kNN的文章中,可見其的表明性:算法

咱們把數據樣本在一個平面上表示出來,相同類別的使用相同顏色和記號。綠色的圓形表明一個新的樣本,咱們使用kNN來判斷它的類別。方法以下:以綠色圓形爲圓心,開始作不一樣半徑的同心圓,從實心線的同心圓來看,綠色圓形屬於紅色三角,從虛線同心圓來看,綠色圓形屬於藍色正方形,以此類推......ide

從上面的例子中不難發現問題,一方面,不一樣的半徑會有不一樣的分類結果。能夠說從圖像上來看未知樣本屬於紅色三角的可能性要比屬於藍色正方形的可能性大,也就是實線的同心圓範圍內是合理的結果。反應在算法設計方面就是k值的選擇。從另外一方面看,距離測試樣本近的數據所佔的權重要更大,距離遠的佔的權重應該小,從而能夠部分避免k值選取不當而形成的判斷錯誤。oop

k值的選擇

k越小,分類邊界曲線越光滑,誤差越小,方差越大;K越大,分類邊界曲線越平坦,誤差越大,方差越小。因此即便簡單如kNN,一樣要考慮誤差和方差的權衡問題,表現爲k的選取。測試

k過小,分類結果易受噪聲點影響;idea

k太大,近鄰中又可能包含太多的其它類別的點。(對距離加權,能夠下降k值設定的影響)k值一般是採用交叉檢驗來肯定(以k=1爲基準)設計

經驗規則:k通常低於訓練樣本數的平方根rest

而所謂的交叉驗證就是把數據樣本分紅訓練集和測試集,而後k=1開始,使用驗證集來更新k的值。code

類別斷定(權值選擇)

投票決定:少數服從多數,近鄰中哪一個類別的點最多就分爲該類。對象

加權投票法:根據距離的遠近,對近鄰的投票進行加權,距離越近則權重越大(權重爲距離平方的倒數)

距離的定義

距離衡量包括歐式距離、夾角餘弦等。

對於文本分類來講,使用餘弦(cosine)來計算類似度就比歐式(Euclidean)距離更合適

Tensorflow實現

對minist數據集使用kNN算法 python3.5版本能夠運行:

import tensorflow as tf 
import numpy as np

import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)     #下載並加載mnist數據

train_X, train_Y = mnist.train.next_batch(5000) # 5000 for training (nn candidates)
test_X, test_Y = mnist.test.next_batch(100)   # 200 for testing


tra_X = tf.placeholder("float", [None, 784])
te_X = tf.placeholder("float", [784])

# Nearest Neighbor calculation using L1 Distance
# Calculate L1 Distance
distance = tf.reduce_sum(tf.abs(tf.add(tra_X, tf.neg(te_X))), reduction_indices=1)
# Prediction: Get min distance index (Nearest neighbor)
pred = tf.arg_min(distance, 0)

accuracy = 0.

# Initializing the variables
init = tf.initialize_all_variables()

# Launch the graph
with tf.Session() as sess:
	sess.run(init)

	# loop over test data
	for i in range(len(test_X)):
    	# Get nearest neighbor
    	nn_index = sess.run(pred, feed_dict={tra_X: train_X, te_X: test_X[i, :]})
    	# Get nearest neighbor class label and compare it to its true label
    	print("Test", i, "Prediction:", np.argmax(train_Y[nn_index]), \
        	"True Class:", np.argmax(test_Y[i]))
    	# Calculate accuracy
    	if np.argmax(train_Y[nn_index]) == np.argmax(test_Y[i]):
        	accuracy += 1./len(test_X)
	print("Done!")
	print("Accuracy:", accuracy)

kNN分類算法的評價

##優勢

  • 1.簡單,易於理解,易於實現,無需估計參數,無需訓練;
    1. 適合對稀有事件進行分類;
  • 3.特別適合於多分類問題(multi-modal,對象具備多個類別標籤), kNN比SVM的表現要好。

缺點

  • 1.樣本不平衡時,會使結果出現誤差
  • 2.計算量龐大
  • 3.因爲不須要訓練,因此算法的可控性比較差

改進策略

分類效率:事先對樣本屬性進行約簡,刪除對分類結果影響較小的屬性,快速的得出待分類樣本的類別。該算法比較適用於樣本容量比較大的類域的自動分類,而那些樣本容量較小的類域採用這種算法比較容易產生誤分。

分類效果:採用權值的方法(和該樣本距離小的鄰居權值大)來改進,Han等人於2002年嘗試利用貪心法,針對文件分類實作可調整權重的k最近鄰居法WAkNN (weighted adjusted k nearest neighbor),以促進分類效果;而Li等人於2004年提出因爲不一樣分類的文件自己有數量上有差別,所以也應該依照訓練集合中各類分類的文件數量,選取不一樣數目的最近鄰居,來參與分類

相關文章
相關標籤/搜索