J'essaie de faire un CV k-fold pour plusieurs méthodes de classification/paramètres hiper en utilisant les données disponibles sur
Cet ensemble est composé de 208 lignes, chacune avec 60 attributs. Je le lis dans un data.frame en utilisant la fonction read.table.
L'étape suivante consiste à diviser mes données en k plis, disons k = 5. Ma première tentative a été d'utiliser
test <- createFolds (t, k = 5)
J'ai eu deux problèmes avec cela. La première est que les longueurs des plis ne sont pas côte à côte:
Length Class Mode
Fold1 29 -none- numérique
Fold2 14 -aucun- numérique
Fold3 7 -aucun- numérique
Fold4 5 -aucun- numérique
Fold5 5 -aucun- numérique
L'autre est que cela a apparemment divisé mes données en fonction des index d'attributs, mais je veux diviser les données elles-mêmes. J'ai pensé qu'en transposant mon data.frame, en utilisant:
test <- t (myDataNumericValues)
Mais quand j'appelle la fonction createFolds, cela me donne quelque chose comme ceci:
Length Class Mode
Fold1 2496 -aucun- numérique
Fold2 2496 -aucun- numérique
Fold3 2495 -aucun- numérique
Fold4 2496 -aucun- numérique
Fold5 2497 -aucun- numérique
Le problème de longueur a été résolu, mais il ne divise toujours pas mes 208 données en conséquence.
Avez-vous des réflexions sur ce que je peux faire? Pensez-vous que le package caret n'est pas le plus approprié?
Merci d'avance
Lisez s'il vous plaît ?createFolds
pour comprendre ce que fait la fonction. Il crée les indices qui définissent quelles données sont tenues les plis séparés (voir les options pour retourner l'inverse):
> library(caret)
> library(mlbench)
> data(Sonar)
>
> folds <- createFolds(Sonar$Class)
> str(folds)
List of 10
$ Fold01: int [1:21] 25 39 58 63 69 73 80 85 90 95 ...
$ Fold02: int [1:21] 19 21 42 48 52 66 72 81 88 89 ...
$ Fold03: int [1:21] 4 5 17 34 35 47 54 68 86 100 ...
$ Fold04: int [1:21] 2 6 22 29 32 40 60 65 67 92 ...
$ Fold05: int [1:20] 3 14 36 41 45 75 78 84 94 104 ...
$ Fold06: int [1:21] 10 11 24 33 43 46 50 55 56 97 ...
$ Fold07: int [1:21] 1 7 8 20 23 28 31 44 71 76 ...
$ Fold08: int [1:20] 16 18 26 27 38 57 77 79 91 99 ...
$ Fold09: int [1:21] 13 15 30 37 49 53 74 83 93 96 ...
$ Fold10: int [1:21] 9 12 51 59 61 62 64 70 82 87 ...
Pour les utiliser pour diviser les données:
> split_up <- lapply(folds, function(ind, dat) dat[ind,], dat = Sonar)
> dim(Sonar)
[1] 208 61
> unlist(lapply(split_up, nrow))
Fold01 Fold02 Fold03 Fold04 Fold05 Fold06 Fold07 Fold08 Fold09 Fold10
21 21 21 21 20 21 21 20 21 21
La fonction train
est utilisée dans ce paquet pour faire la modélisation réelle (vous n'avez généralement pas besoin de faire le fractionnement vous-même. Voir cette page ).
Max
Je ne suis pas familier avec le package caret
, mais j'avais l'habitude d'écrire une fonction calculant le CV basé sur l'arbre de décision du package rpart
. Bien sûr, la fonction doit être motivée pour répondre à votre objectif.
CV <- function(form, x, fold = 10, cp = 0.01) {
# x is the data
n <- nrow(x)
prop <- n%/%fold
set.seed(7)
newseq <- rank(runif(n))
k <- as.factor((newseq - 1)%/%prop + 1)
y <- unlist(strsplit(as.character(form), " "))[2]
vec.accuracy <- vector(length = fold)
for (i in seq(fold)) {
# It depends on which classification method you use
fit <- rpart(form, data = x[k != i, ], method = "class")
fit.Prune <- Prune(fit, cp = cp)
fcast <- predict(fit.Prune, newdata = x[k == i, ], type = "class")
cm <- table(x[k == i, y], fcast)
accuracy <- (cm[1, 1] + cm[2, 2])/sum(cm)
vec.accuracy[i] <- accuracy
}
avg.accuracy <- mean(vec.accuracy)
avg.error <- 1 - avg.accuracy
cv <- data.frame(Accuracy = avg.accuracy, Error = avg.error)
return(cv)
}