Skip to content

Instantly share code, notes, and snippets.

@rupython
Created June 5, 2021 12:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rupython/cf88979f9940919a020daac05f9af60a to your computer and use it in GitHub Desktop.
Save rupython/cf88979f9940919a020daac05f9af60a to your computer and use it in GitHub Desktop.
From: Jampik
import numpy as np
import math
# классификация методом k ближайших соседей
# X - обучающее множество.
# Строки соответствуют объектам,
# столбцы - признакам.
# Последний столбец - номер класса
# k - количество ближайших соседей (не более числа объектов в X)
# obj - объект, который нужно классифицировать
def k_nearest(X, k, obj):
# TODO: выполнить нормализацию каждого столбца (кроме последнего)
# матрицы X, пользуясь формулой с практики по k-means. Для этого удобно
# сохранить часть матрицы X без последнего столбца в матрицу sub_X
# Пример выбора всех столбцов, кроме последнего:
sub_X = X[:, 0:-1]
m = sub_X.shape[0]
n = sub_X.shape[1]
min_x = X.min(axis=0)
max_x = X.max(axis=0)
print(m)
print(n)
print(sub_X)
sub_X = (max_x - min_x) * np.random.random((3, )) + min_x
# >>> a = np.arange(1, 7).reshape([2, 3])
# >>> a
# array([[1, 2, 3],
# [4, 5, 6]])
# >>> a[:, 0:-1] # <- первое двоеточие значит, что берём все строки, а запись 0:-1 - берём столбцы от самого первого (с индексом 0) до предпоследнего
# array([[1, 2],
# [4, 5]])
# TODO: зная параметры среднего и среднеквадратического отклонения
# по каждому столбцу sub_X, выполнить нормализацию объекта obj
obj = (max_x-min_x)*np.random.random((1, 1))+min_x
# TODO: рассчитать евклидово расстояние от obj до каждого объекта sub_X (функция dist ниже).
# Реализовать можно с помощью цикла for. Существуют разные варианты записи этого цикла, например, такой:
# Пример реализации цикла for на Python. Здесь возводится в квадрат каждый элемент массива a
# >>> a = np.array([1, 2, 3])
# >>> b = [pow(i, 2) for i in a]
# >>> b
# [1, 4, 9]
res = []
for i in range(len(sub_X)):
res.append(dist(sub_X[i], obj))
# TODO: Получить с помощью функции np.argsort индексы соседей по мере их удаления от obj.
# Для справки по функции argsort выполните в консоли Python команду help('numpy.argsort')
# Пример вызова функции argsort:
# >>> a = np.array([3, 2, 5])
# >>> np.argsort(a)
# array([1, 0, 2], dtype=int64) # минимальный элемент 2 с индексом 1 в массиве a, затем 3 с индексом 0 и в конце 5 с индексом 2.
ind = np.argsort(res)
# TODO: выбрать в отдельный вектор классы k ближайших соседей
# Нужно взять k строк из матрицы X, соответствующих ближайшим соседям.
# Индексы строк ближайших соседей были получены на предыдущем шаге.
# Из этих строк нас интересует только последнее значение (последний столбец матрицы X),
# так как там хранится класс объекта. Пример выбора из матрицы строк по заданным индексам и последнего столбца:
# >>> a = np.arange(1, 10).reshape([3, 3]) # создание матрицы 3*3
# >>> a
# array([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]])
# >>> a[[0, 2], -1] # взяли первую и третью строки (индексы 0 и 2 соответственно), и в них последнее значение. Это будут значения 3 и 9.
nearest_classes = X[ind]
# TODO: определить наиболее часто встречающийся класс в этом векторе. Просто раскомментируйте код ниже:
unique, counts = np.unique(nearest_classes, return_counts=True)
object_class = unique[np.argmax(counts)]
# TODO: вернуть полученное значение из функции. Искомый класс объекта obj хранится в переменной object_class
return object_class
# вычисление евклидова расстояния между двумя точками
def dist(p1, p2):
return math.sqrt(sum((p1 - p2)**2))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment