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

  2. Нормализовать все входные признаки.

#Нормализуем данные, вычитая среднее значение, и разделив на стандартное отклонение.
for (i in 1:ncol(my_data[,-5]))
  my_data[,i] = (my_data[,i] - mean(my_data[,i]))/sd(my_data[,i])
  1. Разделить выборку your_data на равные по длине обучающее tr_set и контрольное val_set подмножества в пропорции 10 на 90%. Для разделения выборки рекомендуется использовать возможности функции rbinom(N, 1, p), где N – размер исходной выборки, p – доля наблюдений исходной выборки, выбираемых в обучающее множество, которая генерирует случайную последовательность нулей и единиц длины N, причём соотношение нулей и единиц соответствует параметру p. Полученную случайную последовательность можно использовать для выборки наблюдений в обучающую (единицы) и контрольную (нули) выборку.
indexes = rbinom(nrow(my_data), 1, 0.1)
tr_set = my_data[which(indexes==1),]
val_set = my_data[which(indexes==0),]
  1. Написать функцию euclid(x1,x2) для оценки евклидового расстояния между двумя числовыми векторами x1 и x2 равной размерности.
euclid <- function(x1,x2) {sqrt(sum((x1-x2)^2))}
  1. Написать функцию knn_estimate(xt, classes, K, query), которая, используя обучающую выборку xt (значений входных признаков) и вектор соответствующих значений классов объектов classes, позволяет получить классификацию запроса query (вектор значений входных признаков) методом K ближайших соседей:
    • c помощью функции euclid() определяются расстояния от вектора query до каждого из наблюдений обучающей выборки;
    • по полученным расстояниям находятся K наиболее близких к query наблюдений из обучающей выборки и определяются их классы (по номерам в исходной выборке);
    • классификация осуществляется путём определения класса большинства ближайших соседей (предполагается, что K – нечётное).
knn_estimate <- function(xt, k, query){
  len = nrow(xt);
  dist = vector(length=len);
  for (i in 1:len) 
    dist[i]=euclid(xt[i,1:4],query);
  names(dist)=1:len; #Обозначаем каждое расстояние соответсвующим порядковым номером
  nearbs = as.integer(names(sort(dist)[1:k])); #Получаем индексы K ближайших соседей
  rt = table(xt[nearbs,5]); #rt == Result Table
  names(rt[which(rt==max(rt))]);
}
#Пример работы функции
knn_estimate(tr_set,15, 1:4)
## [1] "Original"
  1. Оценить долю ошибочных классификаций наблюдений из контрольной выборки для K=1,3,5.
get_error <- function(train, val, k){
  len = nrow(val);
  res_names = vector(length = len);
  for (i in 1:len)
    res_names[i] = knn_estimate(train, k, val[i,1:4]);
  rt = table(val[,5]==res_names);
  cat(c("Для",k,"ближайших соседей:"));
  cat(c("Ошибочно классифицировано ",round(as.numeric(rt[1]/len),4)*100,"% данных."),sep="");
}

get_error(tr_set, val_set, 1)
## Для 1 ближайших соседей:Ошибочно классифицировано 17.55% данных.
get_error(tr_set, val_set, 3)
## Для 3 ближайших соседей:Ошибочно классифицировано 14.51% данных.
get_error(tr_set, val_set, 5)
## Для 5 ближайших соседей:Ошибочно классифицировано 13.72% данных.
  1. Определить 2 оптимальных значения параметра K с помощью кросс-валидации (K∈{1,3,5,7,9,11,13,15}) и рассчитать для них величины ошибки классификации.