天天看點

python 實作 knn分類算法 (Iris 資料集)machine-learning-databases/iris 點選打開連結

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]
           

繼續閱讀