¿Cómo dividir automáticamente una matriz usando R para 5 veces la validación cruzada? En realidad, quiero generar los 5 conjuntos de (test_matrix_indices, train matrix_indices).Generar conjuntos para la validación cruzada
Respuesta
f_K_fold <- function(Nobs,K=5){
rs <- runif(Nobs)
id <- seq(Nobs)[order(rs)]
k <- as.integer(Nobs*seq(1,K-1)/K)
k <- matrix(c(0,rep(k,each=2),Nobs),ncol=2,byrow=TRUE)
k[,1] <- k[,1]+1
l <- lapply(seq.int(K),function(x,k,d)
list(train=d[!(seq(d) %in% seq(k[x,1],k[x,2]))],
test=d[seq(k[x,1],k[x,2])]),k=k,d=id)
return(l)
}
Supongo que quiere que las filas de la matriz sean los casos para dividir. Entonces todo lo que necesita es sample
y split
:
X <- matrix(rnorm(1000),ncol=5)
id <- sample(1:5,nrow(X),replace=TRUE)
ListX <- split(x,id) # gives you a list with the 5 matrices
X[id==2,] # gives you the second matrix
que trabajaría con la lista, ya que le permite hacer algo como:
names(ListX) <- c("Train1","Train2","Train3","Test1","Test2")
mean(ListX$Train3)
que lo convierte en código que es más fácil de leer, y le impide crear toneladas de matrices en su espacio de trabajo. Es inevitable que se equivoque si coloca las matrices individualmente en su área de trabajo. Use listas!
En caso de que quiera la matriz de prueba sea menor o mayor que los demás, utiliza el argumento prob
de sample
:
id <- sample(1:5,nrow(X),replace=TRUE,prob=c(0.15,0.15,0.15,0.15,0.3))
le da una matriz de prueba que es el doble del tamaño de las matrices de tren.
En caso de que quiera determinar el número exacto de casos, sample
y prob
no son las mejores opciones. Puede usar un truco como:
indices <- rep(1:5,c(100,20,20,20,40))
id <- sample(indices)
para obtener matrices con respectivamente 100, 20, ... y 40 casos.
+1 por división: en realidad, me he estado preguntando acerca de cómo generar matrices para la validación cruzada, y esto es perfecto. – richiemorrisroe
joris gran código gracias. ¿No es la idea con la validación cruzada que recorre todos los conjuntos y utiliza cada grupo como datos de prueba al menos una vez, lo que frustraría el propósito de usar la lista y nombrarla como usted? – appleLover
@appleLover El uso de listas es meramente para evitar tener que generar matrices individuales en su espacio de trabajo. Es para mantener todo unido. Existen múltiples enfoques para la validación cruzada y el arranque, y dependiendo del enfoque necesitará diferentes correcciones en sus estadísticas. Acabo de dar un método para crear esas matrices de una manera organizada. –
solución sin dividir:
set.seed(7402313)
X <- matrix(rnorm(999), ncol=3)
k <- 5 # number of folds
# Generating random indices
id <- sample(rep(seq_len(k), length.out=nrow(X)))
table(id)
# 1 2 3 4 5
# 67 67 67 66 66
# lapply over them:
indicies <- lapply(seq_len(k), function(a) list(
test_matrix_indices = which(id==a),
train_matrix_indices = which(id!=a)
))
str(indicies)
# List of 5
# $ :List of 2
# ..$ test_matrix_indices : int [1:67] 12 13 14 17 18 20 23 28 41 45 ...
# ..$ train_matrix_indices: int [1:266] 1 2 3 4 5 6 7 8 9 10 ...
# $ :List of 2
# ..$ test_matrix_indices : int [1:67] 4 19 31 36 47 53 58 67 83 89 ...
# ..$ train_matrix_indices: int [1:266] 1 2 3 5 6 7 8 9 10 11 ...
# $ :List of 2
# ..$ test_matrix_indices : int [1:67] 5 8 9 30 32 35 37 56 59 60 ...
# ..$ train_matrix_indices: int [1:266] 1 2 3 4 6 7 10 11 12 13 ...
# $ :List of 2
# ..$ test_matrix_indices : int [1:66] 1 2 3 6 21 24 27 29 33 34 ...
# ..$ train_matrix_indices: int [1:267] 4 5 7 8 9 10 11 12 13 14 ...
# $ :List of 2
# ..$ test_matrix_indices : int [1:66] 7 10 11 15 16 22 25 26 40 42 ...
# ..$ train_matrix_indices: int [1:267] 1 2 3 4 5 6 8 9 12 13 ...
Pero se puede devolver matrices también:
matrices <- lapply(seq_len(k), function(a) list(
test_matrix = X[id==a, ],
train_matrix = X[id!=a, ]
))
str(matrices)
List of 5
# $ :List of 2
# ..$ test_matrix : num [1:67, 1:3] -1.0132 -1.3657 -0.3495 0.6664 0.0762 ...
# ..$ train_matrix: num [1:266, 1:3] -0.65 0.797 0.689 0.484 0.682 ...
# $ :List of 2
# ..$ test_matrix : num [1:67, 1:3] 0.484 0.418 -0.622 0.996 0.414 ...
# ..$ train_matrix: num [1:266, 1:3] -0.65 0.797 0.689 0.682 0.186 ...
# $ :List of 2
# ..$ test_matrix : num [1:67, 1:3] 0.682 0.812 -1.111 -0.467 0.37 ...
# ..$ train_matrix: num [1:266, 1:3] -0.65 0.797 0.689 0.484 0.186 ...
# $ :List of 2
# ..$ test_matrix : num [1:66, 1:3] -0.65 0.797 0.689 0.186 -1.398 ...
# ..$ train_matrix: num [1:267, 1:3] 0.484 0.682 0.473 0.812 -1.111 ...
# $ :List of 2
# ..$ test_matrix : num [1:66, 1:3] 0.473 0.212 -2.175 -0.746 1.707 ...
# ..$ train_matrix: num [1:267, 1:3] -0.65 0.797 0.689 0.484 0.682 ...
entonces se podría utilizar lapply
para obtener resultados:
lapply(matrices, function(x) {
m <- build_model(x$train_matrix)
performance(m, x$test_matrix)
})
Edición: comparar con Wojc La solución de IECH:
f_K_fold <- function(Nobs, K=5){
id <- sample(rep(seq.int(K), length.out=Nobs))
l <- lapply(seq.int(K), function(x) list(
train = which(x!=id),
test = which(x==id)
))
return(l)
}
Edit: Gracias por sus respuestas. he encontrado la siguiente solución (http://eric.univ-lyon2.fr/~ricco/tanagra/fichiers/fr_Tanagra_Validation_Croisee_Suite.pdf):
n <- nrow(mydata)
K <- 5
size <- n %/% K
set.seed(5)
rdm <- runif(n)
ranked <- rank(rdm)
block <- (ranked-1) %/% size+1
block <- as.factor(block)
Luego uso:
for (k in 1:K) {
matrix_train<-matrix[block!=k,]
matrix_test<-matrix[block==k,]
[Algorithm sequence]
}
para generar los conjuntos adecuados para cada iteración.
Sin embargo, esta solución puede omitir un individuo para las pruebas. No lo recomiendo.
A continuación se explica el truco sin tener que crear separadamente data.frames/matrices, todo lo que necesita hacer es mantener un entero sequnce, id
que almacena los índices mezclados para cada pliegue.
X <- read.csv('data.csv')
k = 5 # number of folds
fold_size <-nrow(X)/k
indices <- rep(1:k,rep(fold_size,k))
id <- sample(indices, replace = FALSE) # random draws without replacement
log_models <- new.env(hash=T, parent=emptyenv())
for (i in 1:k){
train <- X[id != i,]
test <- X[id == i,]
# run algorithm, e.g. logistic regression
log_models[[as.character(i)]] <- glm(outcome~., family="binomial", data=train)
}
Tenga en cuenta que cuando nrow (X) no es un múltiplo de k, algunas muestras se descartan. – Samuel
El paquete sperrorest
proporciona esta posibilidad. Puede elegir entre una división aleatoria (partition.cv()
), una división espacial (partition.kmeans()
) o una división basada en niveles de factor (partition.factor.cv()
). Actualmente, este último solo está disponible en la versión Github.
Ejemplo:
library(sperrorest)
data(ecuador)
## non-spatial cross-validation:
resamp <- partition.cv(ecuador, nfold = 5, repetition = 1:1)
# first repetition, second fold, test set indices:
idx <- resamp[['1']][[2]]$test
# test sample used in this particular repetition and fold:
ecuador[idx , ]
Si usted tiene un conjunto de datos espaciales (con coord), también se puede visualizar sus pliegues generados
# this may take some time...
plot(resamp, ecuador)
La validación cruzada puede ser entonces realizado usando sperrorest()
(secuencial) o parsperrorest()
(paralelo).
- 1. estratificado 10 veces la validación cruzada
- 2. validación cruzada en I
- 3. validación cruzada 10 veces
- 4. 10 * 10 veces la validación cruzada en scikit-learn?
- 5. matriz de confusión scikits con validación cruzada
- 6. Cómo dividir/particionar un conjunto de datos en conjuntos de datos de entrenamiento y prueba para, por ejemplo, validación cruzada?
- 7. Advertencia AL1073 al generar conjuntos de satélite
- 8. Ayuda Comprensión de validación cruzada y árboles de decisión
- 9. Carriles no generar mensajes de validación fallan
- 10. Valgrind compilación cruzada para ARMv5tel
- 11. compilación cruzada para el brazo
- 12. libsvm - Precisión de validación cruzada igual que la proporción de etiquetas
- 13. LibSVM: opción -wi (selección de peso) durante la validación cruzada y prueba
- 14. ¿Cómo usar la validación de Struts2 para la validación condicional?
- 15. ¿Cómo usar solo ciertos conjuntos de validación para validar datos en Cake PHP?
- 16. Normalización/validación para conjuntos de datos internacionales en una base de datos?
- 17. ¿Qué es la compilación cruzada?
- 18. Resolviendo un error 'modelo vacío' en la validación cruzada para la clasificación SVM cuando utilizo el paquete CMA Bioconductor para R
- 19. Sphinx: generar referencias automáticas para tickets y conjuntos de cambios Trac
- 20. Requerimientos de compilación cruzada para C
- 21. CMake add_custom_command/_target en diferentes directorios para la compilación cruzada
- 22. Mejores prácticas para la compilación cruzada .NET/MONO
- 23. ¿Manera cruzada del navegador para girar la imagen usando CSS?
- 24. Aplicaciones ocaml de compilación cruzada para ARM
- 25. módulo usb de plataforma cruzada para python?
- 26. Compilación cruzada en mac para Windows
- 27. algoritmo para generar diferentes órdenes
- 28. ¿Cómo se maneja la importación cruzada?
- 29. Conceptos básicos de la correlación cruzada normalizada
- 30. compilación cruzada con gyp
No mezcle las respuestas a su pregunta. Esto se vuelve confuso. Si quiere responder su propia pregunta, hágalo en una nueva respuesta. – Andrie
Para la validación cruzada en K, tiene que combinar subconjuntos K-1 como conjunto de entrenamiento y dejar uno como prueba (repetirlo K veces), por lo que esta no es una solución completa para su problema. –
He puesto mi respuesta en la sección de respuestas. – Delphine