library(fda)
library(MFPCA)
library(funData)
library(depthTools)
library(roahd)
library(Matrix)
library(MASS)
library(corrplot)Simulaciones
Librerías
CASO UNIVARIADO
En este caso se realizan varias simulaciones de observaciones funcionales para evaluar el desempeño y comportamiento del índice de capacidad multivariado basado en componentes principales dados los límites de especificación preestablecidos. En cada caso, se simulan \(N=250\) observaciones funcionales univariadas tal que:
\[x_i(t) = \sum_{m=1}^M \varepsilon_{im}\phi_m(t)\]
con \(t \in T\) y \(i=1,...,250\).
Adicionalmente, los scores \(\varepsilon_{im}\) son muestras independientes de una distribución \(N(0, \lambda_m)\) para valores propios con decrecimiento lineal, exponencial o correspondientes a un proceso de Wiener.
Se consideran distintas configuraciones para cada escenario, donde varían:
- Los valores de M
- Tipo de funciones con que serán simuladas las curvas (“Poly”: Polinomios de Legendre o “Fourier”: Funciones de la base de Fourier).
- El tipo de decrecimiento de los valores propios: (“linear”: \(\nu_m = \frac{M+1-m}{m}\), “exponential” = \(\nu_m = exp(-\frac{m-1}{2})\), “wiener” = \(\nu_m = \frac{1}{(\pi/2 \cdot (2m-1))^2}\)).
Límites de especificación (utilizando la media)
Se crea un conjunto de datos referencia para establecer los límites de especificación que serán utilizados en los escenarios propuestos de simulación. Para este caso, se consideran \(M=20\) funciones de la base de Fourier en el intervalo \([0,1]\) para el proceso univariado. Los límites de control están dados por:
\[USL(t)=\bar{x}(t)+3.5 \sigma(t)\] \[LSL(t)=\bar{x}(t)-3.5\sigma(t)\]
Code
# Construcción límites de especificación
set.seed(2143)
t <- seq(0, 1, length.out = 100)
sim_uni <- simFunData(argvals = t, M=20, eFunType = "Fourier", eValType = "exponential", N=250)
mu <- colMeans(sim_uni$simData@X)
sigma <- apply(sim_uni$simData@X, 2, sd)
k <- 3.5
# Límites de especificación
USL_uni <- mu + k * sigma
LSL_uni <- mu - k * sigma
# Gráfico
matplot(t, t(sim_uni$simData@X), type = "l", lty = 1, col = "grey", xlab = "t", ylab = "", ylim = c(-6, 6))
lines(t, USL_uni, col = "red", lwd = 3)
lines(t, LSL_uni, col = "red", lwd = 3)
lines(t, colMeans(sim_uni$simData@X), lwd = 3, col = "blue")Code
USL_fun_uni <- funData(argvals = list(t), X = matrix(USL_uni, nrow = 1))
LSL_fun_uni <- funData(argvals = list(t), X = matrix(LSL_uni, nrow = 1))
mean_fun_uni <- funData(argvals = list(t), X = matrix(mu, nrow = 1))Función para todos los escenarios
Code
run_scenario_fpca <- function(M_sim = 3, eFunType = "Fourier", eValType = "exponential", basis_type = "Fourier",
N = 250, ncomp = 3, alpha = 0.01, R_boot = 1000, nbasis = 20, seed = 2143,
USL, LSL){
set.seed(seed)
t_grid <- seq(0,1,length.out = 100)
sim <- simFunData(argvals = t_grid, M = M_sim, eFunType = eFunType, eValType = eValType, N = N)
X <- sim$simData@X
if(basis_type == "Fourier"){
basis_obj <- create.fourier.basis(rangeval = c(0,1), nbasis = nbasis)
} else{
basis_obj <- create.bspline.basis(rangeval = c(0,1), nbasis = nbasis)
}
fd_obj <- funData2fd(sim$simData, basisobj = basis_obj)
pca <- pca.fd(fd_obj, nharm = ncomp, centerfns = TRUE)
scores <- pca$scores
lambda <- pca$values
T2 <- rowSums(sweep(scores[,1:ncomp]^2, 2, lambda[1:ncomp], "/"))
alpha_t2 <- 1 - sqrt(1 - alpha)
UCL_T2_FPCA_sim <- function(simData){
n <- nObs(simData)
T2_vmax <- numeric(R_boot)
for(i in 1:R_boot){
indices <- sample(1:n, n, replace = TRUE)
X_boot <- simData@X[indices, ]
fun_boot <- funData(argvals = t_grid, X = X_boot)
fd_boot <- funData2fd(fun_boot, basisobj = basis_obj)
pca_boot <- pca.fd( fd_boot, nharm = ncomp, centerfns = TRUE)
scores_boot <- pca_boot$scores[,1:ncomp]
lambda_boot <- pca_boot$values[1:ncomp]
T2_vals <- rowSums(sweep(scores_boot^2, 2, lambda_boot, "/"))
T2_vmax[i] <- max(T2_vals)
}
quantile(T2_vmax, probs = 1 - alpha_t2)
}
UCL_T2 <- UCL_T2_FPCA_sim(sim$simData)
coef_harm <- pca$harmonics$coefs
basis <- pca$harmonics$basis
mean_coef <- pca$meanfd$coefs
n <- nrow(scores)
K <- ncol(scores)
gorros <- vector("list", n)
for(i in 1:n){
coef_i <- rep(0, nrow(coef_harm))
for(k in 1:K){
coef_i <- coef_i + scores[i,k] * coef_harm[,k]
}
coef_i <- coef_i + mean_coef
gorros[[i]] <- fd(coef_i, basis)
}
coef_matrix <- do.call(cbind, lapply(gorros, function(f) f$coefs))
gorros_fd <- fd(coef_matrix, basis)
residuos <- fd_obj - gorros_fd
Q <- diag(inprod(residuos, residuos))
UCL_Q_FPCA_sim <- function(simData){
n <- nObs(simData)
Q_max <- numeric(R_boot)
for(b in 1:R_boot){
indices <- sample(1:n, n, replace = TRUE)
X_boot <- simData@X[indices, ]
fun_boot <- funData(argvals = list(t_grid), X = X_boot)
fd_boot <- funData2fd(fun_boot, basisobj = basis_obj)
pca_boot <- pca.fd(fd_boot, nharm = ncomp, centerfns = TRUE)
scores_boot <- pca_boot$scores
coef_harm_boot <- pca_boot$harmonics$coefs
basis_boot <- pca_boot$harmonics$basis
mean_coef_boot <- pca_boot$meanfd$coefs
n_boot <- nrow(scores_boot)
K_boot <- ncol(scores_boot)
gorros_boot <- vector("list", n_boot)
for(i in 1:n_boot){
coef_i <- rep(0, nrow(coef_harm_boot))
for(k in 1:K_boot){
coef_i <- coef_i + scores_boot[i,k] * coef_harm_boot[,k]
}
coef_i <- coef_i + mean_coef_boot
gorros_boot[[i]] <- fd(coef_i, basis_boot)
}
coef_matrix_boot <- do.call(cbind, lapply(gorros_boot, function(f) f$coefs))
gorros_fd_boot <- fd(coef_matrix_boot, basis_boot)
residuos_boot <- fd_boot - gorros_fd_boot
Q_vals <- diag(inprod(residuos_boot, residuos_boot))
Q_max[b] <- max(Q_vals)
}
quantile(Q_max,
probs = 1 - alpha)
}
UCL_Q <- UCL_Q_FPCA_sim(sim$simData)
mu <- colMeans(X)
USL_fd <- Data2fd(argvals = t_grid, y = USL, basisobj = basis_obj)
LSL_fd <- Data2fd(argvals = t_grid, y = LSL, basisobj = basis_obj)
mean_fd <- Data2fd(argvals = t_grid, y = mu, basisobj = basis_obj)
USL_centered <- USL_fd - mean_fd
LSL_centered <- LSL_fd - mean_fd
USL_pc <- inprod(USL_centered, pca$harmonics)
LSL_pc <- inprod(LSL_centered, pca$harmonics)
lower <- pmin(LSL_pc, USL_pc)
upper <- pmax(LSL_pc, USL_pc)
cuantiles <- function(x, probs = c(0.005, 0.5, 0.995)){
dens <- density(x, bw = "SJ")
dx <- dens$x
dy <- dens$y
cdf <- cumsum(dy) * mean(diff(dx))
cdf <- cdf / max(cdf)
approx(cdf, dx, xout = probs)$y
}
cuantiles_proc <- matrix(NA, nrow = ncomp, ncol = 3)
for(i in 1:ncomp){
cuantiles_proc[i,] <- cuantiles(scores[,i])
}
indices_cpk <- numeric(ncomp)
for(i in 1:ncomp){
indices_cpk[i] <- min((upper[i] - cuantiles_proc[i,2]) / (cuantiles_proc[i,3] - cuantiles_proc[i,2]),
(cuantiles_proc[i,2] - lower[i]) / (cuantiles_proc[i,2] - cuantiles_proc[i,1]))
}
MCnpk <- prod(indices_cpk)^(1/ncomp)
par(mfrow = c(1,1))
plot(T2, pch = 16, xlab = "Observación", ylab = expression(T^2), main = expression("Carta " * T^2), ylim = c(0, max(T2, UCL_T2)))
abline(h = UCL_T2, col = "red", lwd = 2,lty = 2)
plot(Q, pch = 16, xlab = "Observación", ylab = "Q", main = "Carta Q", ylim=c(0, max(Q, UCL_Q)))
abline(h = UCL_Q, col = "red", lwd = 2)
# Curvas funcionales
matplot(t_grid, t(X), type = "l", lty = 1, col = "grey", xlab = "t", ylab = "X(t)", main = "Curvas funcionales")
lines(t_grid, USL, col = "red", lwd = 3)
lines(t_grid, LSL, col = "blue", lwd = 3)
lines(t_grid, mu, col = "black", lwd = 3)
# Scores
par(mfrow = c(1,ncomp))
for(m in 1:ncomp){
plot(scores[,m], pch = 16, cex = 0.8, col = "black", xlab = "Observación",
ylab = bquote(rho[.(m)]), main = paste("Score", m), ylim=c(min(min(scores), lower[m]), max(max(scores), upper[m])))
abline(h = lower[m], col = "blue", lwd = 2, lty = 2)
abline(h = upper[m], col = "red", lwd = 2, lty = 2)
}
return(list(sim = sim, pca = pca, T2 = T2, UCL_T2 = UCL_T2, Q = Q,
UCL_Q = UCL_Q, scores = scores, lower = lower, upper = upper,
indices_cpk = indices_cpk, MCnpk = MCnpk))
}Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=5\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de Fourier. Los valores propios se generan con un decrecimiento exponencial.
Code
# ESCENARIO 1: M = 5, eFunType = "Fourier", eValType = "exponential" --------
escenario2 <- run_scenario_fpca(M_sim = 5, eFunType = "Fourier", eValType = "exponential",
basis_type = "Fourier", ncomp = 3, USL = USL_uni, LSL = LSL_uni)Code
escenario2$indices_cpk[1] 1.941541901 0.038055729 0.006979287
Code
escenario2$MCnpk[1] 0.08019106
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=5\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de polinomios de Legendre. Los valores propios se generan con un decrecimiento exponencial.
Code
# ESCENARIO 2: M = 5, eFunType = "Poly", eValType = "exponential" ---------
escenario3 <- run_scenario_fpca(M_sim = 5, eFunType = "Poly", eValType = "exponential", basis_type = "Fourier", ncomp = 3,
USL = USL_uni, LSL = LSL_uni)Code
escenario3$indices_cpk[1] 1.94207107 0.03805423 0.18851709
Code
escenario3$MCnpk[1] 0.2406244
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=10\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de polinomios de Legendre. Los valores propios se generan con un decrecimiento exponencial.
Code
# ESCENARIO 3: M = 10, eFunType = "Poly", eValType = "exponential"
escenario5 <- run_scenario_fpca(M_sim = 10, eFunType = "Poly", eValType = "exponential", basis_type = "Fourier", ncomp = 3,
USL = USL_uni, LSL = LSL_uni)Code
escenario5$indices_cpk[1] 1.7889992 0.4886865 0.2536972
Code
escenario5$MCnpk[1] 0.6053205
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=10\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un comportamiento como el de un proceso de Wiener.
Code
# ESCENARIO 4: M = 10, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline"
escenario6 <- run_scenario_fpca(M_sim = 10, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USL_uni, LSL = LSL_uni)Code
escenario6$indices_cpk[1] 2.9280268 0.3347997 0.2707339
Code
escenario6$MCnpk[1] 0.6426398
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=30\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un comportamiento como el de un proceso de Wiener.
Code
# ESCENARIO 5: M = 30, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline" -------
escenario8 <- run_scenario_fpca(M_sim = 30, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USL_uni, LSL = LSL_uni)Code
escenario8$indices_cpk[1] 3.28110564 0.09227339 0.38174027
Code
escenario8$MCnpk[1] 0.4871038
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=30\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de polinomios de Legendre. Los valores propios se generan con un comportamiento como el de un proceso de Wiener.
Code
# ESCENARIO 9: M = 30, eFunType = "Poly", eValType = "wiener", basis_type = "bspline" -----------
escenario9 <- run_scenario_fpca(M_sim = 30, eFunType = "Poly", eValType = "wiener", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USL_uni, LSL = LSL_uni)Code
escenario9$indices_cpk[1] 3.28091050 -0.06221351 0.17669107
Code
escenario9$MCnpk[1] NaN
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=50\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un decrecimiento lineal.
Code
# ESCENARIO 7: M = 50, eFunType = "Fourier", eValType = "linear", basis_type = "bspline" --------------
escenario10 <- run_scenario_fpca(M_sim = 50, eFunType = "Fourier", eValType = "linear", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USL_uni, LSL = LSL_uni)Code
escenario10$indices_cpk[1] 0.88162715 0.02376312 1.44096427
Code
escenario10$MCnpk[1] 0.3113727
Resultados
Code
tabla_resultados_uni <- data.frame(
Escenario = paste("Escenario", 1:7),
M = c(5, 5, 10, 10, 30, 30, 50),
eFunType = c(
"Fourier",
"Poly",
"Poly",
"Fourier",
"Fourier",
"Poly",
"Fourier"
),
eValType = c(
"exponential",
"exponential",
"exponential",
"wiener",
"wiener",
"wiener",
"linear"
),
Cpk1 = c(
escenario2$indices_cpk[1],
escenario3$indices_cpk[1],
escenario5$indices_cpk[1],
escenario6$indices_cpk[1],
escenario8$indices_cpk[1],
escenario9$indices_cpk[1],
escenario10$indices_cpk[1]
),
Cpk2 = c(
escenario2$indices_cpk[2],
escenario3$indices_cpk[2],
escenario5$indices_cpk[2],
escenario6$indices_cpk[2],
escenario8$indices_cpk[2],
escenario9$indices_cpk[2],
escenario10$indices_cpk[2]
),
Cpk3 = c(
escenario2$indices_cpk[3],
escenario3$indices_cpk[3],
escenario5$indices_cpk[3],
escenario6$indices_cpk[3],
escenario8$indices_cpk[3],
escenario9$indices_cpk[3],
escenario10$indices_cpk[3]
),
MCnpk = c(
escenario2$MCnpk,
escenario3$MCnpk,
escenario5$MCnpk,
escenario6$MCnpk,
escenario8$MCnpk,
escenario9$MCnpk,
escenario10$MCnpk
)
)
knitr::kable(tabla_resultados_uni)| Escenario | M | eFunType | eValType | Cpk1 | Cpk2 | Cpk3 | MCnpk |
|---|---|---|---|---|---|---|---|
| Escenario 1 | 5 | Fourier | exponential | 1.9415419 | 0.0380557 | 0.0069793 | 0.0801911 |
| Escenario 2 | 5 | Poly | exponential | 1.9420711 | 0.0380542 | 0.1885171 | 0.2406244 |
| Escenario 3 | 10 | Poly | exponential | 1.7889992 | 0.4886865 | 0.2536972 | 0.6053205 |
| Escenario 4 | 10 | Fourier | wiener | 2.9280268 | 0.3347997 | 0.2707339 | 0.6426398 |
| Escenario 5 | 30 | Fourier | wiener | 3.2811056 | 0.0922734 | 0.3817403 | 0.4871038 |
| Escenario 6 | 30 | Poly | wiener | 3.2809105 | -0.0622135 | 0.1766911 | NaN |
| Escenario 7 | 50 | Fourier | linear | 0.8816272 | 0.0237631 | 1.4409643 | 0.3113727 |
Límites de especificación (utilizando la mediana)
En este caso, se considera el mismo conjunto de datos de referencia utilizado anteriormente. Sin embargo, los límites de especificación que serán utilizados en los escenarios propuestos de simulación se definen como:
\[USL(t)=\hat{med}_n(t)+3.5 \sigma(t)\] \[LSL(t)=\hat{med}_n(t)-3.5\sigma(t)\]
donde \(\hat{med}(t)\) hace referencia a la función mediana muestral, que se obtiene como:
\[\hat{med}_n = \arg \max_{x \in \{x_1,\ldots,x_n\}} MBD_n(x)\] donde \(MBD\) es la medida de profundidad Modified Band Depth.
Code
X <- sim_uni$simData@X
mbd <- MBD(X)Code
# Mediana
mediana_indice <- mbd$ordering[1]
# Función mediana muestral
mediana <- X[mediana_indice, ]
k <- 3.5
# Límites de especificación
USL_uni_med <- mediana + k * sigma
LSL_uni_med <- mediana - k * sigma
# Gráfico
matplot(t, t(sim_uni$simData@X), type = "l", lty = 1, col = "grey", xlab = "t", ylab = "", ylim = c(-6, 6))
lines(t, USL_uni_med, col = "red", lwd = 3)
lines(t, LSL_uni_med, col = "red", lwd = 3)
lines(t, mediana, lwd = 3, col = "blue")Code
USL_fun_uni_med <- funData(argvals = list(t), X = matrix(USL_uni_med, nrow = 1))
LSL_fun_uni_med <- funData(argvals = list(t), X = matrix(LSL_uni_med, nrow = 1))
mean_fun_uni <- funData(argvals = list(t), X = matrix(mu, nrow = 1))Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=5\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de Fourier. Los valores propios se generan con un decrecimiento exponencial.
Code
# ESCENARIO 1: M = 5, eFunType = "Fourier", eValType = "exponential" --------
escenario2_med <- run_scenario_fpca(M_sim = 5, eFunType = "Fourier", eValType = "exponential",
basis_type = "Fourier", ncomp = 3, USL = USL_uni_med, LSL = LSL_uni_med)Code
escenario2_med$indices_cpk[1] 1.83324845 -0.05382534 -0.16759576
Code
escenario2_med$MCnpk[1] 0.2547751
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=5\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de polinomios de Legendre. Los valores propios se generan con un decrecimiento exponencial.
Code
# ESCENARIO 2: M = 5, eFunType = "Poly", eValType = "exponential" ---------
escenario3_med <- run_scenario_fpca(M_sim = 5, eFunType = "Poly", eValType = "exponential", basis_type = "Fourier", ncomp = 3,
USL = USL_uni_med, LSL = LSL_uni_med)Code
escenario3_med$indices_cpk[1] 1.83703323 -0.05049960 0.02077519
Code
escenario3_med$MCnpk[1] NaN
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=10\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de polinomios de Legendre. Los valores propios se generan con un decrecimiento exponencial.
Code
# ESCENARIO 3: M = 10, eFunType = "Poly", eValType = "exponential"
escenario5_med <- run_scenario_fpca(M_sim = 10, eFunType = "Poly", eValType = "exponential", basis_type = "Fourier", ncomp = 3,
USL = USL_uni_med, LSL = LSL_uni_med)Code
escenario5_med$indices_cpk[1] 1.8079773 0.3493033 0.1338326
Code
escenario5_med$MCnpk[1] 0.4388532
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=10\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un comportamiento como el de un proceso de Wiener.
Code
# ESCENARIO 4: M = 10, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline"
escenario6_med <- run_scenario_fpca(M_sim = 10, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USL_uni_med, LSL = LSL_uni_med)Code
escenario6_med$indices_cpk[1] 2.9070125 0.1328767 -0.3128785
Code
escenario6_med$MCnpk[1] NaN
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=30\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un comportamiento como el de un proceso de Wiener.
Code
# ESCENARIO 5: M = 30, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline" -------
escenario8_med <- run_scenario_fpca(M_sim = 30, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USL_uni_med, LSL = LSL_uni_med)Code
escenario8_med$indices_cpk[1] 3.0948833 -0.1271266 -0.2287873
Code
escenario8_med$MCnpk[1] 0.4481645
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=30\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de polinomios de Legendre. Los valores propios se generan con un comportamiento como el de un proceso de Wiener.
Code
# ESCENARIO 9: M = 30, eFunType = "Poly", eValType = "wiener", basis_type = "bspline" -----------
escenario9_med <- run_scenario_fpca(M_sim = 30, eFunType = "Poly", eValType = "wiener", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USL_uni_med, LSL = LSL_uni_med)Code
escenario9_med$indices_cpk[1] 3.1007166 -0.3609460 -0.3340221
Code
escenario9_med$MCnpk[1] 0.720377
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=50\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un decrecimiento lineal.
Code
# ESCENARIO 7: M = 50, eFunType = "Fourier", eValType = "linear", basis_type = "bspline" --------------
escenario10_med <- run_scenario_fpca(M_sim = 50, eFunType = "Fourier", eValType = "linear", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USL_uni_med, LSL = LSL_uni_med)Code
escenario10_med$indices_cpk[1] 0.84764124 0.03309566 1.48982868
Code
escenario10_med$MCnpk[1] 0.3470349
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=50\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un decrecimiento lineal.
Code
# ESCENARIO 8: M = 20, eFunType = "Fourier", eValType = "exponential", basis_type = "bspline" --------------
escenario11_med <- run_scenario_fpca(M_sim = 20, eFunType = "Fourier", eValType = "exponential", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USL_uni_med, LSL = LSL_uni_med)Code
escenario11_med$indices_cpk[1] 1.91376855 -0.05947656 0.02069108
Code
escenario11_med$MCnpk[1] NaN
Resultados
Code
tabla_resultados_uni_med <- data.frame(
Escenario = paste("Escenario", 1:8),
M = c(5, 5, 10, 10, 30, 30, 50, 20),
eFunType = c(
"Fourier",
"Poly",
"Poly",
"Fourier",
"Fourier",
"Poly",
"Fourier",
"Fourier"
),
eValType = c(
"exponential",
"exponential",
"exponential",
"wiener",
"wiener",
"wiener",
"linear",
"exponential"
),
Cpk1 = c(
escenario2_med$indices_cpk[1],
escenario3_med$indices_cpk[1],
escenario5_med$indices_cpk[1],
escenario6_med$indices_cpk[1],
escenario8_med$indices_cpk[1],
escenario9_med$indices_cpk[1],
escenario10_med$indices_cpk[1],
escenario11_med$indices_cpk[1]
),
Cpk2 = c(
escenario2_med$indices_cpk[2],
escenario3_med$indices_cpk[2],
escenario5_med$indices_cpk[2],
escenario6_med$indices_cpk[2],
escenario8_med$indices_cpk[2],
escenario9_med$indices_cpk[2],
escenario10_med$indices_cpk[2],
escenario11_med$indices_cpk[2]
),
Cpk3 = c(
escenario2_med$indices_cpk[3],
escenario3_med$indices_cpk[3],
escenario5_med$indices_cpk[3],
escenario6_med$indices_cpk[3],
escenario8_med$indices_cpk[3],
escenario9_med$indices_cpk[3],
escenario10_med$indices_cpk[3],
escenario11_med$indices_cpk[3]
),
MCnpk = c(
escenario2_med$MCnpk,
escenario3_med$MCnpk,
escenario5_med$MCnpk,
escenario6_med$MCnpk,
escenario8_med$MCnpk,
escenario9_med$MCnpk,
escenario10_med$MCnpk,
escenario11_med$MCnpk
)
)
knitr::kable(tabla_resultados_uni_med)| Escenario | M | eFunType | eValType | Cpk1 | Cpk2 | Cpk3 | MCnpk |
|---|---|---|---|---|---|---|---|
| Escenario 1 | 5 | Fourier | exponential | 1.8332485 | -0.0538253 | -0.1675958 | 0.2547751 |
| Escenario 2 | 5 | Poly | exponential | 1.8370332 | -0.0504996 | 0.0207752 | NaN |
| Escenario 3 | 10 | Poly | exponential | 1.8079773 | 0.3493033 | 0.1338326 | 0.4388532 |
| Escenario 4 | 10 | Fourier | wiener | 2.9070125 | 0.1328767 | -0.3128785 | NaN |
| Escenario 5 | 30 | Fourier | wiener | 3.0948833 | -0.1271266 | -0.2287873 | 0.4481645 |
| Escenario 6 | 30 | Poly | wiener | 3.1007166 | -0.3609460 | -0.3340221 | 0.7203770 |
| Escenario 7 | 50 | Fourier | linear | 0.8476412 | 0.0330957 | 1.4898287 | 0.3470349 |
| Escenario 8 | 20 | Fourier | exponential | 1.9137686 | -0.0594766 | 0.0206911 | NaN |
Límites de especificación (utilizando cuantiles)
Code
# Con la relación p=|2q-1|
p <- abs(2*0.975 - 1)
n_esp <- dim(sim_uni$simData@X)[1]
k1 <- ceiling(p * n_esp)
indices_esp <- mbd$ordering[1:k1]
curvas <- sim_uni$simData@X[indices_esp, ]
LSLq <- apply(curvas, 2, min)
USLq <- apply(curvas, 2, max)
# Gráfico
matplot(t, t(sim_uni$simData@X), type = "l", lty = 1, col = "grey", xlab = "t", ylab = "", ylim = c(-6, 6))
lines(t, USLq, col = "red", lwd = 3)
lines(t, LSLq, col = "red", lwd = 3)
lines(t, mediana, lwd = 3, col = "blue")Code
USLq_fun <- funData(argvals = list(t), X = matrix(USLq, nrow = 1))
LSLq_fun <- funData(argvals = list(t), X = matrix(LSLq, nrow = 1))Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=5\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de Fourier. Los valores propios se generan con un decrecimiento exponencial.
Code
# ESCENARIO 1: M = 5, eFunType = "Fourier", eValType = "exponential" --------
escenario2q <- run_scenario_fpca(M_sim = 5, eFunType = "Fourier", eValType = "exponential",
basis_type = "Fourier", ncomp = 3, USL = USLq, LSL = LSLq)Code
escenario2q$indices_cpk[1] 1.51828550 0.05457561 0.05531880
Code
escenario2q$MCnpk[1] 0.1661148
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=5\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de polinomios de Legendre. Los valores propios se generan con un decrecimiento exponencial.
Code
# ESCENARIO 2: M = 5, eFunType = "Poly", eValType = "exponential" ---------
escenario3q <- run_scenario_fpca(M_sim = 5, eFunType = "Poly", eValType = "exponential", basis_type = "Fourier", ncomp = 3,
USL = USLq, LSL = LSLq)Code
escenario3q$indices_cpk[1] 1.51545659 0.13242535 0.05763783
Code
escenario3q$MCnpk[1] 0.2261556
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=10\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de polinomios de Legendre. Los valores propios se generan con un decrecimiento exponencial.
Code
# ESCENARIO 3: M = 10, eFunType = "Poly", eValType = "exponential"
escenario5q <- run_scenario_fpca(M_sim = 10, eFunType = "Poly", eValType = "exponential", basis_type = "Fourier", ncomp = 3,
USL = USLq, LSL = LSLq)Code
escenario5q$indices_cpk[1] 1.4003394 0.2853110 0.1031544
Code
escenario5q$MCnpk[1] 0.3454193
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=10\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un comportamiento como el de un proceso de Wiener.
Code
# ESCENARIO 4: M = 10, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline"
escenario6q <- run_scenario_fpca(M_sim = 10, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USLq, LSL = LSLq)Code
escenario6q$indices_cpk[1] 2.2682000 0.2644760 0.7422495
Code
escenario6q$MCnpk[1] 0.7636116
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=30\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un comportamiento como el de un proceso de Wiener.
Code
# ESCENARIO 5: M = 30, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline" -------
escenario8q <- run_scenario_fpca(M_sim = 30, eFunType = "Fourier", eValType = "wiener", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USLq, LSL = LSLq)Code
escenario8q$indices_cpk[1] 2.57279146 0.04341968 0.68395456
Code
escenario8q$MCnpk[1] 0.4243324
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=30\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de polinomios de Legendre. Los valores propios se generan con un comportamiento como el de un proceso de Wiener.
Code
# ESCENARIO 9: M = 30, eFunType = "Poly", eValType = "wiener", basis_type = "bspline" -----------
escenario9q <- run_scenario_fpca(M_sim = 30, eFunType = "Poly", eValType = "wiener", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USLq, LSL = LSLq)Code
escenario9q$indices_cpk[1] 2.5738703 0.3214234 -0.1244616
Code
escenario9q$MCnpk[1] NaN
Se simulan observaciones funcionales univariadas utilizando una expansión de Karhunen-Loève con \(M=50\) componentes principales funcionales. Las funciones propias del proceso son generadas a partir de funciones de la base Fourier. Los valores propios se generan con un decrecimiento lineal.
Code
# ESCENARIO 7: M = 50, eFunType = "Fourier", eValType = "linear", basis_type = "bspline" --------------
escenario10q <- run_scenario_fpca(M_sim = 50, eFunType = "Fourier", eValType = "linear", basis_type = "bspline", ncomp = 3,
nbasis = 9, USL = USLq, LSL = LSLq)Code
escenario10q$indices_cpk[1] 0.701842810 -0.002412972 1.087470946
Code
escenario10q$MCnpk[1] NaN
Resultados
Code
tabla_resultados_uni_q <- data.frame(
Escenario = paste("Escenario", 1:7),
M = c(5, 5, 10, 10, 30, 30, 50),
eFunType = c(
"Fourier",
"Poly",
"Poly",
"Fourier",
"Fourier",
"Poly",
"Fourier"
),
eValType = c(
"exponential",
"exponential",
"exponential",
"wiener",
"wiener",
"wiener",
"linear"
),
Cpk1 = c(
escenario2q$indices_cpk[1],
escenario3q$indices_cpk[1],
escenario5q$indices_cpk[1],
escenario6q$indices_cpk[1],
escenario8q$indices_cpk[1],
escenario9q$indices_cpk[1],
escenario10q$indices_cpk[1]
),
Cpk2 = c(
escenario2q$indices_cpk[2],
escenario3q$indices_cpk[2],
escenario5q$indices_cpk[2],
escenario6q$indices_cpk[2],
escenario8q$indices_cpk[2],
escenario9q$indices_cpk[2],
escenario10q$indices_cpk[2]
),
Cpk3 = c(
escenario2q$indices_cpk[3],
escenario3q$indices_cpk[3],
escenario5q$indices_cpk[3],
escenario6q$indices_cpk[3],
escenario8q$indices_cpk[3],
escenario9q$indices_cpk[3],
escenario10q$indices_cpk[3]
),
MCnpk = c(
escenario2q$MCnpk,
escenario3q$MCnpk,
escenario5q$MCnpk,
escenario6q$MCnpk,
escenario8q$MCnpk,
escenario9q$MCnpk,
escenario10q$MCnpk
)
)
knitr::kable(tabla_resultados_uni_q)| Escenario | M | eFunType | eValType | Cpk1 | Cpk2 | Cpk3 | MCnpk |
|---|---|---|---|---|---|---|---|
| Escenario 1 | 5 | Fourier | exponential | 1.5182855 | 0.0545756 | 0.0553188 | 0.1661148 |
| Escenario 2 | 5 | Poly | exponential | 1.5154566 | 0.1324254 | 0.0576378 | 0.2261556 |
| Escenario 3 | 10 | Poly | exponential | 1.4003394 | 0.2853110 | 0.1031544 | 0.3454193 |
| Escenario 4 | 10 | Fourier | wiener | 2.2682000 | 0.2644760 | 0.7422495 | 0.7636116 |
| Escenario 5 | 30 | Fourier | wiener | 2.5727915 | 0.0434197 | 0.6839546 | 0.4243324 |
| Escenario 6 | 30 | Poly | wiener | 2.5738703 | 0.3214234 | -0.1244616 | NaN |
| Escenario 7 | 50 | Fourier | linear | 0.7018428 | -0.0024130 | 1.0874709 | NaN |
CASO MULTIVARIADO
Simulación 1
En este caso se realizaron distintas simulaciones de procesos funcionales multivariados con el objetivo de evaluar el comportamiento del índice de capacidad multivariado basado en componentes principales considerando distintas estructuras de dependencia entre las componentes funcionales. En cada escenario se generan \(n=250\) observaciones funcionales bivariadas mediante la descomposición de Karhunen-Loève, es decir, las observaciones funcionales son de la forma:
\[ \boldsymbol{X}_i(t) = \left( X_i^{(1)}(t), X_i^{(2)}(t) \right), \qquad i=1,\dots,N \]
donde cada componente funcional se construye como:
\[ X_i^{(j)}(t) = \sum_{k=1}^{K} \xi_{ik}^{(j)}\phi_k(t), \qquad j=1,2 \] con \(t \in [0,1]\), \(\phi_k(t)\) funciones base ortogonales y \(\xi_{ik}^{(j)}\) los scores asociados a cada componente principal funcional.
Las funciones \(\phi_k(t)\) son tomadas de una base de Fourier, utilizada como aproximación de las eigenfunciones del proceso funcional.
La estructura de dependencia entre las componentes funcionales es controlada directamente mediante la simulación conjunta de los scores. Se define el vector:
\[ \boldsymbol{\xi}_i = ( \xi_{i1}^{(1)}, \dots, \xi_{iK}^{(1)}, \xi_{i1}^{(2)}, \dots, \xi_{iK}^{(2)} ) ^\top \]
y se asume que:
\[ \boldsymbol{\xi}_i \sim N(\boldsymbol{0},\Sigma) \]
donde \(\Sigma\) es una matriz de covarianza definida positiva con la cual se controla:
- La variabilidad de cada componente principal funcional mediante los elementos de la diagonal.
- La dependencia entre procesos funcionales mediante los bloques de covarianza cruzada.
En todos los escenarios, las covarianzas entre componentes principales pertenecientes al mismo proceso funcional se consideran nulas. Por lo tanto, la matriz \(\Sigma\) puede expresarse mediante una estructura en bloques de la forma:
\[ \Sigma = \begin{pmatrix} D_1 & C \\ C^\top & D_2 \end{pmatrix} \]
donde \(D_1\) y \(D_2\) son matrices diagonales asociadas a las varianzas de los scores de cada proceso funcional y \(C\) representa la dependencia entre procesos.
Cada componente funcional fue simulada utilizando la expansión de Karhunen-Loève para procesos funcionales univariados. Posteriormente, para cada componente funcional se realizó FPCA univariado considerando 3 componentes principales. A partir de estas expansiones univariadas se aplicó MFPCA, considerando 3 componentes principales multivariados.
Finalmente, los scores obtenidos fueron utilizados para la construcción de las cartas de control \(T^2\) y \(Q\), y para el cálculo del índice de capacidad multivariado basado en componentes principales funcionales.
Límites de especificación
Se crea un conjunto de datos referencia para establecer los límites de especificación que serán utilizados en los escenarios propuestos de simulación. Para este caso, se consideran \(M=20\) funciones de la base de Fourier en el intervalo \([0,1]\) para cada uno de los procesos del proceso bivariado. Los límites de control están dados por:
\[USL(\boldsymbol{t})=\bar{\boldsymbol{x}}(\boldsymbol{t})+3.5 \boldsymbol{\sigma}(\boldsymbol{t})\] \[LSL(\boldsymbol{t})=\bar{\boldsymbol{x}}(\boldsymbol{t})-3.5 \boldsymbol{\sigma}(\boldsymbol{t})\]
Code
# Construcción de límites de especificación
set.seed(2143)
t <- seq(0, 1, length.out = 200)
sim_ref <- simMultiFunData(type = "split", argvals = list(t,t), M = 20, eFunType = "Fourier",
eValType = "exponential", N = 250)
mu1 <- colMeans(sim_ref$simData[[1]]@X)
sd1 <- apply(sim_ref$simData[[1]]@X, 2, sd)
mu2 <- colMeans(sim_ref$simData[[2]]@X)
sd2 <- apply(sim_ref$simData[[2]]@X, 2, sd)
k <- 3.5
USL1 <- mu1 + k*sd1
LSL1 <- mu1 - k*sd1
USL2 <- mu2 + k*sd2
LSL2 <- mu2 - k*sd2
USL <- cbind(USL1, USL2)
LSL <- cbind(LSL1, LSL2)
par(mfrow=c(1,2))
for (j in 1:2){
matplot(t, t(sim_ref$simData[[j]]@X), type = "l", lty = 1, col = "grey", xlab = "t", ylab = "",
ylim = c(-5, 5), main= paste("Proceso", j))
lines(t, USL[,j], col = "red", lwd = 3)
lines(t, LSL[,j], col = "red", lwd = 3)
lines(t, colMeans(sim_ref$simData[[j]]@X), lwd = 3, col = "blue")
legend("topright", legend = c("Límites de \n especificación"), col = c("red"), lwd = 3, lty = 1, bty = "n",
cex = 0.4)
}Code
USL_fun <- multiFunData(list(funData(argvals = list(t), X = matrix(USL1, nrow = 1)),
funData(argvals = list(t), X = matrix(USL2, nrow = 1))))
LSL_fun <- multiFunData(list(funData(argvals = list(t), X = matrix(LSL1, nrow = 1)),
funData(argvals = list(t), X = matrix(LSL2, nrow = 1))))
mean_list <- list(funData(argvals = list(t), X = matrix(mu1, nrow = 1)),
funData(argvals = list(t), X = matrix(mu2, nrow = 1)))
mean_mult <- multiFunData(mean_list)Funciones utilizadas
Code
# Función para simular observaciones -----------------------
sim_mfpca_fourier <- function(n = 100, nbasis = 3, M = 6, t = seq(0,1,length.out = 200),
Sigma = NULL, seed = NULL){
if(!is.null(seed)){
set.seed(seed)
}
if(is.null(Sigma)){
Sigma <- matrix(c(
# proceso 1
2.0, 0.0, 0.0, 0.4, 0.1, 0.1,
0.0, 1.0, 0.0, 0.2, 0.3, 0.2,
0.0, 0.0, 0.5, 0.1, 0.2, 0.4,
# proceso 2
0.4, 0.2, 0.1, 2.0, 0.0, 0.0,
0.1, 0.3, 0.2, 0.0, 1.0, 0.0,
0.1, 0.2, 0.4, 0.0, 0.0, 0.5
), nrow = 6, byrow = TRUE)
}
eigvals <- eigen(Sigma)$values
if(any(eigvals <= 0)){
stop("Sigma no es definida positiva")
}
basis_obj <- create.fourier.basis(rangeval = c(0,1), nbasis = nbasis)
Phi <- eval.basis(t, basis_obj)
scores <- MASS::mvrnorm(n = n, mu = rep(0, 2*nbasis), Sigma = Sigma)
Xi1 <- scores[,1:nbasis]
Xi2 <- scores[,(nbasis+1):(2*nbasis)]
X1 <- Xi1 %*% t(Phi)
X2 <- Xi2 %*% t(Phi)
fd1 <- funData(argvals = list(t), X = X1)
fd2 <- funData(argvals = list(t), X = X2)
mfd <- multiFunData(fd1, fd2)
uni_exp <- vector("list", 2)
pca_uni <- vector("list", 2)
for(j in 1:2){
fd_j <- funData2fd(mfd[[j]], basisobj = basis_obj)
pca_j <- pca.fd(fd_j, nharm = nbasis, centerfns = TRUE)
uni_exp[[j]] <- list(
type = "given",
functions = fd2funData(pca_j$harmonics, argvals = mfd[[j]]@argvals),
scores = pca_j$scores
)
pca_uni[[j]] <- pca_j
}
fit_mfpca <- MFPCA(mFData = mfd, M = M, uniExpansions = uni_exp)
reconstruction <- predict(fit_mfpca, scores = fit_mfpca$scores)
return(list(t = t, Phi = Phi, Sigma = Sigma, scores = scores, Xi1 = Xi1,
Xi2 = Xi2, X1 = X1, X2 = X2, mfd = mfd, pca_uni = pca_uni,
fit_mfpca = fit_mfpca, reconstruction = reconstruction))
}
sim1 <- sim_mfpca_fourier(n = 100, nbasis = 3, M = 6, t = seq(0,1,length.out = 200),
seed = 123)
### Función para cartas de control ------------------------------------------
analisis_mfpca <- function(sim_obj, alpha = 0.01, ncomp = 3, M = 3, R = 500,
nbasis_monitor = 9
){
simData <- sim_obj$mfd
p <- length(simData)
uni_exp <- vector("list", length = p)
pca_uni <- vector("list", length = p)
FourierBasis <- create.fourier.basis(rangeval = c(0,1), nbasis = nbasis_monitor)
for(j in 1:p){
fd_j <- funData2fd(simData[[j]], basisobj = FourierBasis)
pca_j <- pca.fd(fd_j, nharm = ncomp, centerfns = TRUE)
uni_exp[[j]] <- list(type = "given", functions = fd2funData(pca_j$harmonics,
argvals = simData[[j]]@argvals),
scores = pca_j$scores)
pca_uni[[j]] <- pca_j
}
mfpca <- MFPCA(mFData = simData, M = M, uniExpansions = uni_exp)
scores_mult <- mfpca$scores
lambda_mult <- mfpca$values
T2_valores <- rowSums(sweep(scores_mult[,1:M]^2, 2, lambda_mult[1:M], "/"))
alpha_boot <- 1 - sqrt(1 - alpha)
UCL_T2_MFPCA_sim <- function(simData, alpha, ncomp = 3, M = M, R = R, nbasis = 9
){
p <- length(simData)
n <- nObs(simData)
t_grid <- simData[[1]]@argvals[[1]]
FourierBasis <- create.fourier.basis(rangeval = range(t_grid),
nbasis = nbasis)
T2_vmax <- numeric(R)
for(i in 1:R){
indices <- sample(1:n, n, replace = TRUE)
lista_funData <- vector("list", p)
for(k in 1:p){
Xk <- simData[[k]]@X[indices, ]
lista_funData[[k]] <- funData(argvals = list(t_grid), X = Xk)
}
mfData_boot <- multiFunData(lista_funData)
uni_exp <- vector("list", p)
for(j in 1:p){
fd_j <- funData2fd(mfData_boot[[j]], basisobj = FourierBasis)
pca_j <- pca.fd(fd_j, nharm = ncomp, centerfns = TRUE)
uni_exp[[j]] <- list(type = "given",
functions = fd2funData(pca_j$harmonics,
argvals = mfData_boot[[j]]@argvals),
scores = pca_j$scores)
}
mfpca_boot <- MFPCA(mFData = mfData_boot, M = M, uniExpansions = uni_exp)
scores_boot <- mfpca_boot$scores[,1:M]
lambda_boot <- mfpca_boot$values[1:M]
T2_vals <- rowSums(sweep(scores_boot^2, 2, lambda_boot, "/"))
T2_vmax[i] <- max(T2_vals)
}
quantile(T2_vmax, probs = 1 - alpha)
}
UCL_T2 <- UCL_T2_MFPCA_sim(simData = simData, alpha = alpha_boot, ncomp = ncomp, M = M,
R = R, nbasis = nbasis_monitor)
curvas_klmult <- predict(mfpca, scores = mfpca$scores)
n <- nObs(simData)
t_grid <- simData[[1]]@argvals[[1]]
dt <- diff(t_grid)[1]
Q_mult <- rep(0, n)
for(i in 1:p){
X_orig <- simData[[i]]@X
X_hat <- curvas_klmult[[i]]@X
error <- X_orig - X_hat
Q_mult <- Q_mult + rowSums(error^2) * dt
}
UCL_Q_MFPCA_sim <- function(simData, alpha, ncomp, M, R, nbasis){
p <- length(simData)
n <- nObs(simData)
t_grid <- simData[[1]]@argvals[[1]]
dt <- diff(t_grid)[1]
FourierBasis <- create.fourier.basis(rangeval = range(t_grid), nbasis = nbasis)
Q_max <- numeric(R)
for(b in 1:R){
indices <- sample(1:n, n, replace = TRUE)
lista_funData <- vector("list", p)
for(j in 1:p){
Xj <- simData[[j]]@X[indices, ]
lista_funData[[j]] <- funData(argvals = list(t_grid), X = Xj)
}
mfData_boot <- multiFunData(lista_funData)
uni_exp <- vector("list", p)
for(j in 1:p){
fd_j <- funData2fd(mfData_boot[[j]], basisobj = FourierBasis)
pca_j <- pca.fd(fd_j, nharm = ncomp, centerfns = TRUE)
uni_exp[[j]] <- list(type = "given",
functions = fd2funData(pca_j$harmonics, argvals = mfData_boot[[j]]@argvals),
scores = pca_j$scores)
}
mfpca_boot <- MFPCA(mFData = mfData_boot, M = M, uniExpansions = uni_exp,
fit = TRUE)
residuos <- mfData_boot - mfpca_boot$fit
Q_vals <- rep(0, n)
for(j in 1:p){
err_sq <- residuos[[j]]@X^2
Q_vals <- Q_vals + rowSums(err_sq) * dt
}
Q_max[b] <- max(Q_vals)
}
quantile(Q_max, probs = 1 - alpha)
}
UCL_Q <- UCL_Q_MFPCA_sim(simData = simData, alpha = alpha_boot, ncomp = ncomp, M = M,
R = R, nbasis = nbasis_monitor)
return(list(mfpca = mfpca, scores_mult = scores_mult, lambda_mult = lambda_mult, pca_uni = pca_uni,
T2 = T2_valores, UCL_T2 = UCL_T2, Q = Q_mult, UCL_Q = UCL_Q,
reconstruction = curvas_klmult))
}
### Función para calcular los índices de capacidad ---------------------------
indices_capacidad_mfpca <- function(sim_obj, analisis, USL, LSL, M = 3){
t_grid <- sim_obj$t
mean1 <- colMeans(sim_obj$X1)
mean2 <- colMeans(sim_obj$X2)
mean_fd1 <- funData( argvals = list(t_grid), X = matrix(mean1, nrow = 1))
mean_fd2 <- funData(argvals = list(t_grid), X = matrix(mean2, nrow = 1))
mean_mult <- multiFunData(mean_fd1, mean_fd2)
USL_fd1 <- funData(argvals = list(t_grid), X = matrix(USL[,1], nrow = 1))
USL_fd2 <- funData(argvals = list(t_grid), X = matrix(USL[,2], nrow = 1))
LSL_fd1 <- funData(argvals = list(t_grid), X = matrix(LSL[,1], nrow = 1))
LSL_fd2 <- funData(argvals = list(t_grid), X = matrix(LSL[,2], nrow = 1))
USL_fun <- multiFunData(USL_fd1, USL_fd2)
LSL_fun <- multiFunData( LSL_fd1, LSL_fd2)
USL_centered <- USL_fun - mean_mult
LSL_centered <- LSL_fun - mean_mult
mfpca <- analisis$mfpca
USL_pc <- scalarProduct(USL_centered, mfpca$functions)
LSL_pc <- scalarProduct(LSL_centered, mfpca$functions)
lower <- pmin(LSL_pc, USL_pc)
upper <- pmax(LSL_pc, USL_pc)
scores_mult <- analisis$scores_mult
cuantiles <- function(x, probs = c(0.005, 0.5, 0.995)){
dens <- density(x, bw = "SJ")
dx <- dens$x
dy <- dens$y
cdf <- cumsum(dy) * mean(diff(dx))
cdf <- cdf / max(cdf)
approx(cdf, dx, xout = probs)$y
}
cuantiles_proc <- matrix(NA, nrow = M, ncol = 3)
for(i in 1:M){
cuantiles_proc[i, ] <- cuantiles(scores_mult[,i])
}
indices_cpk <- numeric(M)
for(i in 1:M){
indices_cpk[i] <- min((upper[i] - cuantiles_proc[i,2]) / (cuantiles_proc[i,3] - cuantiles_proc[i,2]),
(cuantiles_proc[i,2] - lower[i]) / (cuantiles_proc[i,2] - cuantiles_proc[i,1]))
}
MCnpk <- prod(indices_cpk)^(1/M)
return(list(lower = lower, upper = upper, indices_cpk = indices_cpk, MCnpk = MCnpk))
}
### Función para graficar los scores ---------------------
graf_scores <- function(analisis, capacidad, M = 3){
scores_mult <- analisis$scores_mult
lower <- capacidad$lower
upper <- capacidad$upper
par(mfrow = c(1, M))
for(m in 1:M){
plot(scores_mult[,m], pch = 16, cex = 0.8,col = "black",
xlab = "Observación", ylab = bquote(rho[.(m)]),
main = paste("Score", m), ylim = c(min(min(scores_mult[,m]),lower[m]), max(max(scores_mult[,m]),upper[m])))
abline(h = lower[m], col = "blue", lwd = 2, lty = 2)
abline(h = upper[m], col = "red", lwd = 2, lty = 2)
}
}
### Funcion para graficar los datos simulados con las especificaciones
graf_sim <- function(sim_obj, USL = NULL, LSL = NULL, ylim = NULL){
t_grid <- sim_obj$t
X_list <- list(sim_obj$X1, sim_obj$X2)
p <- length(X_list)
if(is.null(ylim)){
ymin_curvas <- min(sapply(X_list, min))
ymax_curvas <- max(sapply(X_list, max))
if(!is.null(LSL)){
ymin <- min(ymin_curvas, min(LSL))
} else{
ymin <- ymin_curvas
}
if(!is.null(USL)){
ymax <- max(ymax_curvas, max(USL))
} else{
ymax <- ymax_curvas
}
ylim <- c(ymin, ymax)
}
par(mfrow = c(1,p))
for(j in 1:p){
Xj <- X_list[[j]]
matplot(t_grid, t(Xj), type = "l", lty = 1, col = "grey", xlab = "t", ylab = "",
main = paste("Componente", j), ylim = ylim)
lines(t_grid, colMeans(Xj), lwd = 3, col = "black")
if(!is.null(USL)){lines(t_grid, USL[,j], col = "red", lwd = 3)
}
if(!is.null(LSL)){lines(t_grid, LSL[,j], col = "blue", lwd = 3)
}
}
}
scores_corr <- function(scores){
corr_mat <- cor(scores)
corrplot(corr_mat, method = "color", addCoef.col = "black",
number.cex = 0.8, tl.col = "black", tl.srt = 0, diag = TRUE
)
}Se simulan observaciones que presenten baja variabilidad y baja correlación entre componentes funcionales.
Code
Sigma1 <- matrix(c(
0.5, 0.0, 0.0, 0.08, 0.03, 0.01,
0.0, 0.3, 0.0, 0.03, 0.07, 0.02,
0.0, 0.0, 0.1, 0.01, 0.02, 0.04,
0.08, 0.03, 0.01, 0.5, 0.0, 0.0,
0.03, 0.07, 0.02, 0.0, 0.3, 0.0,
0.01, 0.02, 0.04, 0.0, 0.0, 0.1
), nrow = 6, byrow = TRUE)
sim1 <- sim_mfpca_fourier(n = 250 , nbasis = 3, M = 6, seed = 123, Sigma = Sigma1)
graf_sim(sim_obj = sim1, USL = USL, LSL = LSL)Code
analisis1 <- analisis_mfpca(sim_obj = sim1, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis1$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis1$UCL_T2))
abline(h = analisis1$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis1$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis1$UCL_Q))
abline(h = analisis1$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis1$reconstruction)Code
t_grid <- sim1$t
capacidad1 <- indices_capacidad_mfpca(sim_obj = sim1, analisis = analisis1,
USL = USL, LSL = LSL, M = 3)
capacidad1$indices_cpk[1] 2.4213253 0.9354403 0.5676756
Code
capacidad1$MCnpk[1] 1.087401
Code
graf_scores(analisis1, capacidad1, M=3)Code
scores_corr(analisis1$scores_mult)
# scores univariados
scores_uni1 <- cbind(analisis1$pca_uni[[1]]$scores, analisis1$pca_uni[[2]]$scores)
corrplot(cor(scores_uni1), method = "color", addCoef.col = "black", tl.col = "black",
tl.srt = 45)Se simulan observaciones que presenten variabilidad media y baja correlación entre componentes funcionales.
Code
Sigma2 <- matrix(c(
0.8, 0.0, 0.0, 0.25, 0.12, 0.05,
0.0, 0.4, 0.0, 0.12, 0.20, 0.08,
0.0, 0.0, 0.2, 0.05, 0.08, 0.12,
0.25, 0.12, 0.05, 0.8, 0.0, 0.0,
0.12, 0.20, 0.08, 0.0, 0.4, 0.0,
0.05, 0.08, 0.12, 0.0, 0.0, 0.2
), nrow = 6, byrow = TRUE)
sim2 <- sim_mfpca_fourier(n = 250, nbasis = 3, M = 6, seed = 123, Sigma = Sigma2)
graf_sim(sim_obj = sim2, USL = USL, LSL = LSL)Code
analisis2 <- analisis_mfpca(sim_obj = sim2, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis2$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis2$UCL_T2))
abline(h = analisis2$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis2$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis2$UCL_Q))
abline(h = analisis2$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis2$reconstruction)Code
t_grid <- sim2$t
capacidad2 <- indices_capacidad_mfpca(sim_obj = sim2, analisis = analisis2,
USL = USL, LSL = LSL, M = 3)
capacidad2$indices_cpk[1] 1.86165553 0.08132553 0.71820595
Code
capacidad2$MCnpk[1] 0.4773003
Code
graf_scores(analisis2, capacidad2, M=3)Code
scores_corr(analisis2$scores_mult)
# scores univariados
scores_uni2 <- cbind(analisis2$pca_uni[[1]]$scores, analisis2$pca_uni[[2]]$scores)
corrplot(cor(scores_uni2), method = "color", addCoef.col = "black", tl.col = "black",
tl.srt = 45)Se simulan observaciones que presenten variabilidad moderada-alta y correlación moderada entre componentes funcionales.
Code
Sigma3 <- matrix(c(
1.0, 0.0, 0.0, 0.40, 0.22, 0.10,
0.0, 0.6, 0.0, 0.22, 0.30, 0.12,
0.0, 0.0, 0.3, 0.10, 0.12, 0.10,
0.40, 0.22, 0.10, 1.2, 0.0, 0.0,
0.22, 0.30, 0.12, 0.0, 0.64, 0.0,
0.10, 0.12, 0.10, 0.0, 0.0, 0.2
), nrow = 6, byrow = TRUE)
sim3 <- sim_mfpca_fourier(n = 250, nbasis = 3, M = 6, seed = 123, Sigma = Sigma3)
graf_sim(sim_obj = sim3, USL = USL, LSL = LSL)Code
analisis3 <- analisis_mfpca(sim_obj = sim3, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis3$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis3$UCL_T2))
abline(h = analisis3$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis3$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis3$UCL_Q))
abline(h = analisis3$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis3$reconstruction)Code
t_grid <- sim3$t
capacidad3 <- indices_capacidad_mfpca(sim_obj = sim3, analisis = analisis3,
USL = USL, LSL = LSL, M = 3)
capacidad3$indices_cpk[1] 1.4392968 0.5894751 0.8043269
Code
capacidad3$MCnpk[1] 0.8804056
Code
graf_scores(analisis3, capacidad3, M=3)Code
scores_corr(analisis3$scores_mult)
# scores univariados
scores_uni3 <- cbind(analisis3$pca_uni[[1]]$scores, analisis3$pca_uni[[2]]$scores)
corrplot(cor(scores_uni3), method = "color", addCoef.col = "black", tl.col = "black",
tl.srt = 45)Se simulan observaciones que presenten alta variabilidad y correlación moderada-alta entre componentes funcionales.
Code
Sigma4 <- matrix(c(
2.5, 0.0, 0.0, 0.02, 0.35, 0.15,
0.0, 1, 0.0, 0.25, 0.05, 0.20,
0.0, 0.0, 0.4, 0.15, 0.20, 0.04,
0.02, 0.25, 0.15, 1.5, 0.0, 0.0,
0.35, 0.05, 0.20, 0.0, 0.8, 0.0,
0.15, 0.20, 0.04, 0.0, 0.0, 0.2
), nrow = 6, byrow = TRUE)
sim4 <- sim_mfpca_fourier(n = 250, nbasis = 3, M = 6, seed = 123, Sigma = Sigma4)
analisis4 <- analisis_mfpca(sim_obj = sim4, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
graf_sim(sim_obj = sim4, USL = USL, LSL = LSL)Code
# Carta T2
plot(analisis4$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis4$UCL_T2))
abline(h = analisis4$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis4$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis4$UCL_Q))
abline(h = analisis4$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis4$reconstruction)Code
t_grid <- sim4$t
capacidad4 <- indices_capacidad_mfpca(sim_obj = sim4, analisis = analisis4,
USL = USL, LSL = LSL, M = 3)
capacidad4$indices_cpk[1] 0.6827604 1.3134108 0.4021197
Code
capacidad4$MCnpk[1] 0.7117729
Code
graf_scores(analisis4, capacidad4, M=3)Code
scores_corr(analisis4$scores_mult)
# scores univariados
scores_uni4 <- cbind(analisis4$pca_uni[[1]]$scores, analisis4$pca_uni[[2]]$scores)
corrplot(cor(scores_uni4), method = "color", addCoef.col = "black", tl.col = "black",
tl.srt = 45)Se simulan observaciones que presenten alta variabilidad y alta correlación entre componentes funcionales.
Code
Sigma5 <- matrix(c(
2.4, 0.0, 0.0, 0.70, 0.35, 0.15,
0.0, 0.8, 0.0, 0.35, 0.45, 0.18,
0.0, 0.0, 0.5, 0.15, 0.18, 0.18,
0.70, 0.35, 0.15, 2.6, 0.0, 0.0,
0.35, 0.45, 0.18, 0.0, 1.0, 0.0,
0.15, 0.18, 0.18, 0.0, 0.0, 0.4
), nrow = 6, byrow = TRUE)
sim5 <- sim_mfpca_fourier(n = 250, nbasis = 3, M = 6, seed = 123, Sigma = Sigma5)
graf_sim(sim_obj = sim5, USL = USL, LSL = LSL)Code
analisis5 <- analisis_mfpca(sim_obj = sim5, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis5$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis5$UCL_T2))
abline(h = analisis5$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis5$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis5$UCL_Q))
abline(h = analisis5$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis5$reconstruction)Code
t_grid <- sim5$t
capacidad5 <- indices_capacidad_mfpca(sim_obj = sim5, analisis = analisis5,
USL = USL, LSL = LSL, M = 3)
capacidad5$indices_cpk[1] 1.0596171 0.3468498 0.2982798
Code
capacidad5$MCnpk[1] 0.4785986
Code
graf_scores(analisis5, capacidad5, M=3)Code
scores_corr(analisis5$scores_mult)
# scores univariados
scores_uni5 <- cbind(analisis5$pca_uni[[1]]$scores, analisis5$pca_uni[[2]]$scores)
corrplot(cor(scores_uni5), method = "color", addCoef.col = "black", tl.col = "black",
tl.srt = 45)Se simulan observaciones que presenten alta variabilidad y baja correlación entre componentes funcionales.
Code
Sigma6 <- matrix(c(
1.8, 0.0, 0.0, 0.18, 0.08, 0.04,
0.0, 1.1, 0.0, 0.08, 0.15, 0.06,
0.0, 0.0, 0.7, 0.04, 0.06, 0.10,
0.18, 0.08, 0.04, 1.7, 0.0, 0.0,
0.08, 0.15, 0.06, 0.0, 1.0, 0.0,
0.04, 0.06, 0.10, 0.0, 0.0, 0.6
), nrow = 6, byrow = TRUE)
sim6 <- sim_mfpca_fourier(n = 250, nbasis = 3, M = 6, seed = 123, Sigma = Sigma6)
graf_sim(sim_obj = sim6, USL = USL, LSL = LSL)Code
analisis6 <- analisis_mfpca(sim_obj = sim6, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis6$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis6$UCL_T2))
abline(h = analisis6$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis6$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis6$UCL_Q))
abline(h = analisis6$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis6$reconstruction)Code
t_grid <- sim6$t
capacidad6 <- indices_capacidad_mfpca(sim_obj = sim6, analisis = analisis6,
USL = USL, LSL = LSL, M = 3)
capacidad6$indices_cpk[1] 1.1131298 1.0488950 0.2497074
Code
capacidad6$MCnpk[1] 0.6630858
Code
graf_scores(analisis6, capacidad6, M=3)Code
scores_corr(analisis6$scores_mult)
# scores univariados
scores_uni6 <- cbind(analisis6$pca_uni[[1]]$scores, analisis6$pca_uni[[2]]$scores)
corrplot(cor(scores_uni6), method = "color", addCoef.col = "black", tl.col = "black",
tl.srt = 45)Resultados
Code
resultados_dependencia <- data.frame(
Escenario = c(
"Escenario 1",
"Escenario 2",
"Escenario 3",
"Escenario 4",
"Escenario 5",
"Escenario 6"
),
Variabilidad = c(
"Baja",
"Media",
"Moderada-Alta",
"Alta",
"Alta",
"Alta"
),
Covarianza = c(
"Baja",
"Moderada",
"Moderada",
"Moderada-Alta",
"Alta",
"Baja"
),
Cpk_1 = c(
capacidad1$indices_cpk[1],
capacidad2$indices_cpk[1],
capacidad3$indices_cpk[1],
capacidad4$indices_cpk[1],
capacidad5$indices_cpk[1],
capacidad6$indices_cpk[1]
),
Cpk_2 = c(
capacidad1$indices_cpk[2],
capacidad2$indices_cpk[2],
capacidad3$indices_cpk[2],
capacidad4$indices_cpk[2],
capacidad5$indices_cpk[2],
capacidad6$indices_cpk[2]
),
Cpk_3 = c(
capacidad1$indices_cpk[3],
capacidad2$indices_cpk[3],
capacidad3$indices_cpk[3],
capacidad4$indices_cpk[3],
capacidad5$indices_cpk[3],
capacidad6$indices_cpk[3]
),
MCpk = c(
capacidad1$MCnpk,
capacidad2$MCnpk,
capacidad3$MCnpk,
capacidad4$MCnpk,
capacidad5$MCnpk,
capacidad6$MCnpk
)
)
resultados_dependencia[,4:7] <- round(
resultados_dependencia[,4:7],
3
)
knitr::kable(
resultados_dependencia,
caption = "Índices de capacidad para distintos escenarios de dependencia"
)| Escenario | Variabilidad | Covarianza | Cpk_1 | Cpk_2 | Cpk_3 | MCpk |
|---|---|---|---|---|---|---|
| Escenario 1 | Baja | Baja | 2.421 | 0.935 | 0.568 | 1.087 |
| Escenario 2 | Media | Moderada | 1.862 | 0.081 | 0.718 | 0.477 |
| Escenario 3 | Moderada-Alta | Moderada | 1.439 | 0.589 | 0.804 | 0.880 |
| Escenario 4 | Alta | Moderada-Alta | 0.683 | 1.313 | 0.402 | 0.712 |
| Escenario 5 | Alta | Alta | 1.060 | 0.347 | 0.298 | 0.479 |
| Escenario 6 | Alta | Baja | 1.113 | 1.049 | 0.250 | 0.663 |
Simulación 2
Para simular las observaciones funcionales multivariadas, en primer lugar se generan las bases de funciones propias univariadas para cada uno de los \(p\) procesos funcionales. Para el \(j\)-ésimo proceso, se consideran \(M_j\) funciones base \(\phi_m^{(j)}\), las cuales representan las principales direcciones de variación de cada componente funcional.
Posteriormente, se define una matriz de correlaciones entre procesos
\[ R = \begin{pmatrix} 1 & r_{12} & \cdots & r_{1p} \\ r_{21} & 1 & \cdots & r_{2p} \\ \vdots & \vdots & \ddots & \vdots \\ r_{p1} & r_{p2} & \cdots & 1 \end{pmatrix}, \]
donde cada elemento \(r_{ij}\) representa la correlación entre los procesos \(i\) y \(j\). Esta matriz se utiliza para construir una matriz de covarianzas conjunta \(\mathbf{Z}\) entre los scores univariados de todos los procesos.
Las entradas de \(\mathbf{Z}\) están dadas por
\[ Z_{mn}^{(ij)} = \operatorname{Cov}(\xi_m^{(i)},\xi_n^{(j)}). \]
Dentro de un mismo proceso, las covarianzas corresponden a los valores propios asociados a las funciones base univariadas. Para procesos distintos, las covarianzas se definen mediante
\[ Z_{mn}^{(ij)} = \text{Cov}(\xi_{m}^{(i)}, \xi_{n}^{(j)}) = r_{ij}\exp(-\alpha |m-n|) \sqrt{\lambda_m^{(i)}\lambda_n^{(j)}}, \]
donde \(\alpha > 0\) controla el decrecimiento de la correlación entre componentes de diferente orden. De esta forma, la correlación entre procesos se incorpora en la estructura de covarianza de los scores.
A partir de la matriz \(\mathbf{Z}\), se generan muestras de scores univariados utilizando una distribución normal multivariada. Luego, se realiza la descomposición espectral de \(\mathbf{Z}\) para obtener sus valores propios y vectores propios, los cuales permiten construir tanto los scores multivariados \(\rho_{im}\) como las funciones propias multivariadas \(\boldsymbol{\psi}_m\).
Finalmente, las observaciones funcionales multivariadas se generan utilizando la expansión truncada de Karhunen–Loève
\[ \mathbf{X}_i(\mathbf{t}) = \sum_{m=1}^{M} \rho_{im}\boldsymbol{\psi}_m(\mathbf{t}), \qquad i=1,\ldots,N. \]
Equivalentemente, para cada proceso \(j=1,\ldots,p\),
\[ X_i^{(j)}(t_j) = \sum_{m=1}^{M} \rho_{im}\psi_m^{(j)}(t_j). \]
Funciones utilizadas
Code
MultiScores <- function(scores, Z, M){
scores <- scale(scores, center = TRUE, scale = FALSE)
eig <- eigen(Z, symmetric = TRUE)
TrueVals <- eig$values[1:M]
Cvec <- eig$vectors[, 1:M, drop = FALSE]
rho <- scores %*% Cvec
return(list(MultiScores = rho,
TrueVals = TrueVals,
Cvec = Cvec))
}
simMultiScores <- function(N, M, multiM, correlations, type){
p <- length(M)
Mtotal <- sum(M)
# Matriz de correlaciones entre los procesos
if (length(correlations) == 1) {
R <- matrix(correlations, p, p)
diag(R) <- 1
} else {
R <- matrix(1, p, p)
R[upper.tri(R)] <- correlations
R[lower.tri(R)] <- t(R)[lower.tri(R)]
}
# Valores propios
lambdas <- lapply(M, function(m) {
eVal(M = m, type = type)
})
# Construcción matriz de covarianzas
bloques <- split(1:Mtotal, rep(1:p, M))
Z <- matrix(0, Mtotal, Mtotal)
## Dentro de cada proceso
for (j in 1:p) {
Z[bloques[[j]], bloques[[j]]] <- diag(lambdas[[j]])
}
## Covarianzas entre procesos
for (j in 1:(p - 1)) {
for (k in (j + 1):p) {
for (m in 1:M[j]) {
for (n in 1:M[k]) {
a <- bloques[[j]][m]
b <- bloques[[k]][n]
rho_mn <- R[j, k] * exp(- 3 * abs(m - n))
Z[a, b] <- rho_mn * sqrt(lambdas[[j]][m] * lambdas[[k]][n])
Z[b, a] <- Z[a, b]
}
}
}
}
if (min(eigen(Z, symmetric = TRUE)$values) < -1e-8) {
stop("La matriz Z no es semidefinida positiva")
}
# Simular matriz de scores Xi
Xi <- mvrnorm(n = N, mu = rep(0, Mtotal), Sigma = Z)
# Construir los scores multivariados
multiScores <- MultiScores(scores = Xi, Z = Z, M = multiM)
return(list(UniScores = Xi,
MultiScores = multiScores$MultiScores,
TrueVals = multiScores$TrueVals,
Cvec = multiScores$Cvec,
Z = Z))
}
simUniBasis <- function(argvals, Ms, eFunType, eValType){
p <- length(argvals)
uniBasis <- vector("list", p)
for(j in seq_len(p)){
M <- if(is.list(Ms)) Ms[[j]] else Ms[j]
eFun <- if(is.list(eFunType)) eFunType[[j]] else eFunType
uniBasis[[j]] <- simFunData(N = 1,
argvals = argvals[[j]],
M = M,
eFunType = eFun,
eValType = eValType)$trueFuns
}
return(uniBasis)
}
buildMultiFuns <- function(uniBasis, Cvec, M){
p <- length(uniBasis)
# Número de bases univariadas por proceso
Ms <- sapply(uniBasis, nObs)
# Bloques del vector propio asociados a cada proceso
bloques <- split(seq_len(sum(Ms)), rep(seq_len(p), Ms))
trueFuns <- vector("list", p)
for(j in seq_len(p)){
Phi <- uniBasis[[j]]@X
dims_phi <- dim(Phi)
# Matriz de funciones base
Phi_mat <- matrix(Phi, nrow = Ms[j])
# Coeficientes del proceso j en los vectores propios de Z
C <- Cvec[bloques[[j]], 1:M, drop = FALSE]
# Construcción de la función propia
Psi_mat <- t(C) %*% Phi_mat
# Objeto funData
Psi <- array(Psi_mat, dim = c(M, dims_phi[-1]))
trueFuns[[j]] <- funData(
argvals = uniBasis[[j]]@argvals,
X = Psi
)
}
return(multiFunData(trueFuns))
}
simMultiCorr <- function(type,
argvals,
M,
Ms,
eFunType,
eValType,
N,
correlations,
ignoreDeg = NULL){
# Bases de funciones univariadas por proceso
uniBasis <- simUniBasis(argvals = argvals,
Ms = Ms,
eFunType = eFunType,
eValType = eValType)
Mscores <- sapply(uniBasis, nObs)
# Se generan los valores propios y scores con correlación
multiScores <- simMultiScores(N = N,
M = Mscores,
multiM = M,
correlations = correlations,
type = eValType)
trueVals <- multiScores$TrueVals
scores <- multiScores$MultiScores
Cvec <- multiScores$Cvec
# Construcción de funciones propias multivariadas
trueFuns <- buildMultiFuns(uniBasis = uniBasis,
Cvec = Cvec,
M = M)
Mtotal <- nObs(trueFuns)
p <- length(trueFuns)
# Simulación de los datos
simData <- vector("list", p)
for (j in seq_len(p)) {
X <- apply(trueFuns[[j]]@X, -1, function(v) {
scores %*% v
})
if (N == 1) {
dim(X) <- c(1, nObsPoints(trueFuns[[j]]))
}
simData[[j]] <- funData(trueFuns[[j]]@argvals, X)
}
return(list(simData = multiFunData(simData), trueFuns = trueFuns,
trueVals = trueVals))
}
### Función para cartas de control ------------------------------------------
analisis_mfpca2 <- function(sim_obj, alpha = 0.01, ncomp = 3, M = 3, R = 500,
nbasis_monitor = 9
){
simData <- sim_obj$simData
p <- length(simData)
uni_exp <- vector("list", length = p)
pca_uni <- vector("list", length = p)
FourierBasis <- create.fourier.basis(rangeval = c(0,1), nbasis = nbasis_monitor)
for(j in 1:p){
fd_j <- funData2fd(simData[[j]], basisobj = FourierBasis)
pca_j <- pca.fd(fd_j, nharm = ncomp, centerfns = TRUE)
uni_exp[[j]] <- list(type = "given", functions = fd2funData(pca_j$harmonics,
argvals = simData[[j]]@argvals),
scores = pca_j$scores)
pca_uni[[j]] <- pca_j
}
mfpca <- MFPCA(mFData = simData, M = M, uniExpansions = uni_exp)
scores_mult <- mfpca$scores
lambda_mult <- mfpca$values
T2_valores <- rowSums(sweep(scores_mult[,1:M]^2, 2, lambda_mult[1:M], "/"))
alpha_boot <- 1 - sqrt(1 - alpha)
UCL_T2_MFPCA_sim <- function(simData, alpha, ncomp = 3, M = M, R = R, nbasis = 9
){
p <- length(simData)
n <- nObs(simData)
t_grid <- simData[[1]]@argvals[[1]]
FourierBasis <- create.fourier.basis(rangeval = range(t_grid),
nbasis = nbasis)
T2_vmax <- numeric(R)
for(i in 1:R){
indices <- sample(1:n, n, replace = TRUE)
lista_funData <- vector("list", p)
for(k in 1:p){
Xk <- simData[[k]]@X[indices, ]
lista_funData[[k]] <- funData(argvals = list(t_grid), X = Xk)
}
mfData_boot <- multiFunData(lista_funData)
uni_exp <- vector("list", p)
for(j in 1:p){
fd_j <- funData2fd(mfData_boot[[j]], basisobj = FourierBasis)
pca_j <- pca.fd(fd_j, nharm = ncomp, centerfns = TRUE)
uni_exp[[j]] <- list(type = "given",
functions = fd2funData(pca_j$harmonics,
argvals = mfData_boot[[j]]@argvals),
scores = pca_j$scores)
}
mfpca_boot <- MFPCA(mFData = mfData_boot, M = M, uniExpansions = uni_exp)
scores_boot <- mfpca_boot$scores[,1:M]
lambda_boot <- mfpca_boot$values[1:M]
T2_vals <- rowSums(sweep(scores_boot^2, 2, lambda_boot, "/"))
T2_vmax[i] <- max(T2_vals)
}
quantile(T2_vmax, probs = 1 - alpha)
}
UCL_T2 <- UCL_T2_MFPCA_sim(simData = simData, alpha = alpha_boot, ncomp = ncomp, M = M,
R = R, nbasis = nbasis_monitor)
curvas_klmult <- predict(mfpca, scores = mfpca$scores)
n <- nObs(simData)
t_grid <- simData[[1]]@argvals[[1]]
dt <- diff(t_grid)[1]
Q_mult <- rep(0, n)
for(i in 1:p){
X_orig <- simData[[i]]@X
X_hat <- curvas_klmult[[i]]@X
error <- X_orig - X_hat
Q_mult <- Q_mult + rowSums(error^2) * dt
}
UCL_Q_MFPCA_sim <- function(simData, alpha, ncomp, M, R, nbasis){
p <- length(simData)
n <- nObs(simData)
t_grid <- simData[[1]]@argvals[[1]]
dt <- diff(t_grid)[1]
FourierBasis <- create.fourier.basis(rangeval = range(t_grid), nbasis = nbasis)
Q_max <- numeric(R)
for(b in 1:R){
indices <- sample(1:n, n, replace = TRUE)
lista_funData <- vector("list", p)
for(j in 1:p){
Xj <- simData[[j]]@X[indices, ]
lista_funData[[j]] <- funData(argvals = list(t_grid), X = Xj)
}
mfData_boot <- multiFunData(lista_funData)
uni_exp <- vector("list", p)
for(j in 1:p){
fd_j <- funData2fd(mfData_boot[[j]], basisobj = FourierBasis)
pca_j <- pca.fd(fd_j, nharm = ncomp, centerfns = TRUE)
uni_exp[[j]] <- list(type = "given",
functions = fd2funData(pca_j$harmonics, argvals = mfData_boot[[j]]@argvals),
scores = pca_j$scores)
}
mfpca_boot <- MFPCA(mFData = mfData_boot, M = M, uniExpansions = uni_exp,
fit = TRUE)
residuos <- mfData_boot - mfpca_boot$fit
Q_vals <- rep(0, n)
for(j in 1:p){
err_sq <- residuos[[j]]@X^2
Q_vals <- Q_vals + rowSums(err_sq) * dt
}
Q_max[b] <- max(Q_vals)
}
quantile(Q_max, probs = 1 - alpha)
}
UCL_Q <- UCL_Q_MFPCA_sim(simData = simData, alpha = alpha_boot, ncomp = ncomp, M = M,
R = R, nbasis = nbasis_monitor)
return(list(mfpca = mfpca, scores_mult = scores_mult, lambda_mult = lambda_mult, pca_uni = pca_uni,
T2 = T2_valores, UCL_T2 = UCL_T2, Q = Q_mult, UCL_Q = UCL_Q,
reconstruction = curvas_klmult))
}
### Función para calcular los índices de capacidad ---------------------------
indices_capacidad_mfpca2 <- function(sim_obj, analisis, USL, LSL, M = 3){
simData <- sim_obj$simData
p <- length(simData)
mean_list <- vector("list", p)
for(j in seq_len(p)){
mean_j <- colMeans(simData[[j]]@X)
mean_list[[j]] <- funData(
argvals = simData[[j]]@argvals,
X = matrix(mean_j, nrow = 1)
)
}
mean_mult <- multiFunData(mean_list)
USL_list <- vector("list", p)
LSL_list <- vector("list", p)
for(j in seq_len(p)){
USL_list[[j]] <- funData(argvals = simData[[j]]@argvals, X = matrix(USL[[j]], nrow = 1))
LSL_list[[j]] <- funData(argvals = simData[[j]]@argvals, X = matrix(LSL[[j]], nrow = 1)
)
}
USL_fun <- multiFunData(USL_list)
LSL_fun <- multiFunData(LSL_list)
USL_centered <- USL_fun - mean_mult
LSL_centered <- LSL_fun - mean_mult
mfpca <- analisis$mfpca
USL_pc <- scalarProduct(USL_centered, mfpca$functions)
LSL_pc <- scalarProduct(LSL_centered, mfpca$functions)
lower <- pmin(LSL_pc, USL_pc)
upper <- pmax(LSL_pc, USL_pc)
scores_mult <- analisis$scores_mult
cuantiles <- function(x, probs = c(0.005, 0.5, 0.995)){
dens <- density(x, bw = "SJ")
dx <- dens$x
dy <- dens$y
cdf <- cumsum(dy) * mean(diff(dx))
cdf <- cdf / max(cdf)
approx(cdf, dx, xout = probs)$y
}
cuantiles_proc <- matrix(NA, nrow = M, ncol = 3)
for(i in 1:M){
cuantiles_proc[i, ] <- cuantiles(scores_mult[, i])
}
indices_cpk <- numeric(M)
for(i in 1:M){
indices_cpk[i] <-
min((upper[i] - cuantiles_proc[i,2]) / (cuantiles_proc[i,3] - cuantiles_proc[i,2]),
(cuantiles_proc[i,2] - lower[i]) / (cuantiles_proc[i,2] - cuantiles_proc[i,1])
)
}
MCnpk <- prod(indices_cpk)^(1/M)
return(list(lower = lower, upper = upper, indices_cpk = indices_cpk, MCnpk = MCnpk
))
}
### Función para graficar los scores ---------------------
graf_scores <- function(analisis, capacidad, M = 3){
scores_mult <- analisis$scores_mult
lower <- capacidad$lower
upper <- capacidad$upper
par(mfrow = c(1, M))
for(m in 1:M){
plot(scores_mult[,m], pch = 16, cex = 0.8,col = "black",
xlab = "Observación", ylab = bquote(rho[.(m)]),
main = paste("Score", m), ylim = c(min(min(scores_mult[,m]),lower[m]), max(max(scores_mult[,m]),upper[m])))
abline(h = lower[m], col = "blue", lwd = 2, lty = 2)
abline(h = upper[m], col = "red", lwd = 2, lty = 2)
}
}
### Funcion para graficar los datos simulados con las especificaciones
graf_sim2 <- function(sim_obj, USL = NULL, LSL = NULL, ylim = NULL){
simData <- sim_obj$simData
p <- length(simData)
X_list <- lapply(simData, function(fd) fd@X)
if(is.null(ylim)){
ymin_curvas <- min(sapply(X_list, min))
ymax_curvas <- max(sapply(X_list, max))
ymin <- ymin_curvas
ymax <- ymax_curvas
if(!is.null(LSL)){
ymin <- min(ymin, min(unlist(LSL)))
}
if(!is.null(USL)){
ymax <- max(ymax, max(unlist(USL)))
}
ylim <- c(ymin, ymax)
}
par(mfrow = c(1, p))
for(j in seq_len(p)){
t_grid <- simData[[j]]@argvals[[1]]
Xj <- simData[[j]]@X
matplot(t_grid, t(Xj), type = "l", lty = 1, col = "grey", xlab = "t", ylab = "",
main = paste("Componente", j), ylim = ylim)
lines(t_grid, colMeans(Xj), lwd = 3, col = "black")
if(!is.null(USL)){
lines(t_grid, USL[[j]], col = "red", lwd = 3)
}
if(!is.null(LSL)){
lines(t_grid, LSL[[j]], col = "blue", lwd = 3)
}
}
}
USL_sim2 <- list(USL1, USL2)
LSL_sim2 <- list(LSL1, LSL2)Code
t1 <- seq(0, 1, length.out = 200)
t2 <- seq(0, 1, length.out = 200)
argvals <- list(t1, t2)
sim21 <- simMultiCorr(type = "split", argvals = argvals, M = 3,
Ms= c(3,3), eFunType = "Fourier",
eValType = "linear", N = 250,
correlations = 0.1)
graf_sim2(sim_obj = sim21, USL = USL_sim2, LSL = LSL_sim2)Code
analisis21 <- analisis_mfpca2(sim_obj = sim21, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis21$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis21$UCL_T2))
abline(h = analisis21$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis21$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis21$UCL_Q))
abline(h = analisis21$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis21$reconstruction)Code
capacidad21 <- indices_capacidad_mfpca(sim_obj = sim21, analisis = analisis21,
USL = USL_sim2, LSL = LSL_sim2, M = 3)
capacidad21$indices_cpk[1] 1.8052313 0.1204218 0.7505375
Code
capacidad21$MCnpk[1] 0.5464328
Code
graf_scores(analisis21, capacidad21, M=3)Code
t1 <- seq(0, 1, length.out = 200)
t2 <- seq(0, 1, length.out = 200)
argvals <- list(t1, t2)
sim22 <- simMultiCorr(type = "split", argvals = argvals, M = 3,
Ms= c(3,3), eFunType = "Fourier",
eValType = "linear", N = 250,
correlations = 0.4)
graf_sim2(sim_obj = sim22, USL = USL_sim2, LSL = LSL_sim2)Code
analisis22 <- analisis_mfpca2(sim_obj = sim22, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis22$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis22$UCL_T2))
abline(h = analisis22$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis22$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis22$UCL_Q))
abline(h = analisis22$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis22$reconstruction)Code
capacidad22 <- indices_capacidad_mfpca(sim_obj = sim22, analisis = analisis22,
USL = USL_sim2, LSL = LSL_sim2, M = 3)
capacidad22$indices_cpk[1] 1.7010183 0.3218521 0.2217070
Code
capacidad22$MCnpk[1] 0.495125
Code
graf_scores(analisis22, capacidad22, M=3)Code
t1 <- seq(0, 1, length.out = 200)
t2 <- seq(0, 1, length.out = 200)
argvals <- list(t1, t2)
sim23 <- simMultiCorr(type = "split", argvals = argvals, M = 3,
Ms= c(3,3), eFunType = "Fourier",
eValType = "linear", N = 250,
correlations = 0.7)
graf_sim2(sim_obj = sim23, USL = USL_sim2, LSL = LSL_sim2)Code
analisis23 <- analisis_mfpca2(sim_obj = sim23, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis23$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis23$UCL_T2))
abline(h = analisis23$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis23$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis23$UCL_Q))
abline(h = analisis23$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis23$reconstruction)Code
capacidad23 <- indices_capacidad_mfpca(sim_obj = sim23, analisis = analisis23,
USL = USL_sim2, LSL = LSL_sim2, M = 3)
capacidad23$indices_cpk[1] 1.50447995 0.02095069 -0.01153180
Code
capacidad23$MCnpk[1] NaN
Code
graf_scores(analisis23, capacidad23, M=3)Code
t1 <- seq(0, 1, length.out = 200)
t2 <- seq(0, 1, length.out = 200)
argvals <- list(t1, t2)
sim24 <- simMultiCorr(type = "split", argvals = argvals, M = 3,
Ms= c(3,3), eFunType = "Fourier",
eValType = "linear", N = 250,
correlations = 0.9)
graf_sim2(sim_obj = sim24, USL = USL_sim2, LSL = LSL_sim2)Code
analisis24 <- analisis_mfpca2(sim_obj = sim24, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis24$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis24$UCL_T2))
abline(h = analisis24$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis24$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis24$UCL_Q))
abline(h = analisis24$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis24$reconstruction)Code
capacidad24 <- indices_capacidad_mfpca(sim_obj = sim24, analisis = analisis24,
USL = USL_sim2, LSL = LSL_sim2, M = 3)
capacidad24$indices_cpk[1] 1.40880771 0.10856951 0.03470325
Code
capacidad24$MCnpk[1] 0.1744389
Code
graf_scores(analisis24, capacidad24, M=3)Code
t1 <- seq(0, 1, length.out = 200)
t2 <- seq(0, 1, length.out = 200)
argvals <- list(t1, t2)
sim25 <- simMultiCorr(type = "split", argvals = argvals, M = 3,
Ms= c(3,3), eFunType = "Fourier",
eValType = "exponential", N = 250,
correlations = 0.1)
graf_sim2(sim_obj = sim25, USL = USL_sim2, LSL = LSL_sim2)Code
analisis25 <- analisis_mfpca2(sim_obj = sim25, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis25$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis25$UCL_T2))
abline(h = analisis25$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis25$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis25$UCL_Q))
abline(h = analisis25$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis25$reconstruction)Code
capacidad25 <- indices_capacidad_mfpca(sim_obj = sim25, analisis = analisis25,
USL = USL_sim2, LSL = LSL_sim2, M = 3)
capacidad25$indices_cpk[1] 1.72783699 -0.01309271 0.10883342
Code
capacidad25$MCnpk[1] NaN
Code
graf_scores(analisis25, capacidad25, M=3)Code
t1 <- seq(0, 1, length.out = 200)
t2 <- seq(0, 1, length.out = 200)
argvals <- list(t1, t2)
sim26 <- simMultiCorr(type = "split", argvals = argvals, M = 3,
Ms= c(3,3), eFunType = "Fourier",
eValType = "exponential", N = 250,
correlations = 0.3)
graf_sim2(sim_obj = sim26, USL = USL_sim2, LSL = LSL_sim2)Code
analisis26 <- analisis_mfpca2(sim_obj = sim26, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis26$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis26$UCL_T2))
abline(h = analisis26$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis26$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis26$UCL_Q))
abline(h = analisis26$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis26$reconstruction)Code
capacidad26 <- indices_capacidad_mfpca(sim_obj = sim26, analisis = analisis26,
USL = USL_sim2, LSL = LSL_sim2, M = 3)
capacidad26$indices_cpk[1] 1.79309397 0.02712246 0.34650039
Code
capacidad26$MCnpk[1] 0.2563767
Code
graf_scores(analisis26, capacidad26, M=3)Code
t1 <- seq(0, 1, length.out = 200)
t2 <- seq(0, 1, length.out = 200)
argvals <- list(t1, t2)
sim27 <- simMultiCorr(type = "split", argvals = argvals, M = 3,
Ms= c(3,3), eFunType = "Fourier",
eValType = "exponential", N = 250,
correlations = 0.8)
graf_sim2(sim_obj = sim27, USL = USL_sim2, LSL = LSL_sim2)Code
analisis27 <- analisis_mfpca2(sim_obj = sim27, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis27$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis27$UCL_T2))
abline(h = analisis27$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis27$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis27$UCL_Q))
abline(h = analisis27$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis27$reconstruction)Code
capacidad27 <- indices_capacidad_mfpca(sim_obj = sim27, analisis = analisis27,
USL = USL_sim2, LSL = LSL_sim2, M = 3)
capacidad27$indices_cpk[1] 1.42859451 0.16627285 0.07208267
Code
capacidad27$MCnpk[1] 0.2577431
Code
graf_scores(analisis27, capacidad27, M=3)Code
t1 <- seq(0, 1, length.out = 200)
t2 <- seq(0, 1, length.out = 200)
argvals <- list(t1, t2)
sim28 <- simMultiCorr(type = "split", argvals = argvals, M = 3,
Ms= c(3,3), eFunType = "Fourier",
eValType = "exponential", N = 250,
correlations = 0.90)
graf_sim2(sim_obj = sim28, USL = USL_sim2, LSL = LSL_sim2)Code
analisis28 <- analisis_mfpca2(sim_obj = sim28, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis28$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis28$UCL_T2))
abline(h = analisis28$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis28$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis28$UCL_Q))
abline(h = analisis28$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis28$reconstruction)Code
capacidad28 <- indices_capacidad_mfpca(sim_obj = sim28, analisis = analisis28,
USL = USL_sim2, LSL = LSL_sim2, M = 3)
capacidad28$indices_cpk[1] 1.39074224 0.12825031 0.08157224
Code
capacidad28$MCnpk[1] 0.244127
Code
graf_scores(analisis28, capacidad28, M=3)Resultados
Code
resultados_dependencia2 <- data.frame(
Escenario = c(
"Escenario 1",
"Escenario 2",
"Escenario 3",
"Escenario 4",
"Escenario 5",
"Escenario 6",
"Escenario 7",
"Escenario 8"
),
eValType = c(
"linear",
"linear",
"linear",
"linear",
"exponential",
"exponential",
"exponential",
"exponential"
),
Correlación = c(0.1, 0.4, 0.7, 0.9, 0.1, 0.4, 0.7, 0.9),
Cpk_1 = c(
capacidad21$indices_cpk[1],
capacidad22$indices_cpk[1],
capacidad23$indices_cpk[1],
capacidad24$indices_cpk[1],
capacidad25$indices_cpk[1],
capacidad26$indices_cpk[1],
capacidad27$indices_cpk[1],
capacidad28$indices_cpk[1]
),
Cpk_2 = c(
capacidad21$indices_cpk[2],
capacidad22$indices_cpk[2],
capacidad23$indices_cpk[2],
capacidad24$indices_cpk[2],
capacidad25$indices_cpk[2],
capacidad26$indices_cpk[2],
capacidad27$indices_cpk[2],
capacidad28$indices_cpk[2]
),
Cpk_3 = c(
capacidad21$indices_cpk[3],
capacidad22$indices_cpk[3],
capacidad23$indices_cpk[3],
capacidad24$indices_cpk[3],
capacidad25$indices_cpk[3],
capacidad26$indices_cpk[3],
capacidad27$indices_cpk[3],
capacidad28$indices_cpk[3]
),
MCpk = c(
capacidad21$MCnpk,
capacidad22$MCnpk,
capacidad23$MCnpk,
capacidad24$MCnpk,
capacidad25$MCnpk,
capacidad26$MCnpk,
capacidad27$MCnpk,
capacidad28$MCnpk
)
)
resultados_dependencia[,3:6] <- round(
resultados_dependencia[,4:7],
3
)
knitr::kable(
resultados_dependencia2,
caption = "Índices de capacidad para distintos escenarios de dependencia"
)| Escenario | eValType | Correlación | Cpk_1 | Cpk_2 | Cpk_3 | MCpk |
|---|---|---|---|---|---|---|
| Escenario 1 | linear | 0.1 | 1.805231 | 0.1204218 | 0.7505375 | 0.5464328 |
| Escenario 2 | linear | 0.4 | 1.701018 | 0.3218521 | 0.2217070 | 0.4951250 |
| Escenario 3 | linear | 0.7 | 1.504480 | 0.0209507 | -0.0115318 | NaN |
| Escenario 4 | linear | 0.9 | 1.408808 | 0.1085695 | 0.0347033 | 0.1744389 |
| Escenario 5 | exponential | 0.1 | 1.727837 | -0.0130927 | 0.1088334 | NaN |
| Escenario 6 | exponential | 0.4 | 1.793094 | 0.0271225 | 0.3465004 | 0.2563767 |
| Escenario 7 | exponential | 0.7 | 1.428594 | 0.1662728 | 0.0720827 | 0.2577431 |
| Escenario 8 | exponential | 0.9 | 1.390742 | 0.1282503 | 0.0815722 | 0.2441270 |
Simulación 3
Funciones utilizadas
Code
library(fda)
library(MASS)
library(funData)
sim_multi <- function(N = 250, argvals, M = 3, Sigma, basis_type = "fourier"){
library(fda)
library(MASS)
library(funData)
p <- length(argvals)
if(nrow(Sigma) != M || ncol(Sigma) != M){
stop("Sigma debe ser M x M")
}
global_grid <- seq(0, p, length.out = 1000)
if(basis_type == "fourier"){
basis_global <- create.fourier.basis(rangeval = c(0, p), nbasis = M)
} else if(basis_type == "bspline"){
basis_global <- create.bspline.basis(rangeval = c(0, p), nbasis = M)
} else {
stop("basis_type debe ser 'fourier' o 'bspline'")
}
Phi_global <- eval.basis(global_grid, basis_global)[,1:M]
M_real <- ncol(Phi_global)
if(M_real != M){
warning(
paste(
"La base generó", M_real,
"funciones. Ajustando automáticamente."
)
)
if(nrow(Sigma) < M_real){
stop("Sigma tiene menor dimensión que la base generada")
}
Sigma <- Sigma[1:M_real, 1:M_real]
M <- M_real
}
Psi <- vector("list", p)
for(j in 1:p){
idx_j <- which(global_grid >= (j-1) &
global_grid <= j)
Psi_j <- Phi_global[idx_j, , drop = FALSE]
signs <- sample(c(-1,1), M, replace = TRUE)
Psi_j <- sweep(Psi_j, 2, signs, "*")
t_j <- argvals[[j]]
Psi_interp <- matrix(0, nrow = length(t_j), ncol = M)
local_grid <- seq(0,1,length.out=nrow(Psi_j))
for(m in 1:M){
Psi_interp[,m] <- approx(x = local_grid, y = Psi_j[,m], xout = t_j,
rule = 2)$y
}
for(m in 1:M){
norma <- sqrt(sum(Psi_interp[,m]^2) * mean(diff(t_j)))
Psi_interp[,m] <- Psi_interp[,m] / norma
}
Psi[[j]] <- Psi_interp
}
scores <- MASS::mvrnorm(n = N, mu = rep(0, M), Sigma = Sigma)
X <- vector("list", p)
for(j in 1:p){
X[[j]] <- scores %*% t(Psi[[j]])
}
simData <- vector("list", p)
for(j in 1:p){
simData[[j]] <- funData(argvals = list(argvals[[j]]), X = X[[j]])
}
trueFuns <- vector("list", p)
for(j in 1:p){
trueFuns[[j]] <- funData(argvals = list(argvals[[j]]), X = t(Psi[[j]]))
}
trueVals <- eigen(Sigma)$values
return(list(simData = multiFunData(simData), scores = scores, trueFuns = trueFuns,
trueVals = trueVals, argvals = argvals, X = X))
}2+1[1] 3
Escenario 1
Code
set.seed(NULL)
Sigma1 <- matrix(c(
0.5, 0.0, 0.0, 0.08, 0.03, 0.01,
0.0, 0.3, 0.0, 0.03, 0.07, 0.02,
0.0, 0.0, 0.1, 0.01, 0.02, 0.04,
0.08, 0.03, 0.01, 0.5, 0.0, 0.0,
0.03, 0.07, 0.02, 0.0, 0.3, 0.0,
0.01, 0.02, 0.04, 0.0, 0.0, 0.1
), nrow = 6, byrow = TRUE)
t1 <- seq(0, 1, length.out = 200)
t2 <- seq(0, 1, length.out = 200)
argvals <- list(t1, t2)
sim31 <- sim_multi(N=250, argvals = argvals, M=6, Sigma=Sigma1, basis_type = "fourier")
graf_sim2(sim_obj = sim31, USL = USL_sim2, LSL = LSL_sim2)Code
analisis31 <- analisis_mfpca2(sim_obj = sim31, alpha = 0.01, ncomp = 3, M = 3, R = 1000)
# Carta T2
plot(analisis31$T2, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = expression(T^2),
main = expression("Carta " * T^2), ylim = c(0, analisis31$UCL_T2))
abline(h = analisis31$UCL_T2, col = "red", lwd = 2, lty = 2)
# Carta Q
plot(analisis31$Q, type = "p", pch = 16, cex = 0.7, xlab = "Observación", ylab = "Q", main = "Carta Q",
ylim=c(0, analisis31$UCL_Q))
abline(h = analisis31$UCL_Q, col = "red", lwd = 2, lty = 2)Code
plot(analisis31$reconstruction)Code
capacidad31 <- indices_capacidad_mfpca2(sim_obj = sim31, analisis = analisis31,
USL = USL_sim2, LSL = LSL_sim2, M = 3)
capacidad31$indices_cpk[1] 0.9384136 1.6324881 0.3899048
Code
capacidad31$MCnpk[1] 0.8421723
Code
graf_scores(analisis31, capacidad31, M=3)Code
scores_corr(analisis31$scores_mult)
# scores univariados
scores_uni31 <- cbind(analisis31$pca_uni[[1]]$scores, analisis31$pca_uni[[2]]$scores)
corrplot(cor(scores_uni31), method = "color", addCoef.col = "black", tl.col = "black",
tl.srt = 45)