Codigo - Multivariate Methods: T² de Hotelling dos muestras independientes - Comparación de sensores espectrales

Compara dos sensores espectrales independientes mediante T² de Hotelling, verifica normalidad multivariada (Royston), prueba igualdad de covarianzas (Box), y calcula T² tanto con varianzas iguales (pooled) como desiguales (Nel-Van der Merwe).

Scripts multivariados

T² de Hotelling para dos muestras independientes en espectroscopía

Compara dos sensores espectrales independientes mediante T² de Hotelling, verifica normalidad multivariada (Royston), prueba igualdad de covarianzas (Box), y calcula T² tanto con varianzas iguales (pooled) como desiguales (Nel-Van der Merwe).

# T² DE HOTELLING PARA DOS SENSORES INDEPENDIENTES
library(MASS)
library(ggplot2)
library(MVN)
library(biotools)

set.seed(2024)

# Parámetros
n1 <- 50; n2 <- 50; p <- 3
mu_1 <- c(0.30, 0.25, 0.45)
mu_2 <- c(0.32, 0.24, 0.46)

Sigma_1 <- matrix(c(
  0.0015,  0.0008,  0.0010,
  0.0008,  0.0012, -0.0003,
  0.0010, -0.0003,  0.0020
), nrow = 3, byrow = TRUE)

Sigma_2 <- matrix(c(
  0.0018,  0.0009,  0.0011,
  0.0009,  0.0014, -0.0004,
  0.0011, -0.0004,  0.0022
), nrow = 3, byrow = TRUE)

datos_sensor1 <- mvrnorm(n = n1, mu = mu_1, Sigma = Sigma_1)
colnames(datos_sensor1) <- c("Rojo_650nm", "Verde_550nm", "NIR_850nm")
datos_sensor2 <- mvrnorm(n = n2, mu = mu_2, Sigma = Sigma_2)
colnames(datos_sensor2) <- c("Rojo_650nm", "Verde_550nm", "NIR_850nm")

x_bar_1 <- colMeans(datos_sensor1)
x_bar_2 <- colMeans(datos_sensor2)
S_1 <- cov(datos_sensor1)
S_2 <- cov(datos_sensor2)

# 1. Test de normalidad multivariada (Royston)
shapiro_1 <- mvn(data = datos_sensor1, mvnTest = "royston", multivariatePlot = "none")
shapiro_2 <- mvn(data = datos_sensor2, mvnTest = "royston", multivariatePlot = "none")
normalidad_1 <- shapiro_1$multivariateNormality$`p value` > 0.05
normalidad_2 <- shapiro_2$multivariateNormality$`p value` > 0.05
cat(sprintf("Normalidad Sensor 1: p = %.4f → %s\n",
    shapiro_1$multivariateNormality$`p value`,
    ifelse(normalidad_1, "NO RECHAZAR", "RECHAZAR")))
cat(sprintf("Normalidad Sensor 2: p = %.4f → %s\n\n",
    shapiro_2$multivariateNormality$`p value`,
    ifelse(normalidad_2, "NO RECHAZAR", "RECHAZAR")))

# 2. Test de Box para igualdad de covarianzas
datos_combined <- rbind(datos_sensor1, datos_sensor2)
grupo <- factor(rep(c("Sensor1", "Sensor2"), c(n1, n2)))
box_test <- boxM(datos_combined, grupo)
varianzas_iguales <- box_test$p.value > 0.05
cat(sprintf("Test de Box: χ² = %.4f, p = %.4f → %s\n\n",
    box_test$statistic, box_test$p.value,
    ifelse(varianzas_iguales, "Varianzas iguales", "Varianzas desiguales")))

# 3. T² de Hotelling
d <- x_bar_1 - x_bar_2
alpha <- 0.05

