El proceso de simulación constituye una herramienta poderosa para la estadística que se pueden emplear para entender relaciones complejas y estimar valores difíciles de calcular directamente. Para entenderlo utilizaremos se plantean los siguientes problemas:
Se elige de forma aleatoria n puntos dentro del cuadrado . La probabilidad de que un punto esté dentro del círculo es igual a la fracción del área del cuadrado que abarca a este, la cual es π/4. Por tanto, se puede estimar el valor de π/4 al contar el número de puntos dentro del círculo, para obtener la estimación de π/4. De este último resultado se encontrar una aproximación para el valor de π.
Se genera la función create_sample la cual recibe como
parámetro n y genera una distribución uniforme de coordenadas usando
runif:
# Function to create a sample of coordinates
create_sample <- function(n) {
x <- runif(n)
y <- runif(n)
return(data.frame(x, y))
}
La función recibe el número de puntos a tomar, y devuelve un dataframe con dos columnas (x e y), las cuales contienen los puntos generados con la distribución uniforme.
Se usa la función create_sample pasando como parámetro
la cantidad de coordenadas deseadas, en este caso n = 1.000. Además, se
genera un seed para que los resultados pierdan
aleatoriedad.
# Generate a sample of coordinates
set.seed(1) # Set seed for reproducibility
n = 1000
sample <- create_sample(n)
Se usa la función center_distance para realizar el
cálculo por pitágoras para hallar la distancia del punto hasta el centro
del círculo de diámetro 1. La función se aplica al dataframe generado en
el paso anterior, el resultado es un vector de distancias, 1.000
distancias dado que es el número de n asignado.
# Function to calculate the distance from each point to the center
center_distance <- function(sample) {
return((sample$x - 0.5)^2 + (sample$y - 0.5)^2)
}
# Calculate distances to the center for each point
distances <- center_distance(sample)
points_in <- sum(distances < 0.25)
cat("cantidad de puntos dentro del círculo: ", points_in)
## cantidad de puntos dentro del círculo: 770
perc_points_in <- points_in/n
cat("Estimación de π para muestra con 1.000 puntos: ", perc_points_in)
## Estimación de π para muestra con 1.000 puntos: 0.77
perc_points_in <- points_in/n
cat("Valor real π: ", pi/4)
## Valor real π: 0.7853982
# Generate sample
n = 10000
sample <- create_sample(n)
# Calculate distances to the center for each point
distances <- center_distance(sample)
points_in <- sum(distances < 0.25)
cat("cantidad de puntos dentro del círculo: ", points_in)
## cantidad de puntos dentro del círculo: 7854
perc_points_in <- points_in/n
cat("Estimación de π para muestra con 10.000 puntos: ", perc_points_in)
## Estimación de π para muestra con 10.000 puntos: 0.7854
perc_points_in <- points_in/n
cat("Valor real π: ", pi/4)
## Valor real π: 0.7853982
En conclusión, se encuentra que el valor estimado (con muestra de 1.000: 0.77 y con muestra de 10.000: 0.7854) tiende a ser muy cercano al valor real de 0.7853. Mientras mayor es la muestra, más se acerca el valor estimado al valor real.
La simulación ayuda a entender y validad las propiedades de los estimadores estadísticos como son. insesgadez, eficiencia y la consistencia principalmente. El siguiente problema permite evidenciar las principales características de un grupo de estimadores propuestos para la estimación de un parámetro asociado a un modelo de probabilidad.
El primer paso es generar una función para aplicarla sobre las muestras de la distribución con las características solicitadas.
set.seed(4)
calc_estimators <- function(x1, x2, x3, x4) {
t1 <- (x1 + x2)/6 + (x3 + x4)/3
t2 <- (x1 + 2*x2 + 3*x3 + 4*x4)/5
t3 <- (x1 + x2 + x3 + x4)/4
t4 <- (min(x1, x2, x3, x4) + max(x1, x2, x3, x4))/2
return(c(t1, t2, t3, t4))
}
Lo siguiente es realizar la aplicación de la función en un dataframe
de las características solicitadas, en este caso será una con un vector
de 4.000 datos de la distribución exponencial distribuidos en cuatro
columnas. Luego de la aplicación de la función df contendrá
la información del cálculo de los indicadores.
rate <- 1 ## Rate = 1/lambda => lambda = 1
random_rexp <- matrix(rexp(4000, rate = rate), ncol = 4, nrow = 1000)
df_rexp <- data.frame(random_rexp)
series <- apply(df_rexp, 1, function(col) calc_estimators(col[1], col[2], col[3], col[4]))
df <- data.frame(t(series))
colnames(df) <- c("t1", "t2", "t3", "t4")
head(df, 3)
## t1 t2 t3 t4
## 1 0.5910686 1.359468 0.4732722 0.7988039
## 2 1.2439094 1.906450 1.5126452 2.3130521
## 3 0.7849282 1.607025 0.9413257 1.1906450
Se realiza un proceso iterativo para realizar revisión del comportamiento de los estimadores conforme aumenta la cantidad de estimadores tomados de la muestra.
sample_n = c(20, 50, 100, 1000)
complete_stats = data.frame()
for (n in sample_n) {
cat(sprintf("Boxplot de estimadores para %s observaciones", n))
df_sample <- head(df, n)
boxplot(df_sample, main = sprintf("%s observaciones", n))
abline(h=1, col="red")
stats = sapply(df_sample, function(x) c(mean=mean(x), var=var(x), sd=sd(x)))
colnames(stats) <- c(sprintf("t1_%s", n), sprintf("t2_%s", n), sprintf("t3_%s", n), sprintf("t4_%s", n))
complete_stats = rbind(complete_stats, t(stats))
}
## Boxplot de estimadores para 20 observaciones
## Boxplot de estimadores para 50 observaciones
## Boxplot de estimadores para 100 observaciones
## Boxplot de estimadores para 1000 observaciones
También se genera una tabla que contiene los datos de la media, la
varianza y la desviación estándar de los indicadores, la cual tiene como
nombre complete_stats. La tabla se ve de la siguiente
manera:
complete_stats[rownames(complete_stats)[order(rownames(complete_stats))], ]
## mean var sd
## t1_100 0.9724227 0.2788806 0.5280915
## t1_1000 1.0082160 0.2781248 0.5273754
## t1_20 0.8084008 0.2585561 0.5084841
## t1_50 0.9119348 0.3122715 0.5588126
## t2_100 1.9710698 1.2589164 1.1220144
## t2_1000 2.0115496 1.1766746 1.0847463
## t2_20 1.6195049 1.0121450 1.0060542
## t2_50 1.8412903 1.3891100 1.1786051
## t3_100 0.9748315 0.2292699 0.4788214
## t3_1000 1.0129165 0.2500660 0.5000660
## t3_20 0.8238081 0.2317945 0.4814505
## t3_50 0.9097480 0.2559280 0.5058932
## t4_100 1.1151086 0.3372509 0.5807331
## t4_1000 1.1880112 0.4126039 0.6423425
## t4_20 0.9471879 0.2869552 0.5356820
## t4_50 1.0829970 0.4187947 0.6471435
Realizando la revisión de la tabla resultado y las gráficas generadas se encuentra que:
Población de 1.000 plantas, 500 enfermas representadas por el 1 en la secuencia.
population <- c(rep(1, 500), rep(0, 500))
# Función para muestreo y cálculo de p_estimados
get_p_estimados <- function(population, n) {
p_estimados = c()
for (i in seq(500)) {
p_sample <- sample(population, n)
p_estimados <- append(p_estimados, (sum(p_sample)/n))
}
return (p_estimados)
}
p_estimados <- get_p_estimados(population, 500)
boxplot(p_estimados)
abline(h=0.5, col="blue")
plotn(p_estimados)
qqnorm(p_estimados, main = sprintf("qqnorm para muestra de tamaño %s", 500))
cat("Promedio:", mean(p_estimados), "Varianza:", var(p_estimados))
## Promedio: 0.501136 Varianza: 0.0002696648
¿Qué tan simétricos o sesgados son los resultados obtenidos?_: Los resultados tienden a ser insesgados dado que la media de los promedios encontrados se acerca mucho al valor poblacional definido de 0.5. El valor muestral es de 0.501136
¿Qué se puede observar en cuanto a la variabilidad?_: Se tiene una varianza relativamente pequeña, lo que indica que la distribución va a tender a orbitar a la media definida de 0.5.
size_sample = c(5, 10, 15, 20, 30, 50, 60, 100, 200, 500)
for (m in size_sample) {
p_estimados <- get_p_estimados(population, m)
cat("\nShapiro test para muestra de tamaño", m)
print(shapiro.test(p_estimados))
}
##
## Shapiro test para muestra de tamaño 5
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.92986, p-value = 1.498e-14
##
##
## Shapiro test para muestra de tamaño 10
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.96177, p-value = 4.139e-10
##
##
## Shapiro test para muestra de tamaño 15
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.97766, p-value = 6.23e-07
##
##
## Shapiro test para muestra de tamaño 20
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.98045, p-value = 2.986e-06
##
##
## Shapiro test para muestra de tamaño 30
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.98277, p-value = 1.2e-05
##
##
## Shapiro test para muestra de tamaño 50
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.98929, p-value = 0.001029
##
##
## Shapiro test para muestra de tamaño 60
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.98776, p-value = 0.0003343
##
##
## Shapiro test para muestra de tamaño 100
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.99454, p-value = 0.07206
##
##
## Shapiro test para muestra de tamaño 200
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.99579, p-value = 0.2022
##
##
## Shapiro test para muestra de tamaño 500
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.99529, p-value = 0.1347
En cuanto a la normalidad, realizando la revisión de los gráficos generados y los test de shapiro aplicados, se puede evidenciar, en primera medida, un aumento paulatino del valor de p_value al ir aumentando la cantidad de muestra procesada. Esto puede indicar que mientras más datos son tomados, más se va acercando la muestra a tener una distribución normal. El p-value mayor a 0.05 indica una mayor probabilidad de tener una distribución normal.
A la misma conclusión se puede llegar realizando la revisión de los gráficos qqnorm. Mientras más aumenta el valor de n tomado para realizar la muestra, mayor va siendo la correspondencia de los datos con los cuantiles. Esto permite, al final, develar la distribución normal de la población.
population_10 <- c(rep(1, 100), rep(0, 900))
p_estimados <- get_p_estimados(population_10, 500)
boxplot(p_estimados)
abline(h=0.1, col="blue")
cat("Promedio:", mean(p_estimados), "Varianza:", var(p_estimados))
## Promedio: 0.099804 Varianza: 8.726411e-05
plotn(p_estimados)
qqnorm(p_estimados, main = sprintf("qqnorm para muestra de tamaño %s", 500))
size_sample = c(5, 10, 15, 20, 30, 50, 60, 100, 200, 500)
for (m in size_sample) {
p_estimados <- get_p_estimados(population_10, m)
cat("\nShapiro test para muestra de tamaño", m)
print(shapiro.test(p_estimados))
}
##
## Shapiro test para muestra de tamaño 5
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.70902, p-value < 2.2e-16
##
##
## Shapiro test para muestra de tamaño 10
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.84755, p-value < 2.2e-16
##
##
## Shapiro test para muestra de tamaño 15
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.90031, p-value < 2.2e-16
##
##
## Shapiro test para muestra de tamaño 20
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.92119, p-value = 1.652e-15
##
##
## Shapiro test para muestra de tamaño 30
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.94929, p-value = 4.594e-12
##
##
## Shapiro test para muestra de tamaño 50
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.97061, p-value = 1.818e-08
##
##
## Shapiro test para muestra de tamaño 60
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.97806, p-value = 7.73e-07
##
##
## Shapiro test para muestra de tamaño 100
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.9823, p-value = 8.966e-06
##
##
## Shapiro test para muestra de tamaño 200
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.99045, p-value = 0.00252
##
##
## Shapiro test para muestra de tamaño 500
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.99289, p-value = 0.01803
population_90 <- c(rep(1, 900), rep(0, 100))
p_estimados <- get_p_estimados(population_90, 500)
boxplot(p_estimados)
abline(h=0.9, col="blue")
cat("Promedio:", mean(p_estimados), "Varianza:", var(p_estimados))
## Promedio: 0.899592 Varianza: 8.624603e-05
plotn(p_estimados)
qqnorm(p_estimados, main = sprintf("qqnorm para muestra de tamaño %s", 500))
size_sample = c(5, 10, 15, 20, 30, 50, 60, 100, 200, 500)
for (m in size_sample) {
p_estimados <- get_p_estimados(population_90, m)
cat("\nShapiro test para muestra de tamaño", m)
print(shapiro.test(p_estimados))
}
##
## Shapiro test para muestra de tamaño 5
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.69951, p-value < 2.2e-16
##
##
## Shapiro test para muestra de tamaño 10
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.85444, p-value < 2.2e-16
##
##
## Shapiro test para muestra de tamaño 15
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.90255, p-value < 2.2e-16
##
##
## Shapiro test para muestra de tamaño 20
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.92294, p-value = 2.544e-15
##
##
## Shapiro test para muestra de tamaño 30
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.94829, p-value = 3.305e-12
##
##
## Shapiro test para muestra de tamaño 50
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.96989, p-value = 1.306e-08
##
##
## Shapiro test para muestra de tamaño 60
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.97811, p-value = 7.939e-07
##
##
## Shapiro test para muestra de tamaño 100
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.97968, p-value = 1.91e-06
##
##
## Shapiro test para muestra de tamaño 200
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.98789, p-value = 0.0003663
##
##
## Shapiro test para muestra de tamaño 500
## Shapiro-Wilk normality test
##
## data: p_estimados
## W = 0.99172, p-value = 0.006878
Realizando la revisión de los shapiro test generados, se encuentra que para este tipo de distribuciones que poseen colas hacia la izquierda o hacia la derecha no pasan métodos de normalidad. Los p-values del test nunca superan el umbral de 0.05, lo que quiere decir que estadísticamente se rechaza la hipótesis nula, lo que permite corroborar que los datos no siguen una distribución normal. Sin embargo, dentro de los qq norm se encuentra una tendencia hacia la normalidad, la cual no se confirma dentro de los test estadísticos para las variaciones de poblaciones no balanceadas.
Cuando se extrae una muestra de una población que no es normal y se requiere estimar un intervalo de confianza se pueden utilizar los métodos de estimación bootstrap.Construya el intervalo de confianza por los dos métodos y compare los resultados obtenidos.
Se realiza cálculo de los promedios muestrales, suponiendo muestras
de 4 para cada uno de las iteraciones. Se realizan 1.000 iteraciones con
el vector de promedios que el ejercicio indica. Así mismo, se calcula el
promedio de los promedios y se almacena en X_mean, además
de los percentiles 2.5 y 97.5
x <- c(7.69, 4.97, 4.56, 6.49, 4.34, 6.24, 4.45)
means_sample = c()
for (i in 1:1000) {
means_sample <- append(means_sample, mean(sample(x, 4)))
}
X_mean <- mean(means_sample)
q025 <- quantile(means_sample, 0.025)
q975 <- quantile(means_sample, 0.975)
El primer método asume que los percentiles calculados sobre los promedios de las muestras son suficientes para realizar la estimación. Por lo tanto, se muestran los percentiles 2.5 y 97.5
cat("Intervalo de confianza desde", q025)
## Intervalo de confianza desde 4.889563
cat("Intervalo de confianza hasta", q975)
## Intervalo de confianza hasta 6.3475
En el segundo método se realiza el cálculo de dos veces el promedio de los promedios de las muestras, operado contra los percentiles anteriormente calculados.
liminf <- 2 * X_mean - q975
limsup <- 2 * X_mean - q025
cat("Intervalo de confianza desde", liminf)
## Intervalo de confianza desde 4.721665
cat("Intervalo de confianza hasta", limsup)
## Intervalo de confianza hasta 6.179602
El médodo de estimación bootstrap posee ventajas claves en su flexibilidad para estimar estadísticas de interés a partir de datos de muestra. Al generar muestras de la misma distribución que los datos observados, el método bootstrap permite estimar intervalos de confianza con pequeñas muestras.
Además, se identifica que al reutilizar y generar múltiples muestras a partir de los datos originales, se obtienen distribuciones empíricas de las estadísticas de interés, lo que permite calcular intervalos de confianza entendiendo que la distribución de los datos es desconocida.
Sin embargo, si los datos de muestra son pequeños, es posible que las estimaciones bootstrap no reflejen con precisión la verdadera distribución de los datos. Por ejemplo, en el caso de este ejercicio, para los dos métodos, los intervalos de confianza dejarían por fuera tres de siete datos disponibles y que son reales. Es algo importante y a tener en cuenta al realizar estimaciones por este tipo de modelación.