Задание 1.

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

load("F://ML/РК4/Banknotes.rda

set.seed(451) 
n <- 800+sample(nrow(data)-800,1) 
set.seed(451) 
sample <- data[sample(nrow(data), n), ] 
str(sample)
## 'data.frame':    899 obs. of  5 variables:
##  $ V1: num  3.18 3.02 -3.15 2.69 -1.98 ...
##  $ V2: num  -5.28 -8.57 -1.72 4.66 4.3 ...
##  $ V3: num  5.08 9.45 1.9 -4.29 -1.02 ...
##  $ V4: num  1.006 -1.96 -3.856 -1.236 0.207 ...
##  $ V5: Factor w/ 2 levels "Original","Fake": 1 1 2 2 2 2 2 2 2 1 ...

Выборка состоит из 899 наблюдений,5 переменных. Дадим имена переменным исходя из их описания в тексте рубежного контроля №4

names(sample) <- c("dispersion","asymmetry","excess","entropy","fake")
hist(sample$dispersion)

hist(sample$asymmetry)

Распределения дисперсии и асиметрии близко к нормальному.

hist(sample$excess)

hist(sample$entropy)

Диапазоны для признаков различны.

pairs(data=sample, ~.,col=as.numeric(sample$fake))

Задание 2.

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

Нормализуем данные, вычитая среднее значение и делия на стандартное отклонение.

for (i in 1:4){
  sample[,i] = (sample[,i] - mean(sample[,i]))/sd(sample[,i])
}

Задание 3.

Разделить выборку your_data на равные по длине обучающее tr_set и контрольное val_set подмножества в пропорции 10 на 90%. Для разделения выборки рекомендуется использовать возможности функции rbinom(N, 1, p), где N – размер исходной выборки, p – доля наблюдений исходной выборки, выбираемых в обучающее множество, которая генерирует случайную последовательность нулей и единиц длины N, причём соотношение нулей и единиц соответствует параметру p. Полученную случайную последовательность можно использовать для выборки наблюдений в обучающую (единицы) и контрольную (нули) выборку.

dft_dfc = which(rbinom(nrow(sample),1,0.1) == 1)
tr_set = sample[dft_dfc,]
val_set = sample[-dft_dfc,]

Задание 4.

Написать функцию euclid(x1,x2) для оценки евклидового расстояния между двумя числовыми векторами x1 и x2 равной размерности.

euclid <- function(x1,x2) {
  sqrt(sum((x1-x2)^2))
}

Задание 5.

Написать функцию knn_estimate(xt, classes, K, query), которая, используя обучающую выборку xt (значений входных признаков) и вектор соответствующих значений классов объектов classes, позволяет получить классификацию запроса query (вектор значений входных признаков) методом K ближайших соседей: c помощью функции euclid() определяются расстояния от вектора query до каждого из наблюдений обучающей выборки; по полученным расстояниям находятся K наиболее близких к query наблюдений из обучающей выборки и определяются их классы (по номерам в исходной выборке); классификация осуществляется путём определения класса большинства ближайших соседей (предполагается, что K – нечётное).

knn_estimate <- function(xt,k,query)
{
  classes = c()
  len = nrow(xt)
  for (i in 1 : len)
  {
    classes= append(classes,euclid(xt[i,1:4],query))
  }
  names(classes) <- 1:len
  classes = sort(classes)
  nearby = xt[as.integer(names(classes[1:k])),]
  result_table = table(nearby[,5])
  names(result_table)[which(result_table == max(result_table))] 
}
knn_estimate(tr_set,1, 1:4)
## [1] "Original"

Задание 6.

Оценить долю ошибочных классификаций наблюдений из контрольной выборки для K=1,3,5.

err <- function(tr, val, k){
  len = nrow(val)
  rn = vector(length = len)
  for (i in 1:len){
  rn[i] = knn_estimate(tr, k, val[i,1:4])
  result_table = table(val[,5]==rn)
  }
  cat(c("Для K=",k))
  cat(c(" ошибка классификации = ",round(as.numeric(result_table[1]/len),4)*100,"% "))
  
}
err(tr_set, val_set, 1)
## Для K= 1 ошибка классификации =  21.58 %
err(tr_set, val_set, 3)
## Для K= 3 ошибка классификации =  17.58 %
err(tr_set, val_set, 5)
## Для K= 5 ошибка классификации =  16.36 %

Задание 7.

Определить 2 оптимальных значения параметра K с помощью кросс-валидации (K∈{1,3,5,7,9,11,13,15}) и рассчитать для них величины ошибки классификации.

library(caret)

crossvalidation <- function(data)
{
  indexes <- createDataPartition(data$fake,p=0.1,times=10,list=F)
  for (k in seq(1,15,2))
  {
    len=ncol(indexes)
    for (i in 1:len)
    {
      tr_set <- data[indexes[,i],]
      val_set <- data[-indexes[,i],]
      
    }
err(tr_set,val_set,k)
cat("\n")
  }
}

crossvalidation(sample)
## Для K= 1 ошибка классификации =  17.82 % 
## Для K= 3 ошибка классификации =  14.23 % 
## Для K= 5 ошибка классификации =  15.72 % 
## Для K= 7 ошибка классификации =  15.72 % 
## Для K= 9 ошибка классификации =  15.97 % 
## Для K= 11 ошибка классификации =  16.83 % 
## Для K= 13 ошибка классификации =  15.72 % 
## Для K= 15 ошибка классификации =  16.46 %

Из полученных значений оптимальными можно считать К=3 и К=5,7,13(процент ошибок одинаковый)