Подготовка к работе

Значение параметра S = 51

Загружаем таблицу

load("F://ML/ML Block 6/РК2/df.rda")
df=samsungData

Формируем случайную выборку случайного размера из исходной таблицы df.

set.seed(51) 
n <- 4000+sample(nrow(df)-4000,1) 
set.seed(51) 
rand_sample=df[sample(nrow(df), n), ]

Задание 1.1

Определить размер выборки, количество переменных, типы переменных, наличие факторов(категориальных признаков) и пропущенных значений

str(rand_sample,list.len=0)
## 'data.frame':    6602 obs. of  561 variables:
##   [list output truncated]
#проверим количество не пропущенных значений в выборке
length_s=length(complete.cases(rand_sample))
length_s
## [1] 6602
#проверим, какие переменные в таблице - факторы
l=lapply(rand_sample, is.factor)
tail(l,n = 6L)
## $X556
## [1] FALSE
## 
## $X557
## [1] FALSE
## 
## $X558
## [1] FALSE
## 
## $X559
## [1] FALSE
## 
## $id
## [1] TRUE
## 
## $state
## [1] TRUE

Выборка состоит из 6602 наблюдений, 561 переменных, числовых (целочисленных и вещественных) и факторов(id и state), для удобства представления не вывожу в отчете полный список описания переменных. Пропущенные значения отсутствуют.

Задание 1.2

При наличии категориальных признаков следует изменить тип соответствующих столбцов таблицы на factor, указав все предусмотренные уровни факторов

str(rand_sample[,560:561])
## 'data.frame':    6602 obs. of  2 variables:
##  $ id   : Factor w/ 21 levels "1","3","5","6",..: 17 5 7 21 5 18 17 10 21 3 ...
##  $ state: Factor w/ 6 levels "laying","sitting",..: 3 6 6 1 5 1 2 4 6 6 ...
factor_id=rand_sample$id
levels(factor_id)
##  [1] "1"  "3"  "5"  "6"  "7"  "8"  "11" "14" "15" "16" "17" "19" "21" "22"
## [15] "23" "25" "26" "27" "28" "29" "30"
factor_state=rand_sample$state
levels(factor_state)
## [1] "laying"   "sitting"  "standing" "walk"     "walkdown" "walkup"

Тип столбцов и уровни факторов даны изначально.

Задание 1.3

Построить таблицу распределения числа наблюдений по испытуемым

table(rand_sample$id)
## 
##   1   3   5   6   7   8  11  14  15  16  17  19  21  22  23  25  26  27 
## 321 303 276 296 275 254 280 295 295 323 334 323 370 286 320 374 347 329 
##  28  29  30 
## 353 306 342

Задание 1.4

Построить таблицу распределения числа наблюдений по состояниям

table(rand_sample$state)
## 
##   laying  sitting standing     walk walkdown   walkup 
##     1264     1168     1233     1085      902      950

Задание 1.5

С помощью функции table(x, y) построить таблицу, содержащую в ячейках число наблюдений для соответствующего пользователя (x) и соответствующего состояния (y).

table(rand_sample$id, rand_sample$state)
##     
##      laying sitting standing walk walkdown walkup
##   1      46      40       52   86       46     51
##   3      56      46       53   53       46     49
##   5      49      42       52   50       42     41
##   6      51      51       52   55       43     44
##   7      49      42       47   51       44     42
##   8      51      41       49   41       36     36
##   11     52      52       41   46       42     47
##   14     47      49       51   54       43     51
##   15     69      55       44   51       38     38
##   16     63      58       67   46       43     46
##   17     67      60       74   51       42     40
##   19     79      63       68   42       33     38
##   21     78      81       81   43       43     44
##   22     63      59       54   44       31     35
##   23     58      60       59   53       45     45
##   25     69      58       64   68       54     61
##   26     65      70       67   50       46     49
##   27     60      62       72   50       39     46
##   28     75      66       74   51       45     42
##   29     58      56       59   44       44     45
##   30     59      57       53   56       57     60

