Se requiere que la densidad de una pieza de plástico usada en un teléfono celular sea de al menos 0.70 g/cm3. Las piezas se suministran en grandes lotes y se piensa usar un plan de aceptación por variables para evaluar los lotes. Se desea que un lote con 2% de unidades no conformes sea aceptado con una probabilidad del 90%, mientras que los lotes con 10% de unidades no conformes sean aceptados con una probabilidad de solo 6%.
AQL <- 0.02
alpha <- 0.10
Pa_AQL <- 1 - alpha
LTPD <- 0.10
beta <- 0.06
Pa_LTPD <- beta
library(AcceptanceSampling)
plan_conocida <- find.plan(PRP = c(AQL, 1 - alpha),
CRP = c(LTPD, beta),
type = "normal",
s.type = "known")
n_calculada <- plan_conocida$n
k_calculada <- plan_conocida$k
construirTabla(
data.frame(
Parametro = c("n (tamaño de muestra)", "k (constante de aceptación)"),
Valor = c(n_calculada, round(k_calculada, 5))
),
titulo = "Parámetros del muestreo (σ conocida)",
decimales = 5
)| Parametro | Valor |
|---|---|
| n (tamaño de muestra) | 14.00000 |
| k (constante de aceptación) | 1.71124 |
p <- seq(0, 0.14, 0.001)
plan1 <- OCvar(n = 14, k = 1.71124, pd = p, s.type = "known")
plot(p, plan1@paccept, type = 'l', lty = 1, col = 1,
xlab = 'Proporción de no conformes', ylab = 'OC')
legend(0.04, 0.95, c("Variable, sigma conocida"), lty = 1, col = 1)
grid()Con sigma conocida el plan dio n = 14 y k = 1.71124. O sea que se toman 14 piezas, se saca el promedio de la densidad y se acepta el lote si ese promedio queda al menos 1.71124 desviaciones estándar por encima de 0.70 g/cm³. La curva OC lo confirma: con 2% de no conformes el plan acepta más o menos el 90% de los lotes, y con 10% baja a cerca del 6%.
datos <- data.frame(
Elemento = c("LEI", "Punto 1 (calidad buena)", "Punto 2 (calidad mala)"),
Valor = c("0.70 g/cm³",
"p₁ = 0.02, Pa = 0.90, entonces α = 0.10",
"p₂ = 0.10, Pa = 0.06, entonces β = 0.06")
)
datos %>%
kbl(col.names = c("Datos", "Valor")) %>%
kable_styling(full_width = FALSE, position = "left")| Datos | Valor |
|---|---|
| LEI | 0.70 g/cm³ |
| Punto 1 (calidad buena) | p₁ = 0.02, Pa = 0.90, entonces α = 0.10 |
| Punto 2 (calidad mala) | p₂ = 0.10, Pa = 0.06, entonces β = 0.06 |
Los z se sacaron con la normal estándar (qnorm). Como
qnorm pide la probabilidad acumulada, se usa 1 - p.
z_p1 <- qnorm(1 - 0.02)
z_p2 <- qnorm(1 - 0.10)
z_alpha <- qnorm(1 - 0.10)
z_beta <- qnorm(1 - 0.06)
valores_z <- data.frame(
Parametro = c("z(p₁)", "z(p₂)", "z(α)", "z(β)"),
Probabilidad_Entrada = c("0.02", "0.10", "0.10", "0.06"),
Valor_Z = round(c(z_p1, z_p2, z_alpha, z_beta), 4)
)
tabla_valores_z <- kable(valores_z, digits = 4,
caption = "Valores Z calculados",
col.names = c("Parámetro", "Probabilidad de entrada", "Valor Z")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE, position = "center") %>%
row_spec(0, bold = TRUE, color = "white", background = "#264653")
tabla_valores_z| Parámetro | Probabilidad de entrada | Valor Z |
|---|---|---|
| z(p₁) | 0.02 | 2.0537 |
| z(p₂) | 0.10 | 1.2816 |
| z(α) | 0.10 | 1.2816 |
| z(β) | 0.06 | 1.5548 |
Se usan las fórmulas de las diapositivas:
\[n=\left(\frac{z_\alpha+z_\beta}{z_{p_1}-z_{p_2}}\right)^2=\left(\frac{1.2816+1.5548}{2.0537-1.2816}\right)^2=\left(\frac{2.8364}{0.7721}\right)^2\approx 13.5\;\to\; n=14\]
\[k=z_{p_1}-\frac{z_\alpha}{\sqrt{n}}=2.0537-\frac{1.2816}{\sqrt{14}}=2.0537-0.3425=1.7112\]
Primero se obtuvieron los z de la normal estándar que corresponden a
las proporciones y los riesgos del enunciado: z(p₁ = 2%) = 2.0537, z(p₂
= 10%) = 1.2816, z(α = 10%) = 1.2816 y z(β = 6%) = 1.5548. Con eso n dio
13.5 y se subió a n = 14. Para k se usó el n ya redondeado (14), y dio
1.7112, que es lo mismo que devuelve find.plan
(1.71124).
plan_desconocida <- find.plan(PRP = c(AQL, 1 - alpha),
CRP = c(LTPD, beta),
type = "normal",
s.type = "unknown")
tabla_plan_desconocida <- kable(
data.frame(
Parametro = c("n (tamaño de muestra)", "k (constante de aceptación)"),
Valor = c(plan_desconocida$n, round(plan_desconocida$k, 5))
),
caption = "Parámetros del muestreo (σ desconocida)",
col.names = c("Parámetro", "Valor")
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE, position = "center") %>%
row_spec(0, bold = TRUE, color = "white", background = "#264653")
tabla_plan_desconocida| Parámetro | Valor |
|---|---|
| n (tamaño de muestra) | 34.00000 |
| k (constante de aceptación) | 1.71694 |
Para σ desconocida se usó otra vez find.plan, pero con
s.type = "unknown", porque σ no se conoce y se estima con
la desviación estándar de la muestra (S). La función dio n = 34 y k =
1.716943. Es decir, se toman 34 piezas y el lote se acepta si (x̄ −
LEI)/S ≥ 1.7169. Comparado con el plan de σ conocida (n = 14), se
necesita más del doble de muestra, porque al estimar σ con S se mete más
incertidumbre y se compensa con más piezas.
n1 <- 14; k1 <- 1.71124
n2 <- 34; k2 <- 1.716943
tabla_comparacion_planes <- kable(
data.frame(
Plan = c("σ conocida", "σ desconocida"),
n = c(n1, n2),
k = c(k1, k2),
Razon_n2_n1 = c("", round(n2 / n1, 2))
),
caption = "Comparación de planes de muestreo (σ conocida vs. desconocida)",
col.names = c("Plan", "n (tamaño de muestra)", "k (constante de aceptación)", "Razón n2/n1")
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE, position = "center") %>%
row_spec(0, bold = TRUE, color = "white", background = "#264653")
tabla_comparacion_planes| Plan | n (tamaño de muestra) | k (constante de aceptación) | Razón n2/n1 |
|---|---|---|---|
| σ conocida | 14 | 1.711240 | |
| σ desconocida | 34 | 1.716943 | 2.43 |
p <- seq(0, 0.14, 0.001)
oc1 <- OCvar(n = n1, k = k1, pd = p, s.type = "known")
oc2 <- OCvar(n = n2, k = k2, pd = p, s.type = "unknown")
plot(p, oc1@paccept, type = "l", lty = 1, col = 1, lwd = 2,
xlab = "Proporcion de no conformidades", ylab = "Pa",
main = "Curva OC: sigma conocida vs. desconocida")
lines(p, oc2@paccept, lty = 2, col = 2, lwd = 2)
points(c(AQL, LTPD), c(Pa_AQL, Pa_LTPD), pch = 19, col = "blue")
legend("topright", c("Sigma conocida", "Sigma desconocida", "Puntos pedidos"),
lty = c(1, 2, NA), pch = c(NA, NA, 19), col = c(1, 2, "blue"), bty = "n")
grid()Aquí se compararon los dos planes. El de sigma conocida pide n igual a 14 y el de sigma desconocida pide n igual a 34, o sea unas 2.4 veces más piezas. La diferencia se debe a que cuando no conocemos sigma hay que estimarla con la desviación estándar muestral S que cambia de una muestra a otra y esa incertidumbre extra se compensa con más muestra. Por eso si existen datos históricos confiables de la variabilidad del proceso como en el ejemplo de las botellas de la clase conviene usarlos porque permiten inspeccionar menos piezas.
En las curvas OC la probabilidad de aceptar es casi 1 cuando hay pocos no conformes y se acerca a 0 cuando p pasa de 12%. Las dos curvas pasan por los puntos pedidos donde Pa es 0.90 con p de 2% y Pa es 0.06 con p de 10% así que ambos planes protegen igual al productor y al consumidor. Además las curvas casi se montan una encima de la otra o sea que discriminan igual entre lotes buenos y malos. La única diferencia está en el costo de inspección que es de 14 piezas contra 34.
Cuando la desviación estándar es desconocida y se estima con la muestra el plan resultante es n igual a 34 y k igual a 1.716943. Al compararlo con el plan de sigma conocida que tiene n igual a 14 y k igual a 1.71124 se observa que se necesitan unas 2.4 veces más unidades. La razón es que al no conocer sigma hay que estimarla con S que varía entre una muestra y otra y agrega incertidumbre. Para mantener los mismos riesgos de 10% y 6% esa incertidumbre se compensa con una muestra más grande. En cambio con sigma conocida lo único que varía es la media muestral por eso se alcanza una muestra menor. Los dos planes se comportan casi igual y la diferencia está en el costo de inspección.
datos_nuevos <- data.frame(
Elemento = c("Plan (literal b)", "LEI", "Muestra"),
Valor = c("n = 34, k = 1.716943",
"0.70 g/cm³",
"x̄ = 0.73 g/cm³, S = 0.018 g/cm³")
)
datos_nuevos %>%
kbl(col.names = c("Datos", "Valor")) %>%
kable_styling(full_width = FALSE, position = "left")| Datos | Valor |
|---|---|
| Plan (literal b) | n = 34, k = 1.716943 |
| LEI | 0.70 g/cm³ |
| Muestra | x̄ = 0.73 g/cm³, S = 0.018 g/cm³ |
Fórmula del método k con S:
\[Z_{LIE}=\frac{\bar{x}-LIE}{S}\]
Regla de decisión: si Z_LIE ≥ k se acepta el lote; si Z_LIE < k se rechaza.
Cálculo:
\[Z_{LIE}=\frac{0.73-0.70}{0.018}=\frac{0.03}{0.018}=1.667\]
Como 1.667 < 1.716943, no llega al k mínimo exigido, entonces el lote se rechaza.
Se despeja x̄ de la regla Z_LIE ≥ k:
\[\bar{x}\ \ge\ LIE + k\cdot S = 0.70 + (1.716943)(0.018) = 0.70 + 0.0309 = 0.7309\]
La regla para el inspector, con n = 34 unidades y S = 0.018 g/cm³, es: aceptar el lote solo si el promedio es mayor o igual a 0.7309 g/cm³. Como el promedio fue 0.73 g/cm³, el lote no cumple y se rechaza.
LEI <- 0.70; xbar <- 0.73; S <- 0.018
k <- 1.716943
Z <- (xbar - LEI) / S
Z_min <- LEI + k * S
decision <- ifelse(Z >= k, "Se ACEPTA el lote", "Se RECHAZA el lote")
tabla_decision_lote <- kable(
data.frame(
Parametro = c("LEI (g/cm³)", "Promedio de la muestra (x̄)", "Desviación estándar (S)",
"Constante de aceptación (k)", "Estadístico calculado (Z)",
"Promedio mínimo para aceptar (LEI + k·S)", "Decisión"),
Valor = c(LEI, xbar, S, k, round(Z, 4), round(Z_min, 4), decision)
),
caption = "Evaluación de la muestra con el plan de σ desconocida",
col.names = c("Parámetro", "Valor")
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE, position = "center") %>%
row_spec(0, bold = TRUE, color = "white", background = "#264653")
tabla_decision_lote | Parámetro | Valor |
|---|---|
| LEI (g/cm³) | 0.7 |
| Promedio de la muestra (x̄) | |0.73 |
| Desviación estándar (S) | 0.018 |
| Constante de aceptación (k) | 1.716943 |
| Estadístico calculado (Z) | 1.6667 |
| Promedio mínimo para aceptar (LEI + k·S) | 0.7309 |
| Decisión | Se RECHAZA el lote |
En el código se pusieron los datos del límite de especificación inferior el promedio de la muestra y la desviación estándar. Se calculó Z como el promedio menos el límite dividido entre la desviación estándar lo que dio 1.6667 y se comparó con k usando la condición mayor o igual que devolvió FALSE por eso se rechaza. Por último el cálculo del promedio mínimo necesario dio 0.7309 que es lo que se necesitaba para aceptar.
Con el plan del literal b donde n es 34 y k es 1.716943 se evaluó la muestra que tuvo promedio de 0.73 g/cm³ y desviación estándar de 0.018 g/cm³. Con el método k el estadístico Z se calculó como 0.73 menos 0.70 dividido entre 0.018 lo que dio 1.667. Como es menor que la constante de aceptación k de 1.716943 la decisión es rechazar el lote. El criterio en términos del promedio indica que debe ser mayor o igual al límite más k por la desviación lo que con una desviación de 0.018 da un promedio mínimo de 0.7309 g/cm³. El inspector toma las 34 piezas calcula el promedio y la desviación y acepta el lote solo si el promedio supera ese valor. Aquí el promedio de 0.73 quedó apenas por debajo del mínimo requerido. Aunque está por encima del límite de 0.70 no lo está por un margen suficiente para la variabilidad observada así que no hay garantía de que la proporción de no conformes sea tan baja como la que el plan tolera.
Por qué el método M: como la desviación es desconocida se usa la tabla de variabilidad desconocida, y como solo hay un límite, la regla es: se rechaza el lote si \(P_i > M\).
limiteInferior <- 49.8
tamanoLote <- 2500
AQL <- 0.15
nivelInspeccion <- "IV"
construirTabla(
data.frame(
Parametro = c("LEI (kg)", "Tamaño del lote (N)", "AQL (%)", "Nivel de inspección", "Desviación estándar"),
Valor = c(limiteInferior, tamanoLote, AQL, nivelInspeccion, "Desconocida")
),
titulo = "Datos y parámetros del problema - Punto 2"
)| Parametro | Valor |
|---|---|
| LEI (kg) | 49.8 |
| Tamaño del lote (N) | 2500 |
| AQL (%) | 0.15 |
| Nivel de inspección | IV |
| Desviación estándar | Desconocida |
Paso 1, letra código (Tabla 1): un lote de 2500 está en el rango de 1301 a 3200 y con nivel de inspección IV la letra es L.
Paso 2, n y M (Tabla 2, variabilidad desconocida): con la letra L el tamaño de muestra es \(n = 40\) y, en la columna AQL = 0.15 de inspección normal, el máximo porcentaje de no conformes es \(M = 0.566\%\).
letraCodigo <- "L"
tamanoMuestra <- 40
MNormal <- 0.566
construirTabla(
data.frame(
Concepto = c("Letra código", "n (tamaño de muestra)", "M (inspección normal, %)"),
Valor = c(letraCodigo, tamanoMuestra, MNormal)
),
titulo = "Plan de muestreo - Punto 2a"
)| Concepto | Valor |
|---|---|
| Letra código | L |
| n (tamaño de muestra) | 40 |
| M (inspección normal, %) | 0.566 |
Comprobación con la librería, como en el código del profesor:
plan_normal <- list(letter = "L", n = 40, M = 0.566)
plan_severa <- list(letter = "L", n = 40, M = 0.401)Plan: letra código L, \(n = 40\) y \(M = 0.566\%\).
De un lote se toman las \(n = 40\) unidades y se obtiene \(\bar{x} = 50.05\) kg y \(s = 0.1\) kg. Como solo hay límite inferior:
\[Z_{LEI} = \frac{\bar{x} - LEI}{s} = \frac{50.05 - 49.8}{0.1} = 2.5\]
La tabla de estimación de las diapositivas solo llega hasta Z = 1.50,
así que para Z = 2.5 se usa EPn de la librería AQLSchemes,
igual que en el código del profesor.
mediaMuestra <- 50.05
desviacionMuestra <- 0.1
ZLimiteInferior <- (mediaMuestra - limiteInferior) / desviacionMuestra
library(AQLSchemes)
PiLibreria <- EPn(sided = "one", stype = "unknown", LSL = limiteInferior,
xbar = mediaMuestra, s = desviacionMuestra, n = tamanoMuestra) * 100
construirTabla(
data.frame(
Cantidad = c("Z (LEI)", "Pi estimado - EPn (%)", "M normal (%)"),
Valor = c(ZLimiteInferior, PiLibreria, MNormal)
),
titulo = "Estimación del porcentaje de no conformes - Punto 2b"
)| Cantidad | Valor |
|---|---|
| Z (LEI) | 2.5000 |
| Pi estimado - EPn (%) | 0.4725 |
| M normal (%) | 0.5660 |
decisionNormal <- ifelse(PiLibreria <= MNormal, "Se ACEPTA el lote", "Se RECHAZA el lote")
decisionNormal## [1] "Se ACEPTA el lote"
Con \(Z = 2.5\) y \(n = 40\), EPn da un \(P_i\) de aproximadamente 0.473%. Comparado
con \(M = 0.566\%\) de inspección
normal, la decisión es: Se ACEPTA el lote.
Al pasar a inspección severa se mantiene la letra L y \(n = 40\), pero en la Tabla 2 la escala de AQL de la inspección severa está corrida una columna: el AQL = 0.15 severo queda debajo de la columna 0.10 de la inspección normal, y ahí \(M = 0.401\%\).
MSevera <- 0.401
decisionSevera <- ifelse(PiLibreria <= MSevera, "Se ACEPTA el lote", "Se RECHAZA el lote")
tablaDecision <- data.frame(
Inspeccion = c("Normal", "Severa"),
n = c(tamanoMuestra, tamanoMuestra),
M = c(MNormal, MSevera),
Pi = c(PiLibreria, PiLibreria),
Decision = c(decisionNormal, decisionSevera)
)
construirTabla(tablaDecision, titulo = "Comparación de la decisión - Punto 2c")| Inspeccion | n | M | Pi | Decision |
|---|---|---|---|---|
| Normal | 40 | 0.566 | 0.4725 | Se ACEPTA el lote |
| Severa | 40 | 0.401 | 0.4725 | Se RECHAZA el lote |
datosGrafico <- data.frame(
Inspeccion = factor(c("Normal", "Severa"), levels = c("Normal", "Severa")),
M = c(MNormal, MSevera)
)
ggplot(datosGrafico, aes(x = Inspeccion, y = M, fill = Inspeccion)) +
geom_col(width = 0.5, alpha = 0.85) +
geom_text(aes(label = paste0("M = ", M, "%")), vjust = -0.5, size = 3.5) +
geom_hline(yintercept = PiLibreria, linetype = "dashed", color = colorPrincipal, linewidth = 1) +
annotate("text", x = 1.5, y = PiLibreria, vjust = -0.7, size = 3.5, color = colorPrincipal,
label = paste0("Pi estimado = ", round(PiLibreria, 3), "%")) +
scale_fill_manual(values = c("Normal" = colorAcepta, "Severa" = colorRechaza)) +
scale_y_continuous(expand = expansion(mult = c(0, 0.2))) +
labs(title = "El Pi de la muestra frente al M de cada nivel de rigurosidad",
x = NULL, y = "Porcentaje de no conformes (%)", fill = NULL) +
temaTaller +
theme(legend.position = "none")Con inspección severa el Pi estimado es de 0.473% y el valor M es de 0.401% entonces el lote se rechaza. Si la decisión es distinta a la de inspección normal quiere decir que la rigurosidad sí cambia el resultado.
lo que que significa para el ingenio, es decir, que la misma muestra con el mismo resultado puede pasar de aceptada a rechazada solo porque cambia el nivel de rigurosidad. La inspección severa se usa cuando el historial reciente de calidad es malo y exige un lote claramente mejor para aceptarlo. Para el ingenio esto significa más lotes rechazados mientras no demuestre una calidad estable así que le conviene centrar el proceso de llenado y reducir la variabilidad del peso de los sacos para poder volver a inspección normal.
Se usan las mismas condiciones del punto 1 (p₁ = 2%, α = 10%, p₂ = 10%, β = 6%).
datos <- data.frame(
Elemento = c("Nivel de calidad aceptable (p₁)", "Nivel de calidad límite (p₂)"),
Valor = c("p₁ = 0.02, Pa = 0.90, entonces α = 0.10",
"p₂ = 0.10, Pa = 0.06, entonces β = 0.06")
)
datos %>%
kbl(col.names = c("Datos", "Valor")) %>%
kable_styling(full_width = FALSE, position = "left")| Datos | Valor |
|---|---|
| Nivel de calidad aceptable (p₁) | p₁ = 0.02, Pa = 0.90, entonces α = 0.10 |
| Nivel de calidad límite (p₂) | p₂ = 0.10, Pa = 0.06, entonces β = 0.06 |
Como los lotes son grandes, el número de no conformes en la muestra se modela con la binomial. La probabilidad de aceptar un lote con fracción p de no conformes es:
\[P_a(p)=P(X\le c)=\sum_{x=0}^{c}\binom{n}{x}p^x(1-p)^{n-x}\]
El plan (n, c) tiene que cumplir las dos cosas a la vez:
\[P_a(p_1)\ge 1-\alpha=0.90 \qquad \text{y} \qquad P_a(p_2)\le \beta=0.06\]
AQL <- 0.02
alpha <- 0.10
Pa_AQL <- 1 - alpha
LTPD <- 0.10
beta <- 0.06
Pa_LTPD <- beta
library(AcceptanceSampling)
plan_atributos <- find.plan(PRP = c(AQL, 1 - alpha),
CRP = c(LTPD, beta),
type = "binomial")
tabla_plan_atributos <- kable(
data.frame(
Parametro = c("n (tamaño de muestra)", "c (número de aceptación)"),
Valor = c(plan_atributos$n, plan_atributos$c)
),
caption = "Plan de muestreo simple por atributos",
col.names = c("Parámetro", "Valor")
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE, position = "center") %>%
row_spec(0, bold = TRUE, color = "white", background = "#264653")
tabla_plan_atributos| Parámetro | Valor |
|---|---|
| n (tamaño de muestra) | 73 |
| c (número de aceptación) | 3 |
Se usó find.plan con type = "binomial"
porque se trabaja con piezas conformes y no conformes. La función
devuelve el plan con el menor n que cumple las dos condiciones.
n_att <- 73
c_att <- 3
p <- seq(0, 0.20, 0.001)
oc_att <- OC2c(n = n_att, c = c_att, type = "binomial", pd = p)
eval_plan <- assess(oc_att, PRP = c(AQL, 1 - alpha), CRP = c(LTPD, beta))## Acceptance Sampling Plan (binomial)
##
## Sample 1
## Sample size(s) 73
## Acc. Number(s) 3
## Rej. Number(s) 4
##
## Plan CAN meet desired risk point(s):
##
## Quality RP P(accept) Plan P(accept)
## PRP 0.02 0.90 0.94115669
## CRP 0.10 0.06 0.05795227
Pa_p1 <- oc_att@paccept[which.min(abs(p - 0.02))]
Pa_p2 <- oc_att@paccept[which.min(abs(p - 0.10))]
tabla_verificacion_atributos <- kable(
data.frame(
Punto = c("p₁ = 2%", "p₂ = 10%"),
Pa_Calculado = c(round(Pa_p1, 4), round(Pa_p2, 4)),
Requisito = c("Pa ≥ 0.90", "Pa ≤ 0.06"),
Cumple = c(ifelse(Pa_p1 >= 0.90, "Sí", "No"), ifelse(Pa_p2 <= 0.06, "Sí", "No"))
),
caption = "Verificación de riesgos del plan por atributos",
col.names = c("Fracción de no conformes", "Probabilidad de aceptación (Pa)", "Requisito", "¿Cumple?")
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE, position = "center") %>%
row_spec(0, bold = TRUE, color = "white", background = "#264653")
tabla_verificacion_atributos| Fracción de no conformes | Probabilidad de aceptación (Pa) | Requisito | ¿Cumple? |
|---|---|---|---|
| p₁ = 2% | 0.9412 | Pa ≥ 0.90 | Sí |
| p₂ = 10% | 0.0580 | Pa ≤ 0.06 | Sí |
assess revisa si el plan cumple los dos puntos de la
curva OC, igual que en el código del profesor.
plot_ly() %>%
add_lines(x = p, y = oc_att@paccept, name = "Atributos",
hovertemplate = "p = %{x:.3f}<br>Pa = %{y:.4f}<extra></extra>") %>%
add_markers(x = c(AQL, LTPD), y = c(Pa_AQL, Pa_LTPD), name = "Puntos pedidos",
marker = list(size = 10, color = "red"),
hovertemplate = "p = %{x:.2f}<br>Pa = %{y:.2f}<extra></extra>") %>%
layout(title = paste0("Curva OC: plan por atributos (n = ", n_att, ", c = ", c_att, ")"),
xaxis = list(title = "Proporción de no conformidades"),
yaxis = list(title = "Pa", range = c(0, 1)))El plan simple por atributos es de n igual a 73 y c igual a 3. Se toman 73 piezas y se acepta el lote si hay 3 o menos no conformes, si hay 4 o más se rechaza. Con este plan la probabilidad de aceptar un lote con 2% de no conformes es de 0.9412 que es mayor a 0.90 y con 10% baja a 0.058 que es menor a 0.06. La curva OC lo confirma al pasar por encima del primer punto y por debajo del segundo así que se cumplen los dos requisitos del enunciado.
n1 <- 14; k1 <- 1.71124
n2 <- 34; k2 <- 1.716943
comparacion <- data.frame(
Plan = c("Variables, σ conocida", "Variables, σ desconocida", "Atributos"),
n = c(n1, n2, n_att),
Criterio = c(paste0("k = ", round(k1, 4)),
paste0("k = ", round(k2, 4)),
paste0("c = ", c_att)),
Razon = round(c(n1, n2, n_att) / n_att, 2)
)
comparacion %>%
kbl(col.names = c("Plan", "n", "Criterio de aceptación", "n / n atributos")) %>%
kable_styling(full_width = FALSE, position = "left")| Plan | n | Criterio de aceptación | n / n atributos |
|---|---|---|---|
| Variables, σ conocida | 14 | k = 1.7112 | 0.19 |
| Variables, σ desconocida | 34 | k = 1.7169 | 0.47 |
| Atributos | 73 | c = 3 | 1.00 |
En la última columna se ve qué fracción del tamaño de muestra por atributos representa cada plan.
oc_var1 <- OCvar(n = n1, k = k1, pd = p, s.type = "known")
oc_var2 <- OCvar(n = n2, k = k2, pd = p, s.type = "unknown")
plot_ly() %>%
add_lines(x = p, y = oc_var1@paccept,
name = paste0("Variables, σ conocida (n = ", n1, ")"),
hovertemplate = "p = %{x:.3f}<br>Pa = %{y:.4f}<extra></extra>") %>%
add_lines(x = p, y = oc_var2@paccept,
name = paste0("Variables, σ desconocida (n = ", n2, ")"),
hovertemplate = "p = %{x:.3f}<br>Pa = %{y:.4f}<extra></extra>") %>%
add_lines(x = p, y = oc_att@paccept,
name = paste0("Atributos (n = ", n_att, ")"),
hovertemplate = "p = %{x:.3f}<br>Pa = %{y:.4f}<extra></extra>") %>%
add_markers(x = c(AQL, LTPD), y = c(Pa_AQL, Pa_LTPD), name = "Puntos pedidos",
marker = list(size = 10, color = "red"),
hovertemplate = "p = %{x:.2f}<br>Pa = %{y:.2f}<extra></extra>") %>%
layout(title = "Curva OC: variables vs. atributos",
xaxis = list(title = "Proporción de no conformidades"),
yaxis = list(title = "Pa", range = c(0, 1)),
legend = list(orientation = "h", y = -0.25))El plan por atributos pide 73 piezas el de variables con sigma desconocida pide 34 y el de variables con sigma conocida pide 14. Entonces el que requiere menos unidades inspeccionadas es el de variables con sigma conocida seguido del de variables con sigma desconocida. La diferencia viene de la información que da cada pieza ya que en variables se mide la densidad de cada una así que se sabe qué tan lejos está del límite de 0.70 g/cm³ mientras que en atributos solo se anota si la pieza es conforme o no y cada unidad aporta menos información. Por eso para lograr los mismos riesgos de 10% y 6% el plan por atributos necesita más muestra. Esto concuerda con la ventaja que se vio en clase ya que con curvas OC parecidas variables usa un menor tamaño de muestra. Las tres curvas pasan por los puntos pedidos así que los tres planes protegen igual al productor y al consumidor y lo que cambia es cuántas piezas se inspeccionan.
La decisión no depende solo del tamaño de muestra sino del costo total por lote. Si C_ensayo es el costo de medir una pieza en el laboratorio y C_clasificación el de clasificarla como conforme o no conforme:
\[C_{var}=n_{var}\cdot C_{ensayo} \qquad C_{att}=n_{att}\cdot C_{clasificación}\]
El plan por variables solo sale más barato si:
\[\frac{C_{ensayo}}{C_{clasificación}}<\frac{n_{att}}{n_{var}}\]
razon_critica <- n_att / n2
tabla_razon_critica <- kable(
data.frame(
Concepto = c("n por atributos", "n por variables (σ desconocida)", "Razón crítica de costos (n_att / n2)"),
Valor = c(n_att, n2, round(razon_critica, 2))
),
caption = "Razón crítica de costos",
col.names = c("Concepto", "Valor")
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE, position = "center") %>%
row_spec(0, bold = TRUE, color = "white", background = "#264653")
tabla_razon_critica| Concepto | Valor |
|---|---|
| n por atributos | 73.00 |
| n por variables (σ desconocida) | 34.00 |
| Razón crítica de costos (n_att / n2) | 2.15 |
Para la razón crítica se tomó el plan por variables con σ desconocida (n = 34), porque en este caso la variabilidad se estima con la muestra.
razon <- seq(0.5, 6, 0.1)
costo_att <- rep(n_att * 1, length(razon))
costo_var <- n2 * razon
plot_ly() %>%
add_lines(x = razon, y = costo_att, name = "Atributos",
hovertemplate = "Razón = %{x:.1f}<br>Costo = %{y:.1f}<extra></extra>") %>%
add_lines(x = razon, y = costo_var, name = "Variables, σ desconocida",
hovertemplate = "Razón = %{x:.1f}<br>Costo = %{y:.1f}<extra></extra>") %>%
add_markers(x = razon_critica, y = n_att, name = "Punto de equilibrio",
marker = list(size = 10, color = "red"),
hovertemplate = "Razón = %{x:.2f}<br>Costo = %{y:.1f}<extra></extra>") %>%
layout(title = "Costo de inspección por lote",
xaxis = list(title = "C_ensayo / C_clasificación"),
yaxis = list(title = "Costo total (en unidades de C_clasificación)"),
legend = list(orientation = "h", y = -0.25))Se dibujó el costo total de cada plan según la razón entre el costo del ensayo y el de clasificar tomando el costo de clasificar una pieza como la unidad. El costo del plan por atributos es constante porque son 73 piezas mientras que el del plan por variables crece con la razón. Las líneas se cruzan en 2.15 que es el punto de equilibrio.
Análisis
Se recomienda el plan por atributos con n igual a 73 y c igual a 3. El plan por variables inspecciona menos piezas ya que son 34 frente a 73 pero solo sale más barato si el ensayo de laboratorio cuesta menos de 2.15 veces la clasificación de una pieza. Como el enunciado dice que el ensayo es costoso y destructivo y que clasificar es rápido y barato es de esperar que la razón de costos pase de ese valor y entonces el plan por atributos es el de menor costo total. Esto hay que confirmarlo con los costos reales de la empresa ya que si el ensayo costara menos de 2.15 veces la clasificación convendría el plan por variables con sigma desconocida.
Otros factores que se tendrían en cuenta:
1 Normalidad de la densidad. El plan por variables supone que la densidad es normal y si no lo es el plan pierde validez mientras que el de atributos no necesita ese supuesto.
2 Distribución entre lotes. La proporción puede cambiar de un lote a otro y eso afecta el plan por variables.
3 Estabilidad del proceso. El plan por variables necesita un proceso estable para que la desviación estándar muestral sea una buena estimación de la variabilidad.
4 Piezas destruidas. Cada ensayo destructivo es una pieza perdida lo que suma costo al plan por variables.
5 Tiempo de respuesta. El ensayo de laboratorio retrasa la decisión del lote mientras que clasificar es rápido.
6 Error de medición. El ensayo de densidad requiere un equipo calibrado y un método repetible.
7 Varias características. Si la calidad depende de varias variables se necesita un plan por variables para cada una y eso encarece el plan.
8 Información para el proveedor. Los datos de los lotes consecutivos se acumulan y permiten caracterizar la calidad del proveedor y darle retroalimentación algo que el plan por atributos no permite.
9 Historial del proveedor. Si el proceso es estable y se conoce la desviación con datos históricos se podría reevaluar el plan por variables con sigma conocida que es el de menor tamaño de muestra.
Schilling, E. G., & Neubauer, D. V. (2017). Acceptance Sampling in Quality Control (3rd ed.). CRC Press. (Este libro es la biblia del muestreo de aceptación, tiene todo el sustento de las curvas AOQ, ATI y los planes MIL-STD).