Как функция 'rpart' выполняет перекрестную проверку (вычисление xstd)? - PullRequest
0 голосов
/ 04 ноября 2019

Я пытаюсь понять и объяснить некоторые значения rpart :: rpart с помощью RStudio. Я работаю над "spambase" (двоичный классификатор).

У меня есть сомнения по поводу перекрестной проверки и специально для "xstd".

Я создал код, который возвращает информационную матрицу следующим образом:

         xerror    xstd       cp
nsplit.0 0.5183012 0.02345902 0.48651079
nsplit.1 0.3893216 0.02933012 0.14298561

Я хочу объяснить результат вывода cptable моего дерева по умолчанию "arbre0".

Я хочу смоделировать «cptable», я имею в виду, что для каждого значения cp я делаю перекрестную проверку на деревьях, размер которых определяется cp.

1: я делаю перекрестную проверку с помощью "блока" (K = 10)2: я создаю дерево rpart3: я вычисляю класс ошибки с помощью функции предиката ()4: xerror = среднее (ошибка) для каждого блока K = i (это хорошо выглядит) 5: xstd = sd (вектор ошибки) / sqrt (длина (ошибка) -1)

Я действительно не нахожу значения для xstd, и я не знаю, как rpart вычисляет его.

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

Никто в интернете не объясняет простую формулу для вычисления xstd ...

мой код:

arbre0 = rpart(DATASET.train$spam~.,data=DATASET.train)
arbre0$cptable

#   CP         nsplit rel error xerror    xstd
# 1 0.49551020      0 1.0000000 1.0000000 0.02214215
# 2 0.13795918      1 0.5044898 0.5257143 0.01841309
# 3 0.05142857      2 0.3665306 0.3877551 0.01635578
# 4 0.03265306      3 0.3151020 0.3216327 0.01512706
# 5 0.03102041      4 0.2824490 0.3069388 0.01482715
# 6 0.01000000      5 0.2514286 0.2718367 0.01406463

#init 
n=dim(DATASET.train)[1]
K=10 # nombres de blocs de la c.v
size=n%/%K  # taille des blocs en nombre entier
Ind=rep(1:K,size)
set.seed(50)
block=sample(Ind,length(Ind),rep=F)
block=as.factor(block) # permet de nommer facilement les blocs

Y.pos = table(DATASET.train$spam)["1"]/length(DATASET.train$spam)
res=c()
#summary(block)
for(j in 1:(length(arbre0$cptable[,1])-1) ) #la ligne du dernier cp n'est pas executée
{

 # Début de la c.v
 err=c();cp.x=matrix(nrow = 10,byrow = T) # vecteur des erreurs

 for(i in 1:K) { 
  #pour obtenir le cp de chaque split
  set.seed(50)
  treecp= rpart(DATASET.train[block!=i,]$spam~ ., data=DATASET.train[block!=i,], 
                method="class") 

   #if(length(treecp$cptable[,1])==6){
    # apprentissage sur le complémentaire du bloc 
    set.seed(50)
    tree= rpart(DATASET.train[block!=i,]$spam~ ., data=DATASET.train[block!=i,], method="class",
                control=rpart.control(cp=treecp$cptable[j,1] -0.001   )) #-0.001 pour ne pas avoir le root 

    pred= predict(tree,newdata=DATASET.train[block==i,],type="class") # prediction sur le bloc

    mc<-table(DATASET.train$spam[block==i],pred)
    err[i]=((mc[2,1]+mc[1,2])/sum(mc))
    #cp.x = cbind(cp.x, treecp$cptable[,1])
   #}


 }
 err=err  /Y.pos #toujours en % par rapport au % des mal classés du root, d'où la division par Y.pos
 xerror = mean(err, na.rm = T)  # xerror 
 xstd = sd(err, na.rm = T) / sqrt((length(is.na(err)==F)-1))   # xstd  
 print(err)#;print(cp.x)
 res=rbind(res, xerror, xstd, treecp$cptable[j,1])

}
res=matrix(res, ncol=3, byrow=T)
data.frame(xerror=res[,1], xstd=res[,2], cp=res[,3], 
           row.names = paste0("nsplit.",treecp$cptable[1:j,2]))

Проблема с кулаком, я хочу вывести cp, но у меня переменный размердеревья для подвыборки ... (не самое главное)ксеррор выглядит хорошоxstd не похож на вывод моего дерева "arbre0"

Если кто-то уже вычислил xstd для дерева rpart (случай классификации), мне нужна помощь.

Спасибо.

PS:

Я уже видел некоторые документы:https://cran.r -project.org / веб / пакеты / rpart / rpart.pdf https://cran.r -project.org / веб / пакеты / rpart / виньетки / longintro.pdf https://github.com/cran/rpart/blob/master/src/xval.c

...