Код

Читать о KNN

Прежде всего импортируйте все полезные библиотеки, которые нужны в программе.

import math
import numpy as np 
import matplotlib.pyplot as plt
import operator
import random
import pandas as pd

Для работы с массивами используется numpy. Также matplotlib — это библиотека, которая используется для построения графиков. Подобно numpy, pandas предоставляет высокопроизводительные, простые в использовании структуры и инструменты анализа данных.

После импорта библиотек вторым шагом является загрузка набора данных. Вы можете найти набор данных, который я использовал здесь.

#load train data of respective class
loaddata_train1=np.loadtxt('.../group4/class1_train.txt')
loaddata_train2=np.loadtxt('.../group4/class2_train.txt')
#load test data of respective class
loaddata_test1=np.loadtxt('.../group4/class1_test.txt')
loaddata_test2=np.loadtxt('.../group4/class2_test.txt')
#concatenate train and test data of different classes in one variable with axis = 0 (row wise)
loaddata_train=np.concatenate((loaddata_train1, loaddata_train2), axis=0)        
loaddata_test=np.concatenate((loaddata_test1, loaddata_test2), axis=0)

После загрузки данных пришло время пометить данные, поскольку наши исходные данные не помечены.

#label the data - class1 as 1 and class2 = -1 
label1=np.ones((loaddata_train1.shape[0], 1))
label2=np.ones((loaddata_train2.shape[0], 1)) * -1
r1=np.append(label1, loaddata_train1, axis=1)
r2=np.append(label2, loaddata_train2, axis=1)
#concatenate whole train data
train_data=np.concatenate((r1,r2))

Аналогично для тестовых данных.

#label the data - class1 as 1 and class2 = -1
label3=np.ones((loaddata_test1.shape[0], 1))
label4=np.ones((loaddata_test2.shape[0], 1)) * -1
r3=np.append(label3, loaddata_test1, axis=1)
r4=np.append(label4, loaddata_test2, axis=1)
#concatenate whole test data
test_data=np.concatenate((r3,r4))

Диаграмма рассеяния набора данных. Библиотека, используемая для построения графиков, — matplotlib. Мы используем маркер «o» для класса 1 и маркер «x» для класса 2.

plt.scatter(loaddata_train1[:,0], loaddata_train1[:,1], marker='o', label='Class1')
plt.scatter(loaddata_train2[:,0], loaddata_train2[:,1], marker='x', label='Class2')
plt.legend()
plt.show()

Теперь в соответствии с алгоритмом рассчитайте евклидово расстояние между каждой точкой тестовых данных и каждой точкой данных поезда.

def euclideanDistance(instance1, instance2, length):
    distance = 0
    for x in range(length):
        distance += pow((float(instance1[x]) - float(instance2[x])), 2)
    return math.sqrt(distance)

После вычисления евклидова расстояния следующим шагом будет определение соседей, верхних значений k. Предпочтительно использовать нечетное значение k, потому что будет легче узнать метку класса, так как при четном могут быть равные шансы получить ту же метку класса.

def getKNeighbors(train_data, testInstance, k):
    distances = []
    length = len(testInstance)-1
    for x in range(len(train_data)):
        dist = euclideanDistance(testInstance, train_data[x], length)
        distances.append((train_data[x], dist))
    distances.sort(key=operator.itemgetter(1))
#     print(distances)
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
    return neighbors

Пришло время получить ответы или результаты от соседей, которые мы получили от вышеуказанной функции.

def getResponse(neighbors):
    classVotes = {} #empty dictionary to collect class votes
    for x in range(len(neighbors)):
        response = neighbors[x][0]
        if response in classVotes:
            classVotes[response] += 1
        else:
            classVotes[response] = 1
    sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True)
    #print(response)
    return sortedVotes[0][0]

После того, как все сделано, определите функцию main() для дальнейшей и окончательной обработки кода.

def main():
    l00 = 0
    l01 = 0
    l10 = 0
    l11 = 0
    #split = 0.70
    print ('Train: ' + repr(len(train_data)))
    print ('Test: ' + repr(len(test_data)))
    #generate predictions
    #predictions = []
    k = input("Enter value of k: ")
    k = int(k) 
    list_pred = []
    list_act = []
    for x in range(len(test_data)):
        neighbors = getKNeighbors(train_data, test_data[x], k)
        result = getResponse(neighbors)
        #predictions.append(result)
        list_pred.append(result)
        list_act.append(test_data[x][0])
    for i in range(0, len(test_data)):
        x = list_pred[0]
        y = list_act[0]
        if int(list_pred[i]) == -1 and int(list_act[i]) == -1:
            l00 += 1
        elif int(list_pred[i]) == -1 and int(list_act[i]) == 1:
            l01 += 1
        elif int(list_pred[i]) == 1 and int(list_act[i]) == -1:
            l10 += 1
        elif int(list_pred[i]) == 1 and int(list_act[i]) == 1:
            l11 += 1
        i+=1
a = np.array([[l00, l01],
        [l10, l11]])
    print('Confusion Matrix: ') 
    print(pd.DataFrame(a, columns = ['class_0', 'class_1'], index = ['class_0', 'class_1']))
acc = (l00+l11)*100/(l00+l01+l10+l11)
    print('Accuracy: ' + repr(acc) +'%')
main()

Результат :

Train: 2447
Test: 977
Enter value of k: 5
Confusion Matrix: 
         class_0  class_1
class_0      488        0
class_1        0      489
Accuracy: 100.0%