Задание 2

Разделить выборку на равные по длине обучающее dft и контрольное dfc подмножества

library(caret)
inTrain = createDataPartition(y = rand_sample$state,p = 0.5,list=F)
dft=rand_sample[inTrain,] 
dfc =rand_sample[-inTrain,] 

Задание 3

Предварительно удалив из таблицы переменную id, с помощью функции tree(state~.,data=dft, split = “gini”, mincut=10) построить дерево классификации tr1. При возникновении ошибки вида «maximum depth reached» следует немного увеличить значение параметра mincut

library(tree)
#удаляем стобец, содержащий id
rand_sample2 = rand_sample[,-560]

#строим дерево классификаций
tr1=tree(rand_sample2$state~., data=rand_sample2, split="gini", mincut=13)
plot(tr1)
text(tr1, cex=0.4)

Дерево глубоко уходит, однако чем глубже уходит дерево, тем дольше требуется времени для поиска ответа. Видно что дерево разбивается по переменной х65, зачем х64 и х536 тд

Задание 4

Изучить качество полученного дерева tr1 и определить долю ошибок предсказания на обучающей и контрольной выборке.

summary(tr1)
## 
## Classification tree:
## tree(formula = rand_sample2$state ~ ., data = rand_sample2, split = "gini", 
##     mincut = 13)
## Variables actually used in tree construction:
##  [1] "X65"  "X64"  "X447" "X536" "X449" "X293" "X292" "X366" "X367" "X548"
## [11] "X288" "X370" "X448" "X368" "X501" "X1"   "X4"   "X296" "X523" "X43" 
## [21] "X365" "X549" "X291" "X369" "X110" "X52"  "X510" "X134" "X154" "X118"
## [31] "X75"  "X38"  "X63"  "X103" "X77"  "X14"  "X25"  "X156" "X264" "X33" 
## [41] "X173" "X94"  "X70"  "X71"  "X120" "X15"  "X46"  "X28"  "X42"  "X257"
## [51] "X238" "X522" "X509" "X446" "X445" "X74"  "X10"  "X37"  "X148" "X194"
## [61] "X41"  "X124" "X130" "X112" "X175" "X557" "X51"  "X164" "X79"  "X13" 
## [71] "X3"   "X93"  "X34"  "X23"  "X123" "X203" "X558" "X7"   "X30"  "X432"
## [81] "X36"  "X188" "X2"  
## Number of terminal nodes:  327 
## Residual mean deviance:  1.396 = 8762 / 6275 
## Misclassification error rate: 0.3096 = 2044 / 6602

Изучая качество дерева, видно по каким переменным было осуществлено разбиение. Дерево состоит из 327 узлов, процент ошибки на обучающей выборке равен 0,3096.

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

error <- function(a, b)
{
  p = predict(a, b); 
  length_s=length(b$state); 
  predicts = vector(); 
  for (i in 1:length_s){
    p1=max(p[i,])
    predicts=append(predicts,names(which(p[i,]==p1)[1]))
    } 
  print( 1-(sum(predicts == b$state))/length_s) 
}
print("Ошибка классификации на обучающей выборке:")
## [1] "Ошибка классификации на обучающей выборке:"
error(tr1, dft)
## [1] 0.3019382
print("Ошибка классификации на контрольной выборке:")
## [1] "Ошибка классификации на контрольной выборке:"
error(tr1, dfc)
## [1] 0.3172727

Задание 5

С помощью функции cv.tree(tr1, K = 10, method = “misclass”) методом 10-кратного скользящего контроля получить список trees2, содержащий ошибки классификации (свойство dev) для разных размеров дерева (свойство size)