# Caso varianzas iguales (Pooled)
S_pooled <- ((n1 - 1) * S_1 + (n2 - 1) * S_2) / (n1 + n2 - 2)
T2_pooled <- as.numeric((n1 * n2) / (n1 + n2) * t(d) %*% solve(S_pooled) %*% d)
F_pooled <- ((n1 + n2 - p - 1) / ((n1 + n2 - 2) * p)) * T2_pooled
gl1_p <- p; gl2_p <- n1 + n2 - p - 1
p_valor_pooled <- 1 - pf(F_pooled, gl1_p, gl2_p)

# Caso varianzas desiguales (Nel-Van der Merwe)
S_combined <- (S_1/n1) + (S_2/n2)
T2_unpooled <- as.numeric(t(d) %*% solve(S_combined) %*% d)
A <- S_1/n1; B <- S_2/n2
nu_hat <- sum(diag((A+B) %*% solve(A+B)))^2 /
  (sum(diag(A %*% solve(A+B)))^2/(n1-1) + sum(diag(B %*% solve(A+B)))^2/(n2-1))
F_unpooled <- T2_unpooled / p
p_valor_unpooled <- 1 - pf(F_unpooled, p, nu_hat)

cat("Varianzas Iguales (Pooled):\n")
cat(sprintf("  T² = %.4f, F(%d,%d) = %.4f, p = %.6f\n", T2_pooled, gl1_p, gl2_p, F_pooled, p_valor_pooled))
cat("\nVarianzas Desiguales (Nel-Van der Merwe):\n")
cat(sprintf("  T² = %.4f, F(%d,%.2f) = %.4f, p = %.6f\n", T2_unpooled, p, nu_hat, F_unpooled, p_valor_unpooled))

# Decisión final según Test de Box
if(varianzas_iguales) {
  cat(sprintf("\nRecomendación: Usar Pooled → %s\n",
      ifelse(F_pooled > qf(0.95, gl1_p, gl2_p), "RECHAZAR H0", "NO RECHAZAR H0")))
} else {
  cat(sprintf("\nRecomendación: Usar Nel-Van der Merwe → %s\n",
      ifelse(F_unpooled > qf(0.95, p, nu_hat), "RECHAZAR H0", "NO RECHAZAR H0")))
}

# Visualización
estadisticos_comp <- data.frame(
  Banda = rep(c("Rojo (650 nm)", "Verde (550 nm)", "NIR (850 nm)"), 2),
  Sensor = rep(c("Sensor 1", "Sensor 2"), each = 3),
  Media = c(x_bar_1, x_bar_2),
  SE = c(sqrt(diag(S_1)/n1), sqrt(diag(S_2)/n2))
)
estadisticos_comp$Banda <- factor(estadisticos_comp$Banda,
  levels = c("Rojo (650 nm)", "Verde (550 nm)", "NIR (850 nm)"))

ggplot(estadisticos_comp, aes(x = Banda, y = Media, fill = Sensor)) +
  geom_col(position = position_dodge(0.8), alpha = 0.8, width = 0.7) +
  geom_errorbar(aes(ymin = Media - 1.96*SE, ymax = Media + 1.96*SE),
                position = position_dodge(0.8), width = 0.3, size = 1) +
  scale_fill_manual(values = c("Sensor 1" = "#2E86AB", "Sensor 2" = "#A23B72")) +
  labs(title = "Comparación de Reflectancia entre Sensores",
       x = "Banda Espectral", y = "Reflectancia Media", fill = "") +
  theme_minimal(base_size = 14) +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),
        legend.position = "top")
Lenguaje: RDescargar script

Notebooks de analisis multivariado

T² Hotelling dos muestras independientes

Comparación multivariada de dos sensores espectrales con verificación de supuestos.

Test de Box y elección de covarianza

Verificación de homocedasticidad multivariada y selección del enfoque adecuado.

Repositorios de metodos multivariados

Repositorio T² Hotelling dos muestras

Comparación de sensores espectrales con T² de Hotelling para dos muestras independientes.

Análisis multivariado de sensores

Herramientas para comparación estadística multivariada de sensores de reflectancia.

    T² de Hotelling dos muestras independientes - Comparación de sensores espectrales - Metodos Multivariados