{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE)
iris.df <- data.frame(iris)
sample.index <- sample(1:nrow(iris.df), nrow(iris) * 0.75, replace = FALSE)
head(iris[sample.index, ])
summary(iris)
Este fragmento de código hace una muestra aleatoria simple del
conjunto de datos de iris generando primero los índices
mediante los cuales necesita subconjuntos de los datos de
iris. En este caso, seleccionamos al azar cinco filas de
los datos sin reemplazo. Replacement es una opción que si se tiene
activa, va a permitir que al extraer una fila de datos, tendrá la opción
de extraerla nuevamente. De forma predeterminada, esta opción está
desactivada en la función sample() en R, como es el caso de
la mayoría de las funciones de muestreo que se ven en el mundo de la
programación.
Veamos cómo hacer un muestreo estratificado en R. En contraste a
una muestra aleatoria simple, el muestreo estratificado se puede
realizar sobre diferentes características en el conjunto de datos.
Ampliemos esto observando las distribuciones de datos en el conjunto de
datos iris:
summary(iris[sample.index, ])
Este fragmento de código hace una muestra aleatoria simple del
conjunto de datos de iris generando primero los índices
mediante los cuales necesita subconjuntos de los datos de
iris. En este caso, seleccionamos al azar cinco filas de
los datos sin reemplazo. Replacement es una opción que si se tiene
activa, va a permitir que al extraer una fila de datos, tendrá la opción
de extraerla nuevamente. De forma predeterminada, esta opción está
desactivada en la función sample() en R, como es el caso de
la mayoría de las funciones de muestreo que se ven en el mundo de la
programación.
Veamos cómo hacer un muestreo estratificado en R. En contraste a
una muestra aleatoria simple, el muestreo estratificado se puede
realizar sobre diferentes características en el conjunto de datos.
Ampliemos esto observando las distribuciones de datos en el conjunto de
datos iris:
library('MASS')
library(splitstackshape)
summary(stratified(iris.df, "Sepal.Length", 0.7)
Aquí puede ver la población de los datos. Pretendemos obtener una
muestra que tenga aproximadamente la misma distribución de valores para
cualquiera de estas características. Note que algunas de esas columnas
varían en un grado más alto que otras. En este caso,
Petal.Length tiene la mayor cantidad de variación, seguido
por Sepal.Length. Tenga esto en cuenta para el ejercicio de
muestreo estratificado, por ahora hagamos una muestra aleatoria simple
solo con los valores de Sepal.Length:
summary(iris[sample.index, ])
Este ejemplo toma una muestra del 75% de los datos originales, y se
puede ver que las distribuciones están bastante cerca de los valores de
la población principal. Probemos ahora el muestreo estratificado. Para
esto, necesita el paquete splitstackshape y la función
stratified() así:
library('MASS')
library(splitstackshape)
summary(stratified(iris.df, "Sepal.Length", 0.7))
La muestra estratificada tiene los mismos valores aproximadamente.
Realizamos un muestreo estratificado de los datos de iris
utilizando la función estratified(), centrándonos
específicamente en los estratos de Sepal.Length. Luego, el
código solicita una muestra del 70%.
Sin embargo, con el muestreo estratificado, puede especificar sobre
qué estrato particular desea hacer el muestreo. Si está muestreando
muchos estratos, generalmente querrá comenzar con las características
que varían menos y luego avanzar con las que más varían. Las
características con la variación más baja en el conjunto de datos de
iris son Sepal.Width y
Petal.Width, así que comencemos con esas:
summary(stratified(iris, c("Sepal.Width", "Petal.Width"), 0.7))
Puede ver en el resultado que el muestreo estratificado con múltiples
grupos todavía tiene una buena representación de los datos de población
(es decir, el conjunto de datos de iris completo) con el
que comenzó. Las medias y las variaciones parecen bastante apropiadas
para una muestra.
Para el muestreo sistemático, puede escribir una función simple que seleccione cada enésima fila secuencialmente dado un número de inicialización aleatorio:
sys.sample = function(N, n) {
k = ceiling(N/n)
r = sample(1:k, 1)
sys.samp = seq(r, r + k * (n - 1), k)
}
systematic.index <- sys.sample(nrow(iris), nrow(iris) * 0.75)
summary(iris[systematic.index, ])
Este fragmento de código define la función de muestreo sistemático y
luego la ejecuta en los datos de iris. Para este ejemplo,
ejecutamos dando el número de filas para el cual podemos obtener índices
específicos, pero los resultados se ven bastante similares a lo que se
han visto hasta ahora.
Para comprobar la ventaja de hacer muestreo estratificado, simulamos una población con cinco estratos, bajo el supuesto de que cada estrato tiene un tamaño distinto y distintos valores medios y varianzas.
nis=c(1000,2000,5000,8000,10000)
mu=c(25,35,50,10,20)
sigma=c(4,6,8,2,3)
#mu=c(25,25,25,25,25)
#sigma=c(8,8,8,8,8)
estrato=list(
e1=rnorm(nis[1],mu[1],sigma[1]),
e2=rnorm(nis[2],mu[2],sigma[2]),
e3=rnorm(nis[3],mu[3],sigma[3]),
e4=rnorm(nis[4],mu[4],sigma[4]),
e5=rnorm(nis[5],mu[5],sigma[5]))
poblacion=unlist(estrato)
Mostramos el tamaño de la población, así como su media y desviación típica:
N=sum(nis)
mu.pob=mean(poblacion)
sigma.pob=sd(poblacion)
N
mu.pob
sigma.pob
Buscamos en primer lugar el tamaño óptimo para estimar μ con una precisión de 0.5 unidades y confianza 0.95 si se lleva a cabo un muestreo aleatorio simple.
La siguiente función permite calcular el tamaño de muestra necesario si se lleva a cabo un muestreo aleatorio simple:
tam.muestra=function(alfa,epsilon,s,N=Inf)
{
za2=qnorm(1-alfa/2)
if (N==Inf) n=(s*za2/epsilon)^2
else n=N*((za2*s)^2)/((N-1)*epsilon^2+(za2*s)^2)
return(ceiling(n))
}
Utilizaremos esta función para determinar el tamaño de muestra para estimar la media de la población anterior mediante muestreo aleatorio simple sin tener en cuenta la estratificación presente en la población.
Primero se extrae una pequeña muestra para estimar sigma (que no se conoce):
n.piloto=10
muestra.piloto=sample(poblacion, size=n.piloto, replace=F)
s=sd(muestra.piloto)
muestra.piloto
s
Con ese valor piloto determinamos el tamaño de muestra requerido para un muestreo aleatorio simple:
alfa=0.05
epsilon=0.5
n.pobfin=tam.muestra(alfa,epsilon,s,N=N)
n.pobinf=tam.muestra(alfa,epsilon,s)
n.pobfin
n.pobinf
Se saca una muestra de ese tamaño y se estima la media:
n=n.pobfin
muestra=sample(poblacion, size=n, replace=T)
mu.est=mean(muestra)
za2=qnorm(1-alfa/2)
errtip=(sd(muestra)/sqrt(n))*sqrt(1-n/N)
intervalo.mu=mu.est+c(-1,1)*za2*errtip
Se muestran el tamaño muestral utilizado, y la media y el intervalo de confianza obtenidos:
n
mu.est
intervalo.mu
Iteramos este proceso nsim veces y contamos cuántos intervalos contienen a la media
nsim=10000
nc=0
fc=sqrt(1-n/N)
for (i in 1:nsim)
{
muestra=sample(poblacion, size=n)
mu.est=mean(muestra)
intervalo.mu=mu.est+c(-1,1)*za2*(sd(muestra)/sqrt(n))*fc
if ((mu.pob>=intervalo.mu[1])&(mu.pob<=intervalo.mu[2])) nc=nc+1
}
nc
nc/nsim
sí pues, podemos confirmar que el muestreo aleatorio simple consigue estimar la media de la población con la confianza (0.95) y precisión (0.5) requeridas. Ahora bien, ello ha requerido el esfuerzo de tomar una muestra de tamaño
Ejemplo: Tamaño muestral con muestreo aleatorio estratificado
Repetimos el ejercicio anterior, pero ahora con muestreo estratificado.
Para ello se requiere una estimación piloto de la varianza en cada estrato:
s2=rep(0,5)
for (j in 1:5)
{
n.piloto=10
muestra.piloto=sample(estrato[[j]], size=n.piloto, replace=F)
s2[j]=var(muestra.piloto)
}
s2
Para calcular el tamaño de muestra en cada estrato, en primer lugar construimos una función para ello:
La función recibe como argumentos los valores del error máximo a cometer, la confianza, las ϕ, las si, el tipo de afijación a realizar (1: uniforme, 2:proporcional, 3:óptima) y el tamaño N de la población.
Como resultado, la función devuelve el tamaño muestral en cada estrato.
nMuestreoEstratificado=function(epsilon,confianza,phi,s,afijacion=3,N=inf){
K=length(phi) # Número de estratos
alfa=1-confianza
za=qnorm(1-alfa/2)
w=if (afijacion==1) rep(1/K,K) else if (afijacion==2) phi else phi*s/sum(phi*s)
if (N!=Inf) n=sum(phi^2*s^2/w)/((epsilon/za)^2+(1/N)*sum(phi*s^2))
else n=(za/epsilon)^2*sum(phi^2*s^2/w)
ni=ceiling(n*w)
return(ni)
}
Aplicamos ahora nuestra función para el cálculo del tamaño muestral en cada estrato del ejemplo anterior.
Utilizando afijación uniforme:
niUnif=nMuestreoEstratificado(epsilon=0.5,confianza=0.95,phi=nis/N,s=sqrt(s2),afijacion=1,N=N)
niUnif
sum(niUnif)
Utilizando afijación proporcional:
niProp=nMuestreoEstratificado(epsilon=0.5,confianza=0.95,p=nis/N,s=sqrt(s2),afijacion=2,N=N)
niProp
sum(niProp)
Utilizando afijación óptima:
niOpt=nMuestreoEstratificado(epsilon=0.5,confianza=0.95,p=nis/N,s=sqrt(s2),afijacion=3,N=N)
niOpt
sum(niOpt)