trees2 = cv.tree(tr1, K = 10, method = "misclass")
trees2
## $size
##  [1] 327 258 252 238 214 211 201 193 190 184 177 173 155 149 135 133 126
## [18] 117 114 108 106 102 100  94  90  78  71  68  66  64  61  58  53  51
## [35]  48  46  45  43  42  39  38  35  34  31  30  21  19  15  11   7   6
## [52]   4   2   1
## 
## $dev
##  [1] 678 678 678 678 678 678 678 678 678 678 678 678 678 678 678 678 678
## [18] 678 678 678 678 678 678 678 678 678 678 678 678 678 678 678 678 678
## [35] 678 678 678 678 674 674 674 674 674 678 678 678 678 678 678 723 771
## [52] 808 817 817
## 
## $k
##  [1]        -Inf   0.0000000   0.3333333   0.5000000   1.0000000
##  [6]   1.3333333   1.5000000   2.0000000   2.3333333   2.5000000
## [11]   3.0000000   3.2500000   3.3888889   3.5000000   4.0000000
## [16]   4.5000000   5.0000000   5.2222222   5.3333333   5.5000000
## [21]   6.0000000   6.2500000   6.5000000   7.0000000   7.7500000
## [26]   8.0000000   8.1428571   8.6666667   9.0000000   9.5000000
## [31]  10.0000000  11.0000000  12.0000000  13.0000000  14.3333333
## [36]  18.0000000  19.0000000  20.0000000  22.0000000  22.3333333
## [41]  23.0000000  23.3333333  24.0000000  30.3333333  31.0000000
## [46]  31.2222222  32.0000000  34.5000000  35.5000000  51.7500000
## [51]  87.0000000 121.5000000 210.0000000 356.0000000
## 
## $method
## [1] "misclass"
## 
## attr(,"class")
## [1] "prune"         "tree.sequence"
plot(trees2$size,trees2$dev,type="l",xlim=c(0,100))

Задание 6

Определить «на глаз» размер MinTreeSize1 оптимального поддерева дерева tr1, изучив график зависимости ошибки классификации от размера поддерева

Изучая график можно предположить, что рекомендуем размер должен быть = 45

MinTreeSize1=45

Задание 7

Реализовать с использованием списка trees2 нахождение минимального размера MinTreeSize2 дерева tr1, при котором достигается наименьшая величина ошибки предсказания dev.

MinTreeSize2 = min(trees2$size[which(trees2$dev == min(trees2$dev))])
MinTreeSize2
## [1] 34

Задание 8

** С помощью функции cv.tree, указав оптимальный размер (best = MinTreeSize1) дерева, построить это дерево и сохранить в виде объекта tr2**

tr2=cv.tree(tr1, best = MinTreeSize1)
plot(tr2)
text(tr2, cex=0.4)

Задание 9

** С помощью функции cv.tree, указав оптимальный размер (best = MinTreeSize2) дерева, построить это дерево и сохранить в виде объекта tr3. **

tr3 = cv.tree(tr1, best = MinTreeSize2)
plot(tr3)
text(tr3, cex=0.4)

Задание 10

** С помощью функции prune.tree оценить доли ошибок классификации, допускаемых деревьями tr2 и tr3 на обучающей и контрольной выборках **

print("Ошибка классификации tr2 на обучающей выборке:")
## [1] "Ошибка классификации tr2 на обучающей выборке:"
err1t=error(tr2, dft )
## [1] 0.4479104
print("Ошибка классификации tr2 на контрольной выборке:")
## [1] "Ошибка классификации tr2 на контрольной выборке:"
err1c=error(tr2, dfc )
## [1] 0.4833333
print("Ошибка классификации tr3 на обучающей выборке:")
## [1] "Ошибка классификации tr3 на обучающей выборке:"
err2t=error(tr3, dft )
## [1] 0.484252
print("Ошибка классификации tr3 на контрольной выборке:")
## [1] "Ошибка классификации tr3 на контрольной выборке:"
err2c=error(tr3, dfc )
## [1] 0.5087879

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

Используя классификацию при помощи поддеревьев можно заметить, что рост ошибки классификации на контроле растут. Поэтому, можно сделать вывод, что лучшим деревом является - tr1, так как ошибка на контрольной выборке меньше.