1、KNN分類算法
KNN分類算法(K-Nearest-Neighbors Classification),又叫K近鄰算法,是一個概念極其簡單,而分類效果又很優秀的分類算法。
他的核心思想就是,要确定測試樣本屬于哪一類,就尋找所有訓練樣本中與該測試樣本“距離”最近的前K個樣本,然後看這K個樣本大部分屬于哪一類,那麼就認為這個測試樣本也屬于哪一類。簡單的說就是讓最相似的K個樣本來投票決定。
KNN算法不僅可以用于分類,還可以用于回歸。通過找出一個樣本的k個最近鄰居,将這些鄰居的屬性的平均值賦給該樣本,就可以得到該樣本的屬性。更有用的方法是将不同距離的鄰居對該樣本産生的影響給予不同的 權值(weight),如權值與距離成反比。 該算法在分類時有個主要的不足是,當樣本不平衡時,如一個類的樣本容量很大,而其他類樣本容量很小時,有可能導緻當輸入一個新樣本時,該樣本的K個鄰居中大容量類的樣本占多數。 該算法隻計算“最近的”鄰居樣本,某一類的樣本數量很大,那麼或者這類樣本并不接近目标樣本,或者這類樣本很靠近目标樣本。無論怎樣,數量并不能影響運作結果。可以采用權值的方法(和該樣本距離小的鄰居權值大)來改進。 該方法的另一個不足之處是計算量較大,因為對每一個待分類的文本都要計算它到全體已知樣本的距離,才能求得它的K個最近鄰點。目前常用的解決方法是事先對已知 樣本點進行剪輯,事先去除對分類作用不大的樣本。該算法比較适用于 樣本容量比較大的類域的自動分類,而那些樣本容量較小的類域采用這種算法比較容易産生誤分。 實作 K 近鄰算法時,主要考慮的問題是如何對訓練資料進行快速 K 近鄰搜尋,這在特征空間維數大及訓練資料容量大時非常必要。 2、資料集介紹
machine-learning-databases/iris 點選打開連結
資料集資訊:
這也許是最著名的資料庫模式識别文獻中被發現。 費舍爾的論文是一個典型的,經常被引用。 (見杜達&哈特,例如)。 50個執行個體的資料集包含3類,其中
每個類是指一種虹膜。 一個類是線性可分的從其他2;後者不是線性可分的。
預測屬性:類的虹膜。
UCI中的Iris(鸢尾屬植物)資料集。Iris資料包含150條樣本記錄,分剮取自三種不同的鸢尾屬植物setosa、versic010r和virginica的花朵樣本,每一
類各50條記錄,其中每條記錄有4個屬性:萼片長度(sepal length)、萼片寬度sepalwidth)、花瓣長度(petal length)和花瓣寬度(petal width)。
這是一個極其簡單的域。
3、完整源碼
#-*- coding: UTF-8 -*-
'''''
Created on 2016/7/17
@author: chen
'''
import csv #用于處理csv檔案
import random #用于随機數
import math
import operator #
from sklearn import neighbors
#加載資料集
def loadDataset(filename,split,trainingSet=[],testSet = []):
with open(filename,"rb") as csvfile:
lines = csv.reader(csvfile)
dataset = list(lines)
for x in range(len(dataset)-1):
for y in range(4):
dataset[x][y] = float(dataset[x][y])
if random.random()<split:
trainingSet.append(dataset[x])
else:
testSet.append(dataset[y])
#計算距離
def euclideanDistance(instance1,instance2,length):
distance = 0
for x in range(length):
distance += pow((instance1[x] - instance2[x]),2)
return math.sqrt(distance)
#傳回K個最近鄰
def getNeighbors(trainingSet,testInstance,k):
distances = []
length = len(testInstance) -1
#計算每一個測試執行個體到訓練集執行個體的距離
for x in range(len(trainingSet)):
dist = euclideanDistance(testInstance, trainingSet[x], length)
distances.append((trainingSet[x],dist))
#對所有的距離進行排序
distances.sort(key=operator.itemgetter(1))
neighbors = []
#傳回k個最近鄰
for x in range(k):
neighbors.append(distances[x][0])
return neighbors
#對k個近鄰進行合并,傳回value最大的key
def getResponse(neighbors):
classVotes = {}
for x in range(len(neighbors)):
response = neighbors[x][-1]
if response in classVotes:
classVotes[response]+=1
else:
classVotes[response] = 1
#排序
sortedVotes = sorted(classVotes.iteritems(),key = operator.itemgetter(1),reverse =True)
return sortedVotes[0][0]
#計算準确率
def getAccuracy(testSet,predictions):
correct = 0
for x in range(len(testSet)):
if testSet[x][-1] == predictions[x]:
correct+=1
return (correct/float(len(testSet))) * 100.0
def main():
trainingSet = [] #訓練資料集
testSet = [] #測試資料集
split = 0.67 #分割的比例
loadDataset(r"../data/iris.txt", split, trainingSet, testSet)
print "Train set :" + repr(len(trainingSet))
print "Test set :" + repr(len(testSet))
predictions = []
k = 3
for x in range(len(testSet)):
neighbors = getNeighbors(trainingSet, testSet[x], k)
result = getResponse(neighbors)
predictions.append(result)
print ">predicted = " + repr(result) + ",actual = " + repr(testSet[x][-1])
accuracy = getAccuracy(testSet, predictions)
print "Accuracy:" + repr(accuracy) + "%"
if __name__ =="__main__":
main()
為了檢驗上述程式是否正确,編寫一下代碼,測試隻需上面的代碼。
#coding:utf-8
'''''
Created on 2016年7月17日
@author: chen
'''
from sklearn.datasets import load_iris
from sklearn import neighbors
import sklearn
#檢視iris資料集
iris = load_iris()
print iris
knn = neighbors.KNeighborsClassifier()
#訓練資料集
knn.fit(iris.data, iris.target)
#預測
predict = knn.predict([[0.1,0.2,0.3,0.4]])
print predict
print iris.target_names[predict]
結果如下
Train set :92
Test set :39
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
>predicted = 'Iris-setosa',actual = 'Iris-setosa'
Accuracy:100.0%
[Finished in 1.4s]