KNN算法的python實現

1. 處理數據

# filename:文件路徑  trainingSet:訓練集  testSet:測試集 訓練數據集數據量/測試數據集數據量的比值取67/33是一個經常使用的慣例。
def loadDataset(filename,split,trainingSet=[], testSet=[]):
    with open(filename,'r') as csvfile: #使用open方法打開文件
        lines = csv.reader(csvfile) #使用csv模塊讀取數據
        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:
            #random.random()用於生成一個0到1的隨機符點數: 0 <= n < 1.0。
            #隨機地切分訓練數據集和測試數據集。訓練數據集數據量/測試數據集數據量的比值取67/33是一個經常使用的慣例,因此split取值通常爲0.66
                trainingSet.append(dataset[x])
            else:
                testSet.append(dataset[x])

測試代碼算法

trainingSet=[]
testSet=[]
loadDataset('iris.data',0.66,trainingSet,testSet)
print('trainingSet',repr(len(trainingSet)))
print('testSet',repr(len(testSet)))

2. 類似度

咱們須要計算兩個數據之間的類似度,便於獲取最類似的N個實例來作出預測。數組

由於有關花的四個測量維度的數據都是數字形式的,而且具備相同的單位。咱們能夠直接使用歐式距離來測量。app

二維平面上兩點a(x1,y1)與b(x2,y2)間的歐氏距離: 輸入圖片說明dom

# length:告訴函數前幾個維度須要處理,忽略後面的維度
def euclideanDistance(instance1,instance2,length):
    distance = 0
    for x in range(length):
        distance += pow((instance1[x]-instance2[x]),2) #全部須要計算的維度距離相加
    return math.sqrt(distance)

測試代碼:ide

data1 = [2,2,2,'a']
data2 = [4,4,4,'b']
# length=3只計算前面三個維度
distance = euclideanDistance(data1,data2,3)
print('distance',repr(distance))

3. 鄰近類似度

有了類似度計算的方法,咱們能夠獲取與須要預測的數據最接近的N個數據實例了。函數

最直接的方法就是計算待預測數據到全部數據實例的距離,取其中距離最小的N個。測試

# testInstance:待預測數據
def getNeighbors(trainingSet, testInstance, k):
    distances = []
    length = len(testInstance)-1
    for x in range(len(trainingSet)):
        #testinstance
        dist = euclideanDistance(testInstance, trainingSet[x], length)
        distances.append((trainingSet[x], dist))
        #distances.append(dist)
    distances.sort(key=operator.itemgetter(1))
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
        return neighbors

測試代碼:idea

trainSet = [[2,2,2,'a'],[4,4,4,'b']]
testInstance = [5,5,5]
k = 1
neighbors = getNeighbors(trainSet,testInstance,k)
print(neighbors)

測試結果(鄰近元素): [[4, 4, 4, 'b']]code

4. 結果

接下來的任務就是基於最近的幾個實例來獲得預測結果了。圖片

咱們能夠讓這些鄰近元素來對預測屬性進行投票,得票最多的選項做爲預測結果

下面這個函數實現了投票的邏輯,它假設需預測的屬性放在數據實例(數組)的最後。

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.items(), key=None, reverse=True)
    return sortedVotes[0][0] #

測試代碼:

neighbors= [[1,1,1,'a'],[2,2,2,'a'],[3,3,3,'b']]
response = getResponse(neighbors)
print(response)

5. 準確度

簡單的評估方法:計算在測試數據集中算法正確預測的比例,這個比例叫分類準確度。

# 假設predictions爲測試集的預測結果集
def getAccuracy(testSet, predictions):
    correct = 0
    for x in range(len(testSet)):
        if testSet[x][-1] is predictions[x]:
            correct += 1
    return (correct/float(len(testSet))) * 100.0

測試代碼:

testSet = [[1,1,1,'a'],[2,2,2,'a'],[3,3,3,'b']]
predictions = ['a','a','a']
accuracy = getAccuracy(testSet,predictions)
print(accuracy)
相關文章
相關標籤/搜索