1 Introduction

1.1 Contexte Général

La maîtrise statistique des procédés (MSP) est une méthode essentielle pour assurer la qualité et l’efficacité des processus industriels. Elle utilise des outils statistiques pour surveiller, contrôler et améliorer la performance des systèmes de production. Fondée sur les travaux de Walter A. Shewhart, la MSP se concentre sur la réduction de la variabilité des processus et la détection rapide des anomalies.

Dans un environnement industriel compétitif, la MSP aide à minimiser les défauts, réduire les coûts et garantir la conformité aux spécifications. Les outils principaux incluent les cartes de contrôle, l’analyse de capabilité et les méthodes d’amélioration continue.

1.2 Définition : Graphique de Contrôle

Un graphique de contrôle (ou carte de contrôle), traduit de l’anglais control chart, est un outil utilisé dans le domaine du contrôle de la qualité afin de maîtriser un processus. Il permet de déterminer le moment où apparaît une cause particulière de variation d’une caractéristique, entraînant une altération du processus.

Par exemple, un processus de fabrication pourra être mis à l’arrêt avant de produire des pièces non conformes.

1.3 Structure d’une Carte de Contrôle

Selon la norme internationale ISO, un processus est dit sous contrôle (ou encore stable) lorsque les écarts entre les résultats observés sur un échantillon peuvent être attribués à un ensemble de causes aléatoires qui ne paraît pas se modifier dans le temps.

Une carte de contrôle est composée de trois éléments essentiels :

  • Ligne Centrale (LC) : Représente la valeur cible ou moyenne du processus (\(\mu_0\))
  • Limite de Contrôle Supérieure (LSC) : Limite haute au-delà de laquelle le processus est considéré hors contrôle
  • Limite de Contrôle Inférieure (LCI) : Limite basse en deçà de laquelle le processus est considéré hors contrôle

Par convention, selon la règle de Shewhart, ces limites sont placées à \(\pm 3\sigma\) de la moyenne, ce qui correspond à un intervalle de confiance de 99,73%.

1.3.1 Proposition : Règle des 3σ

Si \(X \sim \mathcal{N}(\mu, \sigma)\) alors : \[P[\mu - 3\sigma < X < \mu + 3\sigma] = 0{,}9973\]

1.4 Types de Cartes de Contrôle

On distingue généralement deux types de cartes selon la phase du processus :

Phase I (Cartes d’étude initiale) : Lorsque le processus sous contrôle est de loi \(\mathcal{N}(\mu, \sigma)\) avec \(\mu\) et \(\sigma\) inconnus. On doit alors estimer ces paramètres.

Phase II (Cartes aux valeurs standard) : Lorsque le processus sous contrôle est de loi \(\mathcal{N}(\mu_0, \sigma_0)\) avec \(\mu_0\) et \(\sigma_0\) connus (donnés par des normes ou établis en Phase I).

2 Exemple 1 : Cartes de Contrôle aux Mesures - Phase II

2.1 Carte de Contrôle de type \(\bar{X}\)

2.1.1 Contexte

On considère un procédé qui, sous contrôle, suit une loi normale \(\mathcal{N}(10, 0{,}1)\). Nous disposons de 30 échantillons (sous-groupes rationnels) de taille \(n=5\) prélevés régulièrement.

Objectif : Vérifier si le processus reste centré sur la valeur cible \(\mu_0 = 10\).

2.1.2 Théorie (Cours MSP - Chapitre 3)

Carte X : Pour ce type de carte, l’idée est de s’intéresser aux moyennes de chacun des sous-groupes rationnels, c’est-à-dire aux réalisations des variables aléatoires réelles \(\bar{X}_i\) pour \(i = 1, \ldots, k\). Chaque variable aléatoire \(\bar{X}_i\) est définie comme :

\[\bar{X}_i = \frac{1}{n} \sum_{j=1}^{n} X_{ij}\]

Si chacune des variables aléatoires réelles \(X_{ij}\) suit une loi normale \(\mathcal{N}(\mu, \sigma)\), il est alors immédiat que, d’après l’hypothèse d’indépendance de ces variables aléatoires :

\[\bar{X}_i \sim \mathcal{N}\left(\mu, \frac{\sigma}{\sqrt{n}}\right)\]

Cela signifie que la moyenne \(\bar{X}_i\) suit une loi normale avec une moyenne \(\mu\) et un écart-type réduit par le facteur \(\frac{1}{\sqrt{n}}\).

2.1.3 Limites de Contrôle pour la Carte \(\bar{X}\) (Phase II)

Les limites de contrôle pour la carte \(\bar{X}\) en Phase II (paramètres connus) sont définies comme suit selon la règle des 3σ :

\[\begin{align} \text{LSC} &= \mu_0 + 3 \cdot \frac{\sigma_0}{\sqrt{n}} \\[0.3cm] \text{LC} &= \mu_0 \\[0.3cm] \text{LCI} &= \mu_0 - 3 \cdot \frac{\sigma_0}{\sqrt{n}} \end{align}\]

où : - LSC représente la limite de contrôle supérieure - LC correspond à la ligne centrale (ou moyenne cible) - LCI désigne la limite de contrôle inférieure - Dans ces formules, \(\mu_0\) est la moyenne du processus sous contrôle, \(\sigma_0\) est l’écart-type du processus sous contrôle, et \(n\) est la taille de chaque échantillon.

# Chargement des données
Exemple1 <- read.csv("Exemple1.txt", sep = "", header = FALSE)

# Affichage des premières lignes
kable(head(Exemple1), 
      col.names = c("Échantillon", "Valeur"),
      caption = "Aperçu des données - Exemple 1",
      align = "c") |>
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE)
Aperçu des données - Exemple 1
Échantillon Valeur
1 9.937568
1 9.953563
1 10.015903
1 10.077521
1 9.975793
2 10.092923

Nos données comportent deux variables et 150 observations, réparties en 30 échantillons de 5 mesures chacun.

# Initialiser des vecteurs pour stocker les statistiques des échantillons
x <- numeric(30)
s <- numeric(30)

# Calcul des moyennes et écarts-types des échantillons
for (i in 1:30) {
  echantillon <- Exemple1$V2[Exemple1$V1 == i]
  x[i] <- mean(echantillon)
  s[i] <- sd(echantillon)
}

# Paramètres pour le calcul des limites de contrôle (Phase II - connus)

mu0 <- 10
sigma <- 0.1
n <- 5

# Calcul des limites de contrôle

LIC <- mu0 - 3 * sigma / sqrt(n)  # Limite inférieure
LSC <- mu0 + 3 * sigma / sqrt(n)  # Limite supérieure

# Affichage élégant des limites

afficher_limites(LSC, mu0, LIC, sigma/sqrt(n), "Carte X̄")

┌─────────────────────────────────────────────┐
│ LIMITES DE CONTRÔLE (Carte X̄      )         │
├─────────────────────────────────────────────┤
│  LSC =  10.1342                             │
│  LC  =  10.0000                             │
│  LCI =   9.8658                             │
├─────────────────────────────────────────────┤
│  σ     =  0.0447                           │
└─────────────────────────────────────────────┘

Analyse des limites : L’écart-type de \(\bar{X}\) vaut \(\sigma_{\bar{X}} = \frac{0{,}1}{\sqrt{5}} \approx 0{,}0447\), soit une réduction d’un facteur \(\sqrt{5} \approx 2{,}24\) par rapport à \(\sigma\). Les limites sont placées à \(\pm 0{,}134\) de la moyenne cible, ce qui correspond à un intervalle très étroit rendant la détection sensible.

# Tableau complet des moyennes calculées

moyennes_df <- data.frame(
  Echantillon = 1:30,
  Moyenne = round(x, 4)
)

# Affichage en 3 blocs de 10

kable(moyennes_df[1:10, ], 
      caption = "Moyennes des échantillons 1 à 10",
      align = "c", row.names = FALSE) |>
  kable_styling(bootstrap_options = c("striped", "condensed"), 
                full_width = FALSE, position = "center")
Moyennes des échantillons 1 à 10
Echantillon Moyenne
1 9.9921
2 9.9975
3 10.0587
4 9.9110
5 9.9745
6 9.9435
7 9.9323
8 9.9902
9 10.0251
10 9.9766
kable(moyennes_df[11:20, ], 
      caption = "Moyennes des échantillons 11 à 20",
      align = "c", row.names = FALSE) |>
  kable_styling(bootstrap_options = c("striped", "condensed"), 
                full_width = FALSE, position = "center")
Moyennes des échantillons 11 à 20
Echantillon Moyenne
11 9.9621
12 9.9600
13 10.0307
14 10.0439
15 10.0021
16 9.9449
17 9.9276
18 9.9993
19 9.9767
20 10.0617
kable(moyennes_df[21:30, ], 
      caption = "Moyennes des échantillons 21 à 30",
      align = "c", row.names = FALSE) |>
  kable_styling(bootstrap_options = c("striped", "condensed"), 
                full_width = FALSE, position = "center")
Moyennes des échantillons 21 à 30
Echantillon Moyenne
21 10.0354
22 9.9441
23 10.0302
24 10.0119
25 10.0587
26 10.0136
27 9.9926
28 10.0197
29 9.9613
30 10.0090
# Préparation des données pour ggplot
df_xbar <- data.frame(
  echantillon = 1:30,
  moyenne = x,
  hors_limite = ifelse(x > LSC | x < LIC, "Hors contrôle", "Sous contrôle")
)

# Création du graphique avec les palettes 
ggplot(df_xbar, aes(x = echantillon, y = moyenne)) +
  
  # Zone de contrôle (±1σ) - zone idéale
  annotate("rect", xmin = 0, xmax = 31, 
           ymin = mu0 - sigma/sqrt(n), 
           ymax = mu0 + sigma/sqrt(n), 
           alpha = 0.3, fill = couleurs$zone_ideale) +
  
  # Zone de contrôle (±3σ) - zone acceptable
  annotate("rect", xmin = 0, xmax = 31, 
           ymin = LIC, ymax = LSC,
           alpha = 0.2, fill = couleurs$zone_acceptable) +
  
  # Limites de surveillance ±2σ
  geom_hline(yintercept = mu0 + 2*sigma/sqrt(n), 
             color = couleurs$surveillance, linewidth = 0.8, 
             linetype = "dotted", alpha = 0.7) +
  geom_hline(yintercept = mu0 - 2*sigma/sqrt(n), 
             color = couleurs$surveillance, linewidth = 0.8, 
             linetype = "dotted", alpha = 0.7) +
  
  # Limites de contrôle principales
  geom_hline(yintercept = mu0, color = couleurs$vert_principal, 
             linewidth = 1.3, linetype = "solid") +
  geom_hline(yintercept = LSC, color = couleurs$rouge_principal, 
             linewidth = 1.2, linetype = "dashed") +
  geom_hline(yintercept = LIC, color = couleurs$rouge_principal, 
             linewidth = 1.2, linetype = "dashed") +
  
  # Tracé des données
  geom_line(color = couleurs$bleu_principal, linewidth = 1.1) +
  geom_point(aes(color = hors_limite), size = 3.5, shape = 19) +
  
  # Annotations des limites
  annotate("text", x = 28, y = LSC, 
           label = paste("LSC =", round(LSC, 4)),
           vjust = -0.7, color = couleurs$rouge_principal, 
           fontface = "bold", size = 4) +
  annotate("text", x = 28, y = LIC, 
           label = paste("LCI =", round(LIC, 4)),
           vjust = 1.7, color = couleurs$rouge_principal, 
           fontface = "bold", size = 4) +
  annotate("text", x = 28, y = mu0, 
           label = paste("LC =", mu0),
           vjust = -0.7, color = couleurs$vert_principal, 
           fontface = "bold", size = 4) +
  
  # Mise en forme
  scale_color_manual(values = c("Sous contrôle" = couleurs$sous_controle, 
                                 "Hors contrôle" = couleurs$hors_controle)) +
  labs(
    title = expression(paste("Carte de Contrôle ", bar(X), " - Phase II")),
    subtitle = expression(paste(mu[0], " = 10, ", sigma[0], " = 0.1, n = 5")),
    x = "Numéro d'échantillon",
    y = expression(paste("Moyenne de l'échantillon (", bar(X), ")")),
    color = "État du processus"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 15, hjust = 0.5, 
                              color = couleurs$bleu_principal),
    plot.subtitle = element_text(size = 11, hjust = 0.5, color = couleurs$gris_fonce),
    plot.caption = element_text(size = 9, hjust = 0.5, color = "gray50", 
                                face = "italic", margin = margin(t = 10)),
    panel.grid.minor = element_blank(),
    panel.grid.major = element_line(color = "gray90", linewidth = 0.3),
    panel.border = element_rect(color = "gray70", fill = NA, linewidth = 0.6),
    legend.position = "bottom",
    legend.title = element_text(face = "bold", size = 11),
    legend.background = element_rect(fill = couleurs$gris_clair, 
                                    color = "gray70", linewidth = 0.4),
    legend.margin = margin(5, 5, 5, 5),
    axis.title = element_text(face = "bold", size = 11),
    axis.text = element_text(size = 10)
  ) +
  scale_x_continuous(breaks = seq(0, 30, 5)) +
  scale_y_continuous(breaks = seq(floor(min(x)*10)/10, 
                                  ceiling(max(x)*10)/10, 0.05))
Carte de contrôle X̄ - Phase II avec paramètres connus

Carte de contrôle X̄ - Phase II avec paramètres connus

2.1.4 Interprétation des Résultats

# Analyse statistique
points_hors_controle <- sum(df_xbar$hors_limite == "Hors contrôle")
moyenne_globale <- mean(x)
ecart_type_observe <- sd(x)

writeLines(c(
  "",
  "═══════════════════════════════════════════",
  "        ANALYSE DE LA CARTE X̄",
  "═══════════════════════════════════════════",
  sprintf("Points hors contrôle    : %d sur 30", points_hors_controle),
  sprintf("Moyenne observée (X̄̄)   : %.4f", moyenne_globale),
  sprintf("Écart de la cible       : %.4f", moyenne_globale - mu0),
  sprintf("Écart-type observé      : %.4f", ecart_type_observe),
  sprintf("Écart-type théorique    : %.4f", sigma/sqrt(n)),
  "═══════════════════════════════════════════",
  ""
))

═══════════════════════════════════════════
        ANALYSE DE LA CARTE X̄
═══════════════════════════════════════════
Points hors contrôle    : 0 sur 30
Moyenne observée (X̄̄)   : 9.9929
Écart de la cible       : -0.0071
Écart-type observé      : 0.0412
Écart-type théorique    : 0.0447
═══════════════════════════════════════════

Conclusions :

Le processus semble être sous contrôle, il n’y a aucun point qui sort. Plus précisément :

  1. Processus sous contrôle : Aucun point ne dépasse les limites de contrôle
  2. Stabilité du processus : Tous les points fluctuent aléatoirement autour de la ligne centrale
  3. Absence de tendance : Pas de dérive progressive visible
  4. Centrage correct : La moyenne observée est très proche de \(\mu_0 = 10\)

Décision : Le processus de fabrication fonctionne normalement concernant sa position (centrage). Aucune action corrective n’est nécessaire.

2.2 Carte de Contrôle du type \(S\)

2.2.1 Objectif

Tandis que la carte \(\bar{X}\) surveille le centrage du processus, la carte \(S\) surveille sa dispersion (variabilité). Un processus peut être bien centré mais trop variable, produisant alors des pièces hors tolérances.

2.2.2 Théorie (Cours MSP - Chapitre 3)

Considérons toujours \(k\) sous-groupes rationnels de taille \(n\). La carte \(S\) consiste en la représentation des diverses valeurs \(s_i\) (pour \(1 \leq i \leq k\)) qui sont des réalisations des variables aléatoires \(S_i\) telles que :

\[S_i^2 = \frac{1}{n-1} \sum_{j=1}^{n} (X_{ij} - \bar{X}_i)^2\]

D’après la Proposition 02 du cours, lorsque les variables aléatoires réelles \(X_{ij}\) sont indépendantes avec \(\forall i = 1, \ldots, k\), \(\forall j = 1, \ldots, n\), \(X_{ij} \sim \mathcal{N}(\mu, \sigma)\) alors :

\[(n-1) \frac{S_i^2}{\sigma^2} \sim \chi^2_{n-1}\]

Remarque importante du cours : Attention au fait que généralement \(S\) n’est pas un estimateur sans biais de \(\sigma\) !

Pour une loi normale, on a \(\mathbb{E}[S_i] = c_4(n) \cdot \sigma\)\(c_4(n)\) est un coefficient de correction dépendant de \(n\) et tabulé. De même :

\[\text{Var}(S_i) = \mathbb{E}[S_i^2] - [\mathbb{E}[S_i]]^2 = \sigma^2 - (c_4(n) \cdot \sigma)^2 = \sigma^2(1 - c_4^2(n))\]

Donc : \(\sigma(S_i) = \sigma\sqrt{1 - c_4^2(n)}\)

2.2.3 Limites de Contrôle

Les limites de contrôle pour la carte \(S\) en Phase II sont :

\[\begin{align} \text{LSC} &= c_4(n)\sigma_0 + 3\sigma_0\sqrt{1 - c_4^2(n)} \\[0.3cm] \text{LC} &= c_4(n)\sigma_0 \\[0.3cm] \text{LCI} &= c_4(n)\sigma_0 - 3\sigma_0\sqrt{1 - c_4^2(n)} \end{align}\]

Note importante : Si LCI < 0, on pose LCI = 0 car l’écart-type ne peut être négatif.

# Initialisation d'un vecteur pour stocker les écarts-types
variances <- numeric(30)

# Boucle pour calculer l'écart-type pour chaque groupe
for (i in 1:30) {
  sous_groupe <- Exemple1$V2[Exemple1$V1 == i]
  n <- length(sous_groupe)
  mean_group <- mean(sous_groupe)
  variances[i] <- sum((sous_groupe - mean_group)^2) / (n - 1)
}

# Calcul des écarts-types
sd_vals <- sqrt(variances)

# Paramètres pour la carte S
mu0 <- 10
sigma <- 0.1
C4 <- 0.940  # Coefficient c4 pour n=5

# Calcul des limites
S_bar <- C4 * sigma
LIC_s <- C4*sigma - 3*sigma*sqrt(1 - C4^2)
LSC_s <- C4*sigma + 3*sigma*sqrt(1 - C4^2)

# Si LIC négatif, on le fixe à 0
if (LIC_s < 0) LIC_s <- 0

# Affichage des limites
afficher_limites(LSC_s, S_bar, LIC_s, NULL, "Carte S")

┌─────────────────────────────────────────────┐
│ LIMITES DE CONTRÔLE (Carte S        )         │
├─────────────────────────────────────────────┤
│  LSC =   0.1964                             │
│  LC  =   0.0940                             │
│  LCI =   0.0000                             │
└─────────────────────────────────────────────┘
writeLines(sprintf("Coefficient c4 pour n=5 : %.3f", C4))
Coefficient c4 pour n=5 : 0.940
# Tableau complet des écarts-types calculés
ecarts_df <- data.frame(
  Echantillon = 1:30,
  Ecart_type = round(sd_vals, 4)
)

# Affichage en 3 blocs de 10
kable(ecarts_df[1:10, ], 
      caption = "Écarts-types des échantillons 1 à 10",
      align = "c", row.names = FALSE) |>
  kable_styling(bootstrap_options = c("striped", "condensed"), 
                full_width = FALSE, position = "center")
Écarts-types des échantillons 1 à 10
Echantillon Ecart_type
1 0.0561
2 0.0937
3 0.1131
4 0.0999
5 0.1714
6 0.0509
7 0.0633
8 0.1012
9 0.1057
10 0.0861
kable(ecarts_df[11:20, ], 
      caption = "Écarts-types des échantillons 11 à 20",
      align = "c", row.names = FALSE) |>
  kable_styling(bootstrap_options = c("striped", "condensed"), 
                full_width = FALSE, position = "center")
Écarts-types des échantillons 11 à 20
Echantillon Ecart_type
11 0.0853
12 0.0761
13 0.1798
14 0.1685
15 0.0719
16 0.0925
17 0.1835
18 0.0624
19 0.1419
20 0.0730
kable(ecarts_df[21:30, ], 
      caption = "Écarts-types des échantillons 21 à 30",
      align = "c", row.names = FALSE) |>
  kable_styling(bootstrap_options = c("striped", "condensed"), 
                full_width = FALSE, position = "center")
Écarts-types des échantillons 21 à 30
Echantillon Ecart_type
21 0.1169
22 0.1041
23 0.1123
24 0.1232
25 0.1075
26 0.0545
27 0.0491
28 0.2305
29 0.1644
30 0.0695
# Préparation des données
df_s <- data.frame(
  echantillon = 1:30,
  ecart_type = sd_vals,
  hors_limite = ifelse(sd_vals > LSC_s | sd_vals < LIC_s, 
                       "Hors contrôle", "Sous contrôle")
)

# Graphique
ggplot(df_s, aes(x = echantillon, y = ecart_type)) +
  # Zone de contrôle
  annotate("rect", xmin = 0, xmax = 31, 
           ymin = LIC_s, ymax = LSC_s,
           alpha = 0.15, fill = "lightblue") +
  
  # Limites de contrôle
  geom_hline(yintercept = S_bar, color = "#2E7D32", 
             linewidth = 1.2) +
  geom_hline(yintercept = LSC_s, color = "#D32F2F", 
             linewidth = 1, linetype = "dashed") +
  geom_hline(yintercept = LIC_s, color = "#D32F2F", 
             linewidth = 1, linetype = "dashed") +
  
  # Données
  geom_line(color = "#1976D2", linewidth = 1) +
  geom_point(aes(color = hors_limite), size = 3.5) +
  
  # Annotations
  annotate("text", x = 28, y = LSC_s, 
           label = paste("LSC =", round(LSC_s, 4)),
           vjust = -0.7, color = "#D32F2F", 
           fontface = "bold", size = 4) +
  annotate("text", x = 28, y = S_bar, 
           label = paste("S̄ =", round(S_bar, 4)),
           vjust = -0.7, color = "#2E7D32", 
           fontface = "bold", size = 4) +
  
  # Mise en forme
  scale_color_manual(values = c("Sous contrôle" = "#1976D2", 
                                 "Hors contrôle" = "#D32F2F")) +
  labs(
    title = "Carte de Contrôle S - Phase II",
    subtitle = "Ecart-type = 0.1, n = 5, c4 = 0.940",
    x = "Numéro d'échantillon",
    y = "Écart-type de l'échantillon (S)",
    color = "État du processus"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 15, hjust = 0.5),
    plot.subtitle = element_text(size = 11, hjust = 0.5, color = "gray30"),
    panel.grid.minor = element_blank(),
    legend.position = "bottom",
    legend.title = element_text(face = "bold"),
    axis.title = element_text(face = "bold", size = 11)
  ) +
  scale_x_continuous(breaks = seq(0, 30, 5))
Carte de contrôle S - Surveillance de la dispersion

Carte de contrôle S - Surveillance de la dispersion

2.2.4 Interprétation

points_hors_s <- sum(df_s$hors_limite == "Hors contrôle")
s_moyen <- mean(sd_vals)

writeLines(c(
  "",
  "═══════════════════════════════════════════",
  "         ANALYSE DE LA CARTE S",
  "═══════════════════════════════════════════",
  sprintf("Points hors contrôle    : %d", points_hors_s),
  sprintf("Écart-type moyen obs.   : %.4f", s_moyen),
  sprintf("Écart-type cible (c4×σ0): %.4f", S_bar),
  "═══════════════════════════════════════════",
  ""
))

═══════════════════════════════════════════
         ANALYSE DE LA CARTE S
═══════════════════════════════════════════
Points hors contrôle    : 1
Écart-type moyen obs.   : 0.1069
Écart-type cible (c4×σ0): 0.0940
═══════════════════════════════════════════

En passant par la carte \(S\), on voit qu’il y a un point qui sort de la limite supérieure, donc le processus n’est pas sous contrôle.

Conclusion Exemple 1 :

Le processus est centré correctement, comme l’indique la carte de contrôle \(\bar{X}\) qui montre que les moyennes des sous-groupes restent en conformité avec la valeur cible. Cependant, la carte \(S\) révèle une variabilité interne anormale, signalée par un point hors des limites de contrôle.

Cela suggère que, bien que la position moyenne du processus soit stable, une cause assignable pourrait perturber la dispersion du processus. Cette anomalie peut être liée à des facteurs tels qu’une machine instable, une matière première non homogène, ou un opérateur changeant.

Recommandation : Il est donc recommandé d’analyser ce sous-groupe particulier pour identifier et corriger la source de la variabilité.

3 Exemple 2 : Analyse de Valeurs Aberrantes - Alarmes Incendie

3.1 Contexte

Une entreprise fabrique des alarmes incendie et teste leur qualité en mesurant leur rapidité de réaction. Chaque alarme teste l’atmosphère une fois par seconde.

D’après les normes à respecter, le temps de réaction doit être en moyenne égal à 5 secondes.

Voici les résultats observés pour 20 alarmes :

5  3  3  6  1  4  2  3  8  7
4  5  5  3 17  6  5  1  8  4

Question : Le responsable pense que cette production n’est pas sous contrôle (à cause de l’alarme à 17 secondes). Êtes-vous d’accord ?


3.2 Analyse des données

# Données
alarmes <- c(5, 3, 3, 6, 1, 4, 2, 3, 8, 7,
             4, 5, 5, 3, 17, 6, 5, 1, 8, 4)

# Statistiques de base
n <- length(alarmes)
moyenne <- mean(alarmes)
mediane <- median(alarmes)
ecart_type <- sd(alarmes)
minimum <- min(alarmes)
maximum <- max(alarmes)

# Quartiles
Q1 <- quantile(alarmes, 0.25)
Q3 <- quantile(alarmes, 0.75)
IQR <- Q3 - Q1

# Tableau des statistiques descriptives
stats_alarmes <- data.frame(
  Statistique = c("Nombre d'observations", "Moyenne", "Médiane", 
                  "Écart-type", "Minimum", "Maximum", "Q1", "Q3", "IQR"),
  Valeur = c(n, 
             round(moyenne, 2), 
             mediane, 
             round(ecart_type, 2), 
             minimum, 
             maximum, 
             Q1, 
             Q3, 
             IQR)
)

kable(stats_alarmes,
      caption = "Statistiques descriptives des temps de réaction",
      align = "lr",
      col.names = c("Statistique", "Valeur")) |>
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE) |>
  row_spec(2, bold = TRUE, color = "red") # Mettre la moyenne en rouge
Statistiques descriptives des temps de réaction
Statistique Valeur
Nombre d’observations 20.00
Moyenne 5.00
Médiane 4.50
Écart-type 3.46
Minimum 1.00
Maximum 17.00
Q1 3.00
Q3 6.00
IQR 3.00

3.3 Méthode 1 : Boîte de dispersion (Cours Chapitre 1.2.2)

Une valeur est considérée comme atypique si elle se situe : - Au-dessus de Q3 + 1.5 × IQR - En-dessous de Q1 - 1.5 × IQR

# Limites des moustaches 
limite_sup <- Q3 + 1.5 * IQR
limite_inf <- Q1 - 1.5 * IQR

# Identification des valeurs atypiques
atypiques <- alarmes[alarmes > limite_sup | alarmes < limite_inf]

# Identification des valeurs atypiques
atypiques <- alarmes[alarmes > limite_sup | alarmes < limite_inf]

# Tableau des limites
limites_df <- data.frame(
  Type = c("Limite supérieure (Q3 + 1.5×IQR)", 
           "Limite inférieure (Q1 - 1.5×IQR)",
           "Nombre de valeurs atypiques"),
  Valeur = c(paste(round(limite_sup, 1), "secondes"),
             paste(round(limite_inf, 1), "secondes"),
             length(atypiques))
)

kable(limites_df,
      caption = "Détection des valeurs atypiques",
      align = "lr",
      col.names = c("Critère", "Valeur")) |>
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE)
Détection des valeurs atypiques
Critère Valeur
Limite supérieure (Q3 + 1.5×IQR) 10.5 secondes
Limite inférieure (Q1 - 1.5×IQR) -1.5 secondes
Nombre de valeurs atypiques 1
if (length(atypiques) > 0) {
  atypiques_df <- data.frame(
    Valeur = atypiques,
    Statut = "Atypique"
  )
  
  kable(atypiques_df,
        caption = "Valeurs atypiques détectées",
        align = "cr",
        col.names = c("Temps de réaction (sec)", "Statut")) |>
    kable_styling(bootstrap_options = c("striped", "hover"), 
                  full_width = FALSE) |>
    row_spec(0, bold = TRUE, background = "#ffcccc")
}
Valeurs atypiques détectées
Temps de réaction (sec) Statut
17 Atypique
# Graphique avec ggplot2
df_alarmes <- data.frame(
  valeur = alarmes,
  type = "Temps de réaction"
)

ggplot(df_alarmes, aes(x = type, y = valeur)) +
  geom_boxplot(fill = "#E3F2FD", color = "#1976D2", 
               linewidth = 1, outlier.color = "#D32F2F", 
               outlier.size = 4, outlier.shape = 17) +
  geom_jitter(width = 0.15, alpha = 0.5, size = 3, color = "#1976D2") +
  geom_hline(yintercept = 5, color = "#2E7D32", 
             linewidth = 1.2, linetype = "dashed") +
  geom_hline(yintercept = limite_sup, color = "#D32F2F", 
             linewidth = 1, linetype = "dotted") +
  annotate("text", x = 1.35, y = 5, 
           label = "Norme (5 sec)", color = "#2E7D32", 
           fontface = "bold", vjust = -0.5, size = 4) +
  annotate("text", x = 1.35, y = limite_sup, 
           label = paste0("Q3 + 1.5×IQR = ", round(limite_sup, 1)), 
           color = "#D32F2F", fontface = "bold", vjust = -0.5, size = 3.5) +
  labs(
    title = "Boîte de dispersion - Temps de réaction des alarmes",
    subtitle = "Détection des valeurs atypiques",
    x = "",
    y = "Temps de réaction (secondes)"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5, color = "gray30"),
    axis.title.y = element_text(face = "bold"),
    panel.grid.major.x = element_blank()
  )

Conclusion Méthode 1 : La valeur 17 secondes est ATYPIQUE car elle dépasse Q3 + 1.5×IQR = 10.5


3.4 Méthode 2 : Test de Shapiro-Wilk (Cours Chapitre 1.2.5)

Le test de Shapiro-Wilk (Chapitre 1.2.5) vérifie si les données suivent une loi normale. Ce test est adapté aux petits échantillons (n ≤ 50).

Hypothèses : - H₀ : Les données suivent une loi normale - H₁ : Les données ne suivent pas une loi normale

# Test de Shapiro-Wilk 
test_shapiro <- shapiro.test(alarmes)

# Test de Shapiro-Wilk 
test_shapiro <- shapiro.test(alarmes)

# Tableau des résultats du test
shapiro_df <- data.frame(
  Critère = c("Statistique W", "P-value", "Décision (α = 0.05)", "Interprétation"),
  Résultat = c(
    round(test_shapiro$statistic, 4),
    round(test_shapiro$p.value, 4),
    ifelse(test_shapiro$p.value < 0.05, "Rejet de H₀", "Acceptation de H₀"),
    ifelse(test_shapiro$p.value < 0.05, 
           "Données non normales - Anomalies présentes", 
           "Données normales")
  )
)

kable(shapiro_df,
      caption = "Test de Shapiro-Wilk",
      align = "lr",
      col.names = c("Critère", "Résultat")) |>
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE) |>
  row_spec(3:4, bold = TRUE, 
           background = ifelse(test_shapiro$p.value < 0.05, "#ffcccc", "#ccffcc"))
Test de Shapiro-Wilk
Critère Résultat
Statistique W 0.7911
P-value 6e-04
Décision (α = 0.05) Rejet de H₀
Interprétation Données non normales - Anomalies présentes

Conclusion Méthode 2 : Les données ne suivent pas une loi normale (p < 0.05), ce qui confirme la présence d’anomalies


3.5 Méthode 3 : Histogramme et Règle des 3σ (Cours Chapitre 1.1 et 1.2.1)

Si le processus suit une loi normale N(μ₀, σ₀), alors d’après la règle des 3σ (Proposition 01 du cours) :

99.73% des observations doivent être dans l’intervalle [μ₀ - 3σ₀, μ₀ + 3σ₀]

# Paramètres
mu_0 <- 5  # Norme
sigma_0 <- ecart_type  # Estimation

# Limites théoriques 3σ
limite_inf_3sigma <- mu_0 - 3 * sigma_0
limite_sup_3sigma <- mu_0 + 3 * sigma_0

# Observations hors limites
hors_limites <- alarmes[alarmes < limite_inf_3sigma | alarmes > limite_sup_3sigma]

# Observations hors limites
hors_limites <- alarmes[alarmes < limite_inf_3sigma | alarmes > limite_sup_3sigma]

# Tableau des limites 3sigma
limites_3sigma_df <- data.frame(
  Paramètre = c("Norme μ₀", "Écart-type σ (estimé)", 
                "Limite inférieure (μ₀ - 3σ)", 
                "Limite supérieure (μ₀ + 3σ)",
                "Observations hors limites"),
  Valeur = c(
    paste(mu_0, "secondes"),
    paste(round(sigma_0, 2), "secondes"),
    paste(round(limite_inf_3sigma, 2), "secondes"),
    paste(round(limite_sup_3sigma, 2), "secondes"),
    length(hors_limites)
  )
)

kable(limites_3sigma_df,
      caption = "Règle des 3σ",
      align = "lr",
      col.names = c("Paramètre", "Valeur")) |>
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE)
Règle des 3σ
Paramètre Valeur
Norme μ₀ 5 secondes
Écart-type σ (estimé) 3.46 secondes
Limite inférieure (μ₀ - 3σ) -5.39 secondes
Limite supérieure (μ₀ + 3σ) 15.39 secondes
Observations hors limites 1
if (length(hors_limites) > 0) {
  hors_limites_df <- data.frame(
    Valeur = hors_limites,
    Statut = "Hors limites 3σ"
  )
  
  kable(hors_limites_df,
        caption = "Observations hors des limites 3σ",
        align = "cr",
        col.names = c("Temps de réaction (sec)", "Statut")) |>
    kable_styling(bootstrap_options = c("striped", "hover"), 
                  full_width = FALSE) |>
    row_spec(0, bold = TRUE, background = "#ffcccc")
}
Observations hors des limites 3σ
Temps de réaction (sec) Statut
17 Hors limites 3σ
# Graphique avec ggplot2
df_hist <- data.frame(
  valeur = alarmes
)

ggplot(df_hist, aes(x = valeur)) +
  geom_histogram(bins = ceiling(sqrt(n)), 
                 fill = "#E3F2FD", color = "#1976D2", 
                 linewidth = 0.8, alpha = 0.8) +
  geom_vline(xintercept = mu_0, color = "#2E7D32", 
             linewidth = 1.5, linetype = "dashed") +
  geom_vline(xintercept = limite_inf_3sigma, color = "#D32F2F", 
             linewidth = 1.2, linetype = "dotted") +
  geom_vline(xintercept = limite_sup_3sigma, color = "#D32F2F", 
             linewidth = 1.2, linetype = "dotted") +
  annotate("text", x = mu_0, y = Inf, 
           label = "Norme (5 sec)", color = "#2E7D32", 
           fontface = "bold", vjust = 2, angle = 90, size = 4) +
  annotate("text", x = limite_sup_3sigma, y = Inf, 
           label = paste0("μ₀ + 3σ = ", round(limite_sup_3sigma, 1)), 
           color = "#D32F2F", fontface = "bold", 
           vjust = 2, angle = 90, size = 3.5) +
  labs(
    title = "Histogramme - Temps de réaction des alarmes",
    subtitle = "Règle des 3σ",
    x = "Temps de réaction (secondes)",
    y = "Fréquence"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5, color = "gray30"),
    axis.title = element_text(face = "bold")
  )

Conclusion Méthode 3 : 1 observation HORS des limites 3σ


3.6 Approche 4 : Cartes de Contrôle MSP

3.6.1 Tentative 1 : Carte X̄ classique - Est-elle applicable ?

Analyse de la configuration des données :

writeLines(c(
  "",
  "═══════════════════════════════════════════════════════════════",
  "     CONFIGURATION DES DONNÉES",
  "═══════════════════════════════════════════════════════════════",
  "",
  sprintf("Nombre d'alarmes testées    : %d", n),
  "Mesures par alarme          : 1 (temps de réaction unique)",
  "Taille d'échantillon (n)    : 1",
  "",
  "PRÉREQUIS CARTE X̄ (Cours MSP - Chapitre 3) :",
  "  • Sous-groupes rationnels de taille n ≥ 2 (idéalement n = 4 ou 5)",
  "  • Calcul de la moyenne X̄ᵢ pour chaque sous-groupe",
  "  • Calcul de l'étendue Rᵢ = max - min pour chaque sous-groupe",
  "",
  "PROBLÈME AVEC n=1 :",
  " Impossible de calculer une moyenne intra-groupe (X̄ᵢ = Xᵢ)",
  " Impossible de calculer Rᵢ (besoin de ≥ 2 valeurs)",
  " La carte X̄-R classique est STRICTEMENT NON APPLICABLE",
  "",
  "CONCLUSION :",
  "  → La carte X̄ du Chapitre 3 NE PEUT PAS être utilisée ici",
  "  → Nécessité d'une carte adaptée aux valeurs individuelles",
  "",
  "═══════════════════════════════════════════════════════════════",
  ""
))

═══════════════════════════════════════════════════════════════
     CONFIGURATION DES DONNÉES
═══════════════════════════════════════════════════════════════

Nombre d'alarmes testées    : 20
Mesures par alarme          : 1 (temps de réaction unique)
Taille d'échantillon (n)    : 1

PRÉREQUIS CARTE X̄ (Cours MSP - Chapitre 3) :
  • Sous-groupes rationnels de taille n ≥ 2 (idéalement n = 4 ou 5)
  • Calcul de la moyenne X̄ᵢ pour chaque sous-groupe
  • Calcul de l'étendue Rᵢ = max - min pour chaque sous-groupe

PROBLÈME AVEC n=1 :
 Impossible de calculer une moyenne intra-groupe (X̄ᵢ = Xᵢ)
 Impossible de calculer Rᵢ (besoin de ≥ 2 valeurs)
 La carte X̄-R classique est STRICTEMENT NON APPLICABLE

CONCLUSION :
  → La carte X̄ du Chapitre 3 NE PEUT PAS être utilisée ici
  → Nécessité d'une carte adaptée aux valeurs individuelles

═══════════════════════════════════════════════════════════════

Référence cours : Chapitre 3 définit la carte X̄ pour des sous-groupes de taille n ≥ 2. Notre configuration (n=1) viole cette condition fondamentale.


3.6.2 Tentative 2 : Carte X-mR (Individus et Étendues Mobiles) - Méthode recommandée

Principe (Cours MSP - Chapitre 5) :

Pour des valeurs individuelles (n=1), le cours recommande la Carte X-mR :

  • Carte X : Surveille les valeurs individuelles \(X_i\)
  • Carte mR : Surveille les étendues mobiles \(mR_i = |X_i - X_{i-1}|\)

Avantage clé : Estimation robuste de σ via les étendues mobiles :

\[\hat{\sigma} = \frac{\overline{mR}}{d_2} \quad \text{où} \quad \overline{mR} = \frac{1}{k-1}\sum_{i=2}^{k}|X_i - X_{i-1}|\]

avec \(d_2 = 1.128\) pour des paires de valeurs consécutives.

Pourquoi robuste ? Cette méthode utilise les différences locales entre valeurs successives, ce qui réduit l’influence des valeurs aberrantes isolées.

# ═══════════════════════════════════════════════════════════════
# CARTE X-mR (Individus et Étendues Mobiles)
# ═══════════════════════════════════════════════════════════════

# Calcul des étendues mobiles
mR <- abs(diff(alarmes))
mR_bar <- mean(mR)

# Constante pour n=2 (paires consécutives)
d2_mR <- 1.128

# Estimation ROBUSTE de σ
sigma_hat_mR <- mR_bar / d2_mR

# Paramètres
mu_norme <- 5

# Limites de contrôle pour Carte X (Individus)
LSC_X <- mu_norme + 3 * sigma_hat_mR
LC_X <- mu_norme
LIC_X <- max(0, mu_norme - 3 * sigma_hat_mR)

# Détection points hors contrôle
hors_X <- which(alarmes > LSC_X | alarmes < LIC_X)

# Affichage des calculs
writeLines(c(
  "",
  "┌─────────────────────────────────────────────────────────────┐",
  "│     CALCULS CARTE X (Individus) - Méthode X-mR              │",
  "├─────────────────────────────────────────────────────────────┤",
  sprintf("│  Étendue mobile moyenne (mR̄) = %.3f                        │", mR_bar),
  sprintf("│  Constante d₂ (n=2)          = %.3f                        │", d2_mR),
  sprintf("│  σ̂ = mR̄/d₂                   = %.3f                        │", sigma_hat_mR),
  "├─────────────────────────────────────────────────────────────┤",
  sprintf("│  LSC = μ₀ + 3σ̂               = %.2f                        │", LSC_X),
  sprintf("│  LC  = μ₀                    = %.2f                         │", LC_X),
  sprintf("│  LIC = μ₀ - 3σ̂               = %.2f                         │", LIC_X),
  "├─────────────────────────────────────────────────────────────┤",
  sprintf("│  Points hors contrôle        : %d / %d                        │", length(hors_X), n),
  "└─────────────────────────────────────────────────────────────┘",
  ""
))

┌─────────────────────────────────────────────────────────────┐
│     CALCULS CARTE X (Individus) - Méthode X-mR              │
├─────────────────────────────────────────────────────────────┤
│  Étendue mobile moyenne (mR̄) = 3.632                        │
│  Constante d₂ (n=2)          = 1.128                        │
│  σ̂ = mR̄/d₂                   = 3.219                        │
├─────────────────────────────────────────────────────────────┤
│  LSC = μ₀ + 3σ̂               = 14.66                        │
│  LC  = μ₀                    = 5.00                         │
│  LIC = μ₀ - 3σ̂               = 0.00                         │
├─────────────────────────────────────────────────────────────┤
│  Points hors contrôle        : 1 / 20                        │
└─────────────────────────────────────────────────────────────┘
# Tableau des résultats
resultats_xmr <- data.frame(
  Alarme = 1:n,
  Temps = alarmes,
  Statut = ifelse(alarmes > LSC_X | alarmes < LIC_X, 
                  "Hors contrôle", "Sous contrôle")
)

# Afficher seulement les points hors contrôle
if (length(hors_X) > 0) {
  kable(resultats_xmr[hors_X, ],
        caption = "Points hors contrôle détectés (Carte X-mR)",
        align = "c",
        row.names = FALSE) |>
    kable_styling(bootstrap_options = c("striped", "hover"), 
                  full_width = FALSE) |>
    row_spec(0, bold = TRUE, background = "#ffcccc")
}
Points hors contrôle détectés (Carte X-mR)
Alarme Temps Statut
15 17 Hors contrôle
# Graphique
df_xmr <- data.frame(
  Alarme = 1:n,
  Temps = alarmes,
  Statut = ifelse(alarmes > LSC_X | alarmes < LIC_X,
                  "Hors contrôle", "Sous contrôle")
)

ggplot(df_xmr, aes(x = Alarme, y = Temps)) +
  geom_hline(yintercept = LSC_X, color = "#D32F2F",
             linewidth = 1.2, linetype = "dashed") +
  geom_hline(yintercept = LC_X, color = "#2E7D32",
             linewidth = 1.3) +
  geom_hline(yintercept = LIC_X, color = "#D32F2F",
             linewidth = 1.2, linetype = "dashed") +
  geom_line(color = "#1976D2", linewidth = 1, alpha = 0.6) +
  geom_point(aes(color = Statut), size = 4) +
  scale_color_manual(values = c("Sous contrôle" = "#1976D2",
                                 "Hors contrôle" = "#D32F2F")) +
  annotate("text", x = 17, y = LSC_X,
           label = sprintf("LSC = %.2f", LSC_X),
           vjust = -0.7, color = "#D32F2F",
           fontface = "bold", size = 4) +
  annotate("text", x = 17, y = LC_X,
           label = "Norme = 5 sec",
           vjust = -0.7, color = "#2E7D32",
           fontface = "bold", size = 4) +
  annotate("text", x = 17, y = LIC_X,
           label = sprintf("LIC = %.2f", LIC_X),
           vjust = 1.7, color = "#D32F2F",
           fontface = "bold", size = 4) +
  labs(
    title = "Carte X (Individus) - Méthode X-mR",
    subtitle = "Approche conforme pour valeurs individuelles (n=1)",
    x = "Numéro d'alarme",
    y = "Temps de réaction (secondes)",
    color = "Statut"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5, color = "#2E7D32"),
    legend.position = "bottom",
    panel.grid.minor = element_blank()
  ) +
  scale_y_continuous(breaks = seq(0, max(alarmes) + 2, 2))
Carte X (Individus) - Méthode X-mR recommandée

Carte X (Individus) - Méthode X-mR recommandée

Interprétation :

writeLines(c(
  "",
  "═══════════════════════════════════════════════════════════════",
  "     INTERPRÉTATION CARTE X-mR",
  "═══════════════════════════════════════════════════════════════",
  "",
  sprintf("Points hors contrôle : %d / %d (%.0f%%)", 
          length(hors_X), n, 100*length(hors_X)/n),
  "",
  if (length(hors_X) > 0) {
    paste0("Alarmes concernées : ", paste(hors_X, collapse = ", "))
  } else {
    "Aucune alarme hors contrôle"
  },
  "",
  if (length(hors_X) > 0) {
    paste0("Valeurs : ", paste(alarmes[hors_X], collapse = ", "), " secondes")
  } else {
    ""
  },
  "",
  if (length(hors_X) > 0) {
    sprintf("Dépassements : %.2f secondes au-dessus de LSC", 
            max(alarmes[hors_X] - LSC_X))
  } else {
    ""
  },
  "",
  "CONCLUSION :",
  if (length(hors_X) > 0) {
    "  ️ PROCESSUS HORS CONTRÔLE"
  } else {
    "   Processus sous contrôle"
  },
  "",
  "═══════════════════════════════════════════════════════════════",
  ""
))

═══════════════════════════════════════════════════════════════
     INTERPRÉTATION CARTE X-mR
═══════════════════════════════════════════════════════════════

Points hors contrôle : 1 / 20 (5%)

Alarmes concernées : 15

Valeurs : 17 secondes

Dépassements : 2.34 secondes au-dessus de LSC

CONCLUSION :
  ️ PROCESSUS HORS CONTRÔLE

═══════════════════════════════════════════════════════════════

3.6.3 Analyse de sensibilité : Que se passe-t-il sans l’alarme à 17 secondes ?

Question : L’alarme n°15 (17 sec) est-elle un cas isolé ou révèle-t-elle un problème systémique ?

Méthode : Refaire l’analyse en excluant cette alarme.

# ═══════════════════════════════════════════════════════════════
# ANALYSE SANS L'ALARME ABERRANTE (17 sec)
# ═══════════════════════════════════════════════════════════════

# Identification de l'alarme aberrante
alarme_aberrante <- which(alarmes == max(alarmes))

# Données sans l'alarme aberrante
alarmes_filtrees <- alarmes[-alarme_aberrante]
n_filtrees <- length(alarmes_filtrees)

# Recalcul des étendues mobiles
mR_filtrees <- abs(diff(alarmes_filtrees))
mR_bar_filtrees <- mean(mR_filtrees)

# Nouvelle estimation de σ (réutilisation de d2_mR déjà défini)
sigma_hat_filtrees <- mR_bar_filtrees / d2_mR

# Nouvelles limites
LSC_X_filtrees <- mu_norme + 3 * sigma_hat_filtrees
LIC_X_filtrees <- max(0, mu_norme - 3 * sigma_hat_filtrees)

# Détection
hors_X_filtrees <- which(alarmes_filtrees > LSC_X_filtrees | 
                         alarmes_filtrees < LIC_X_filtrees)

# Statistiques comparatives
moyenne_originale <- mean(alarmes)
moyenne_filtree <- mean(alarmes_filtrees)

writeLines(c(
  "",
  "═══════════════════════════════════════════════════════════════",
  "  COMPARAISON : AVEC vs SANS alarme à 17 secondes",
  "═══════════════════════════════════════════════════════════════",
  "",
  "AVEC alarme à 17 sec (données originales) :",
  sprintf("  • Nombre d'alarmes           : %d", n),
  sprintf("  • Moyenne                    : %.2f sec", moyenne_originale),
  sprintf("  • Écart-type estimé (σ̂)      : %.3f", sigma_hat_mR),
  sprintf("  • LSC                        : %.2f", LSC_X),
  sprintf("  • Points hors contrôle       : %d", length(hors_X)),
  "",
  "SANS alarme à 17 sec (données filtrées) :",
  sprintf("  • Nombre d'alarmes           : %d", n_filtrees),
  sprintf("  • Moyenne                    : %.2f sec", moyenne_filtree),
  sprintf("  • Écart-type estimé (σ̂)      : %.3f", sigma_hat_filtrees),
  sprintf("  • LSC                        : %.2f", LSC_X_filtrees),
  sprintf("  • Points hors contrôle       : %d", length(hors_X_filtrees)),
  "",
  "IMPACT DE L'ALARME ABERRANTE :",
  sprintf("  • Variation moyenne          : %+.2f sec (%.0f%%)", 
          moyenne_originale - moyenne_filtree,
          100*(moyenne_originale - moyenne_filtree)/moyenne_filtree),
  sprintf("  • Variation σ̂                : %+.3f (%.0f%%)",
          sigma_hat_mR - sigma_hat_filtrees,
          100*(sigma_hat_mR - sigma_hat_filtrees)/sigma_hat_filtrees),
  sprintf("  • Variation LSC              : %+.2f",
          LSC_X - LSC_X_filtrees),
  "",
  "═══════════════════════════════════════════════════════════════",
  ""
))

═══════════════════════════════════════════════════════════════
  COMPARAISON : AVEC vs SANS alarme à 17 secondes
═══════════════════════════════════════════════════════════════

AVEC alarme à 17 sec (données originales) :
  • Nombre d'alarmes           : 20
  • Moyenne                    : 5.00 sec
  • Écart-type estimé (σ̂)      : 3.219
  • LSC                        : 14.66
  • Points hors contrôle       : 1

SANS alarme à 17 sec (données filtrées) :
  • Nombre d'alarmes           : 19
  • Moyenne                    : 4.37 sec
  • Écart-type estimé (σ̂)      : 2.315
  • LSC                        : 11.94
  • Points hors contrôle       : 0

IMPACT DE L'ALARME ABERRANTE :
  • Variation moyenne          : +0.63 sec (14%)
  • Variation σ̂                : +0.905 (39%)
  • Variation LSC              : +2.71

═══════════════════════════════════════════════════════════════
# Tableau comparatif
comparaison_df <- data.frame(
  Critère = c("Nombre d'alarmes", "Moyenne (sec)", "Écart-type σ̂", 
              "LSC", "LIC", "Points hors contrôle", "Conclusion"),
  Avec_17sec = c(
    n,
    sprintf("%.2f", moyenne_originale),
    sprintf("%.3f", sigma_hat_mR),
    sprintf("%.2f", LSC_X),
    sprintf("%.2f", LIC_X),
    length(hors_X),
    ifelse(length(hors_X) > 0, "Hors contrôle", "Sous contrôle")
  ),
  Sans_17sec = c(
    n_filtrees,
    sprintf("%.2f", moyenne_filtree),
    sprintf("%.3f", sigma_hat_filtrees),
    sprintf("%.2f", LSC_X_filtrees),
    sprintf("%.2f", LIC_X_filtrees),
    length(hors_X_filtrees),
    ifelse(length(hors_X_filtrees) > 0, "Hors contrôle", "Sous contrôle")
  )
)

kable(comparaison_df,
      caption = "Comparaison : Impact de l'alarme à 17 secondes",
      align = "lcc",
      col.names = c("Critère", "Avec alarme 17 sec", "Sans alarme 17 sec")) |>
  kable_styling(bootstrap_options = c("striped", "hover", "bordered"),
                full_width = FALSE) |>
  column_spec(1, bold = TRUE) |>
  row_spec(7, bold = TRUE, font_size = 13,
           background = ifelse(length(hors_X_filtrees) > 0, "#ffcccc", "#ccffcc"))
Comparaison : Impact de l’alarme à 17 secondes
Critère Avec alarme 17 sec Sans alarme 17 sec
Nombre d’alarmes 20 19
Moyenne (sec) 5.00 4.37
Écart-type σ̂
      3.219
par(mfrow = c(2, 1), mar = c(4, 4, 3, 2))

# Graphique 1 : Avec alarme à 17 sec
plot(1:n, alarmes, type = "b", pch = 19, col = "#1976D2",
     main = "AVEC alarme à 17 secondes (données originales)",
     xlab = "Numéro d'alarme", ylab = "Temps (sec)",
     ylim = c(0, max(alarmes) + 2), cex = 1.2, lwd = 1.5)
abline(h = LSC_X, col = "#D32F2F", lty = 2, lwd = 2)
abline(h = LC_X, col = "#2E7D32", lwd = 2)
abline(h = LIC_X, col = "#D32F2F", lty = 2, lwd = 2)
if (length(hors_X) > 0) {
  points(hors_X, alarmes[hors_X], col = "#D32F2F", pch = 19, cex = 2)
}
text(17, LSC_X, sprintf("LSC = %.2f", LSC_X),
     pos = 3, col = "#D32F2F", font = 2)
legend("topleft",
       legend = sprintf("%d point(s) hors contrôle", length(hors_X)),
       bty = "n", text.col = "#D32F2F", cex = 1.1)

# Graphique 2 : Sans alarme à 17 sec
indices_filtres <- (1:n)[-alarme_aberrante]
plot(indices_filtres, alarmes_filtrees, type = "b", pch = 19, col = "#1976D2",
     main = "SANS alarme à 17 secondes (données filtrées)",
     xlab = "Numéro d'alarme", ylab = "Temps (sec)",
     ylim = c(0, max(alarmes) + 2), cex = 1.2, lwd = 1.5)
abline(h = LSC_X_filtrees, col = "#D32F2F", lty = 2, lwd = 2)
abline(h = LC_X, col = "#2E7D32", lwd = 2)
abline(h = LIC_X_filtrees, col = "#D32F2F", lty = 2, lwd = 2)
if (length(hors_X_filtrees) > 0) {
  points(indices_filtres[hors_X_filtrees], 
         alarmes_filtrees[hors_X_filtrees], 
         col = "#D32F2F", pch = 19, cex = 2)
}
text(17, LSC_X_filtrees, sprintf("LSC = %.2f", LSC_X_filtrees),
     pos = 3, col = "#D32F2F", font = 2)
legend("topleft",
       legend = sprintf("%d point(s) hors contrôle", length(hors_X_filtrees)),
       bty = "n", 
       text.col = ifelse(length(hors_X_filtrees) > 0, "#D32F2F", "#2E7D32"), 
       cex = 1.1)
Comparaison graphique : Avec vs Sans alarme à 17 sec

Comparaison graphique : Avec vs Sans alarme à 17 sec

par(mfrow = c(1, 1))

Conclusion de l’analyse de sensibilité :

writeLines(c(
  "",
  "═══════════════════════════════════════════════════════════════",
  "  CONCLUSION : NATURE DE L'ANOMALIE",
  "═══════════════════════════════════════════════════════════════",
  "",
  if (length(hors_X_filtrees) == 0 && length(hors_X) > 0) {
    c(
      "ANOMALIE ISOLÉE",
      "",
      "OBSERVATIONS :",
      "  • Avec alarme 17 sec  : processus hors contrôle",
      "  • Sans alarme 17 sec  : processus sous contrôle",
      sprintf("  • Moyenne baisse de %.2f sec (%.0f%%)",
              moyenne_originale - moyenne_filtree,
              100*(moyenne_originale - moyenne_filtree)/moyenne_filtree),
      "",
      "INTERPRÉTATION :",
      "  → L'alarme à 17 sec est un cas isolé (défaut ponctuel)",
      "  → Le Processus de fabrication est globalement correct",
      "  → Les 19 autres alarmes sont conformes",
      "",
      "RECOMMANDATIONS :",
      "  1. Analyser l'alarme n°15 individuellement (défaut matériel ?)",
      "  2. La remplacer ou la réparer",
      "  3. Ne pas remettre en cause tout le processus de fabrication",
      "  4. Continuer la surveillance avec carte X-mR"
    )
  } else if (length(hors_X_filtrees) > 0) {
    c(
      " PROBLÈME SYSTÉMIQUE",
      "",
      "OBSERVATIONS :",
      "  • AVEC alarme 17 sec  : processus hors contrôle",
      "  • SANS alarme 17 sec  : processus encore hors contrôle",
      sprintf("  • %d alarme(s) hors contrôle même après filtrage", 
              length(hors_X_filtrees)),
      "",
      "INTERPRÉTATION :",
      "  → Le problème ne se limite pas à l'alarme 17 sec",
      "  → Le Processus de Fabrication présente des défauts multiples",
      "  → Cause assignable générale à identifier",
      "",
      "RECOMMANDATIONS :",
      "  1. Revoir complètement le processus de fabrication",
      "  2. Identifier les causes racines (matière, machine, méthode...)",
      "  3. Mettre en place des actions correctives globales",
      "  4. Refaire une validation complète après corrections"
    )
  } else {
    c(
      "Processus sous contrôle",
      "",
      "Aucune anomalie détectée (même avec l'alarme à 17 sec)"
    )
  },
  "",
  "═══════════════════════════════════════════════════════════════",
  ""
))

═══════════════════════════════════════════════════════════════
  CONCLUSION : NATURE DE L'ANOMALIE
═══════════════════════════════════════════════════════════════

ANOMALIE ISOLÉE

OBSERVATIONS :
  • Avec alarme 17 sec  : processus hors contrôle
  • Sans alarme 17 sec  : processus sous contrôle
  • Moyenne baisse de 0.63 sec (14%)

INTERPRÉTATION :
  → L'alarme à 17 sec est un cas isolé (défaut ponctuel)
  → Le Processus de fabrication est globalement correct
  → Les 19 autres alarmes sont conformes

RECOMMANDATIONS :
  1. Analyser l'alarme n°15 individuellement (défaut matériel ?)
  2. La remplacer ou la réparer
  3. Ne pas remettre en cause tout le processus de fabrication
  4. Continuer la surveillance avec carte X-mR

═══════════════════════════════════════════════════════════════

3.7 RÉPONSE À LA QUESTION

# Tableau récapitulatif des critères
conclusion_df <- data.frame(
  Critère = c(
    "1. Valeurs atypiques",
    "2. Test de normalité",
    "3. Règle des 3σ",
    "4. Conformité à la norme"
  ),
  Résultat = c(
    ifelse(length(atypiques) > 0, 
           paste(length(atypiques), "valeur atypique détectée"),
           "Aucune valeur atypique"),
    ifelse(test_shapiro$p.value < 0.05,
           "Rejet normalité (anomalies présentes)",
           "Données normales"),
    ifelse(length(hors_limites) > 0,
           paste(length(hors_limites), "observation hors limites"),
           "Toutes observations dans les limites"),
    ifelse(moyenne > mu_0,
           paste("Moyenne =", round(moyenne, 2), "sec > norme (5 sec)"),
           "Conforme à la norme")
  ),
  Statut = c(
    ifelse(length(atypiques) > 0, "Problème", "OK"),
    ifelse(test_shapiro$p.value < 0.05, "Problème", "OK"),
    ifelse(length(hors_limites) > 0, "Problème", "OK"),
    ifelse(moyenne > mu_0, "Problème", "OK")
  )
)

kable(conclusion_df,
      caption = "Synthèse des critères d'analyse",
      align = "llc",
      col.names = c("Critère", "Résultat", "Statut")) |>
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE) |>
  column_spec(3, bold = TRUE)
Synthèse des critères d’analyse
Critère Résultat Statut
  1. Valeurs atypiques
1 valeur atypique détectée Problème
  1. Test de normalité
Rejet normalité (anomalies présentes) Problème
  1. Règle des 3σ
1 observation hors limites Problème
  1. Conformité à la norme
Conforme à la norme OK

Question : Le responsable pense que cette production n’est pas sous contrôle (principalement à cause de l’alarme qui a mis 17 secondes pour réagir). Êtes-vous d’accord avec lui ?

Réponse : OUI, nous sommes d’accord avec le responsable.

Justification : Sur les 4 critères analysés, 3 indiquent un problème :

  • La valeur 17 secondes est identifiée comme atypique (dépasse Q3 + 1.5×IQR)
  • Le test de Shapiro-Wilk rejette la normalité des données (présence d’anomalies)
  • Des observations sont hors des limites 3σ

Recommandations :

  1. Retirer l’alarme défectueuse ( 17 secondes)
  2. Enquêter sur le scauses du dysfonctionnement
  3. Recalibrer le processus de fabrication
  4. Renforcer les contrôles de qualité.

4 Exemple 3

4.1 Contexte

Nous considérons un procédé industriel qui, sous contrôle, suit une loi normale avec paramètres inconnus. L’objectif est de construire une carte de contrôle de Shewhart \((\bar{X}, R)\) de Phase I en utilisant les observations issues de 20 sous-groupes rationnels de taille \(n=4\).

Cette carte sera utilisée pour surveiller la position (\(\bar{X}\)) et la dispersion (\(R\)) du processus. Une analyse des résultats permettra de déterminer si le processus est sous contrôle ou nécessite des ajustements.

4.2 Estimation de \(\mu\) et \(\sigma\) (Cours MSP - Chapitre 3)

Dans le cas d’une carte de contrôle de phase I, il est nécessaire d’estimer les quantités \(\mu\) et \(\sigma\). L’idée est alors d’utiliser un maximum d’information, c’est-à-dire la totalité des \(nk\) observations.

4.2.1 Estimation de \(\mu\)

Nous avons déjà vu que, pour chaque sous-groupe rationnel, \(\bar{X}_i\) est un estimateur sans biais de \(\mu\). Ces variables aléatoires ayant toutes une même dispersion, on sait qu’alors un estimateur sans biais plus efficace que chacun des \(\bar{X}_i\) est obtenu à partir de la population totale via la relation suivante :

\[\hat{\mu} = \bar{\bar{X}} = \frac{1}{k} \sum_{i=1}^k \bar{X}_i\]

4.2.2 Estimation de \(\sigma\)

De même, pour chaque sous-groupe rationnel, \(\frac{R_i}{d_2(n)}\) est un estimateur sans biais de \(\sigma\). Ces variables aléatoires ayant toutes une même dispersion, on sait qu’alors un estimateur sans biais plus efficace que chacun des \(\frac{R_i}{d_2(n)}\) est obtenu à partir de la population totale via la relation suivante :

\[\hat{\sigma} = \frac{\bar{R}}{d_2(n)} = \frac{1}{kd_2(n)} \sum_{i=1}^k R_i\]

où : - \(R_i = X_{i(n)} - X_{i(1)} = \max(X_{ij}) - \min(X_{ij})\) est l’étendue de l’échantillon \(i\) - \(\bar{R} = \frac{1}{k}\sum_{i=1}^k R_i\) est l’étendue moyenne - \(d_2(n)\) est une constante tabulée dépendant de \(n\)

Remarque du cours : Lorsque les \(X_{ij}\) sont des variables aléatoires indépendantes de même loi normale alors \(R_i\) suit une loi de probabilité complexe mais que l’on peut néanmoins déterminer explicitement. On montre alors que si \(X_{ij}\) suit une loi normale \(\mathcal{N}(\mu, \sigma)\) et si chaque sous-groupe rationnel est de taille \(n\) alors :

\[\mathbb{E}(R_i) = d_2(n) \cdot \sigma \quad \text{et} \quad \sigma(R_i) = d_3(n) \cdot \sigma\]

où les coefficients \(d_2\) et \(d_3\) sont tabulés.

# Chargement des données
Exemple3 <- read.csv("Exemple3.txt", sep = "", header = FALSE)

Nos données comportent deux variables et 80 observations, réparties en 20 échantillons, chacun comportant 4 éléments.

# Initialisation des vecteurs pour stocker les moyennes et les étendues
k <- 20  # Nombre d'échantillons
x_ex3 <- numeric(k)
r_ex3 <- numeric(k)

# Boucle pour calculer la moyenne et l'étendue pour chaque groupe
for (i in 1:k) {
  sous_groupe <- Exemple3$V2[Exemple3$V1 == i]
  n <- length(sous_groupe)
  r_ex3[i] <- max(sous_groupe) - min(sous_groupe)
  x_ex3[i] <- mean(sous_groupe)
}

# Constantes pour n=4 (valeurs tabulées du cours)
d2 <- 2.059  # Coefficient d2
d3 <- 0.880  # Coefficient d3

# Estimation des paramètres
mu_hat <- mean(x_ex3)        # Estimation de μ
r_bar <- mean(r_ex3)         # Étendue moyenne
sigma_hat <- r_bar / d2      # Estimation de σ

# Affichage des résultats
writeLines(c(
  "",
  "═══════════════════════════════════════════════════",
  "    ESTIMATION DES PARAMÈTRES (PHASE I)",
  "═══════════════════════════════════════════════════",
  sprintf("Moyenne estimée (μ̂)     : %.4f", mu_hat),
  sprintf("Étendue moyenne (R̄)      : %.4f", r_bar),
  sprintf("Écart-type estimé (σ̂)   : %.4f", sigma_hat),
  sprintf("Constante d2 pour n=%d   : %.3f", n, d2),
  "═══════════════════════════════════════════════════",
  ""
))

═══════════════════════════════════════════════════
    ESTIMATION DES PARAMÈTRES (PHASE I)
═══════════════════════════════════════════════════
Moyenne estimée (μ̂)     : 20.0449
Étendue moyenne (R̄)      : 2.3194
Écart-type estimé (σ̂)   : 1.1265
Constante d2 pour n=4   : 2.059
═══════════════════════════════════════════════════

Interprétation : Ces valeurs estimées (\(\hat{\mu}\) et \(\hat{\sigma}\)) serviront de référence pour la surveillance future du processus (Phase II).

4.3 Carte de Contrôle du type \(\bar{X}\)

4.3.1 Construction

Le principe de construction est le suivant :

1. Positionnement de la ligne centrale à la valeur théorique moyenne : \[\mathbb{E}[\bar{X}_i] = \mu \simeq \hat{\mu} = \bar{\bar{X}}\]

2. Positionnement des limites de contrôle selon la règle des \(3\sigma\) :

\[\begin{align} \text{LSC} &= \hat{\mu} + 3 \cdot \frac{\hat{\sigma}}{\sqrt{n}} = \bar{\bar{X}} + 3 \cdot \frac{\bar{R}}{d_2\sqrt{n}} \\[0.3cm] \text{LC} &= \hat{\mu} = \bar{\bar{X}} \\[0.3cm] \text{LCI} &= \hat{\mu} - 3 \cdot \frac{\hat{\sigma}}{\sqrt{n}} = \bar{\bar{X}} - 3 \cdot \frac{\bar{R}}{d_2\sqrt{n}} \end{align}\]

# Calcul des limites pour carte X̄
sigma_xbar <- sigma_hat / sqrt(n)
LIC_xbar3 <- mu_hat - 3 * sigma_xbar
LSC_xbar3 <- mu_hat + 3 * sigma_xbar

# Affichage des limites
afficher_limites(LSC_xbar3, mu_hat, LIC_xbar3, sigma_xbar, "Carte X̄ Phase I")

┌─────────────────────────────────────────────┐
│ LIMITES DE CONTRÔLE (Carte X̄ Phase I)         │
├─────────────────────────────────────────────┤
│  LSC =  21.7346                             │
│  LC  =  20.0449                             │
│  LCI =  18.3553                             │
├─────────────────────────────────────────────┤
│  σ     =  0.5632                           │
└─────────────────────────────────────────────┘
df_xbar3 <- data.frame(
  echantillon = 1:k,
  moyenne = x_ex3,
  hors_limite = ifelse(x_ex3 > LSC_xbar3 | x_ex3 < LIC_xbar3, 
                       "Hors contrôle", "Sous contrôle")
)

ggplot(df_xbar3, aes(x = echantillon, y = moyenne)) +
  annotate("rect", xmin = 0, xmax = k+1, 
           ymin = LIC_xbar3, ymax = LSC_xbar3,
           alpha = 0.15, fill = "lightgreen") +
  geom_hline(yintercept = mu_hat, color = "#2E7D32", linewidth = 1.2) +
  geom_hline(yintercept = LSC_xbar3, color = "#D32F2F", 
             linewidth = 1, linetype = "dashed") +
  geom_hline(yintercept = LIC_xbar3, color = "#D32F2F", 
             linewidth = 1, linetype = "dashed") +
  geom_line(color = "#1976D2", linewidth = 1) +
  geom_point(aes(color = hors_limite), size = 3.5) +
  annotate("text", x = k-2, y = LSC_xbar3, 
           label = paste("LSC =", round(LSC_xbar3, 3)),
           vjust = -0.7, color = "#D32F2F", fontface = "bold") +
  annotate("text", x = k-2, y = LIC_xbar3, 
           label = paste("LCI =", round(LIC_xbar3, 3)),
           vjust = 1.7, color = "#D32F2F", fontface = "bold") +
  annotate("text", x = k-2, y = mu_hat, 
           label = paste("μ̂ =", round(mu_hat, 3)),
           vjust = -0.7, color = "#2E7D32", fontface = "bold") +
  scale_color_manual(values = c("Sous contrôle" = "#1976D2", 
                                 "Hors contrôle" = "#D32F2F")) +
  labs(
    title = "Carte X barre - Phase I",
    subtitle = "Paramètres estimés à partir des données",
    x = "Numéro d'échantillon",
    y = "Moyenne",
    color = "État"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5, color = "gray30"),
    panel.grid.minor = element_blank(),
    legend.position = "bottom"
  )
Carte X̄ Phase I - Paramètres estimés

Carte X̄ Phase I - Paramètres estimés

Le processus semble être sous contrôle en moyenne. Aucun échantillon ne présente de moyenne anormalement élevée ou basse.

4.4 Carte de Contrôle du type \(R\)

4.4.1 Construction (Cours MSP - Chapitre 3)

Le principe de construction est le suivant :

1. Positionnement de la ligne centrale à la valeur théorique moyenne suivante : \[\mathbb{E}[R_i] = d_2(n) \cdot \sigma \simeq d_2(n) \cdot \hat{\sigma} = \bar{R}\]

2. Positionnement des limites de contrôle selon la règle des \(3\sigma\) à partir de :

\[\sigma(R_i) = d_3(n) \cdot \sigma \simeq d_3(n) \cdot \hat{\sigma} = \frac{d_3(n)}{d_2(n)} \cdot \bar{R}\]

Il vient donc :

\[\begin{align} \text{LSC} &= \bar{R} + 3 \cdot \frac{d_3(n)}{d_2(n)} \cdot \bar{R} \\[0.3cm] \text{LC} &= \bar{R} \\[0.3cm] \text{LCI} &= \bar{R} - 3 \cdot \frac{d_3(n)}{d_2(n)} \cdot \bar{R} \end{align}\]

Remarque du cours : Attention au fait que, contrairement à la carte de contrôle \(\bar{X}\), les quantités représentées sont ici des réalisations des variables aléatoires réelles \(R_i\) qui, même sous hypothèse de normalité des observations, ne suivent pas naturellement une loi normale ! Il peut en découler des problèmes concernant les limites de contrôle ainsi calculées (par exemple obtenir LCI négative, ce qui n’a pas de sens). Dans ce cas, on pose LCI = 0.

# Limites carte R
sigma_r <- (d3/d2) * r_bar
LIC_r <- r_bar - 3 * sigma_r
LSC_r <- r_bar + 3 * sigma_r

if (LIC_r < 0) LIC_r <- 0

# Affichage des limites
afficher_limites(LSC_r, r_bar, LIC_r, sigma_r, "Carte R")

┌─────────────────────────────────────────────┐
│ LIMITES DE CONTRÔLE (Carte R        )         │
├─────────────────────────────────────────────┤
│  LSC =   5.2932                             │
│  LC  =   2.3194                             │
│  LCI =   0.0000                             │
├─────────────────────────────────────────────┤
│  σ     =  0.9913                           │
└─────────────────────────────────────────────┘
df_r <- data.frame(
  echantillon = 1:k,
  etendue = r_ex3,
  hors_limite = ifelse(r_ex3 > LSC_r | r_ex3 < LIC_r, 
                       "Hors contrôle", "Sous contrôle")
)

ggplot(df_r, aes(x = echantillon, y = etendue)) +
  annotate("rect", xmin = 0, xmax = k+1, 
           ymin = LIC_r, ymax = LSC_r,
           alpha = 0.15, fill = "lightblue") +
  geom_hline(yintercept = r_bar, color = "#2E7D32", linewidth = 1.2) +
  geom_hline(yintercept = LSC_r, color = "#D32F2F", 
             linewidth = 1, linetype = "dashed") +
  geom_hline(yintercept = LIC_r, color = "#D32F2F", 
             linewidth = 1, linetype = "dashed") +
  geom_line(color = "#1976D2", linewidth = 1) +
  geom_point(aes(color = hors_limite), size = 3.5) +
  scale_color_manual(values = c("Sous contrôle" = "#1976D2", 
                                 "Hors contrôle" = "#D32F2F")) +
  labs(
    title = "Carte R - Phase I",
    subtitle = "Surveillance de la variabilité par l'étendue",
    x = "Numéro d'échantillon",
    y = "Étendue (R)",
    color = "État"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5, color = "gray30"),
    panel.grid.minor = element_blank(),
    legend.position = "bottom"
  )
Carte R - Surveillance de l'étendue

Carte R - Surveillance de l’étendue

Le processus semble être sous contrôle en termes de dispersion.

Conclusion Exemple 3 :

Nous avons établi une carte de contrôle de Shewhart \((\bar{X}, R)\) de Phase I. Le processus semble être sous contrôle tant en termes de moyenne qu’en termes d’étendue. Les deux cartes montrent un processus sous contrôle statistique.

Les paramètres estimés peuvent être utilisés comme référence pour la surveillance future : - \(\mu_0 = \hat{\mu} = 20.0449\) - \(\sigma_0 = \hat{\sigma} = 1.1265\)

5 Exemple 4 : Cartes de Contrôle aux Attributs

5.1 Contexte

Une entreprise s’intéresse au nombre total de défauts d’aspect comptabilisés sur un produit fini. Pour être sous contrôle, la production doit être réalisée avec un nombre moyen de défauts d’aspect de l’ordre de 8. Ces divers nombres ont été relevés pour un échantillon de 50 observations.

On impose ici une étude à l’aide d’une carte de contrôle de phase II avec des limites probabilistes associées à un risque d’erreur de première espèce ne dépassant pas 10%.

5.2 Cartes de Contrôle aux Attributs (Cours MSP - Chapitre 4)

5.2.1 Principe Général

Nous nous intéressons au nombre moyen de défauts, c’est pourquoi nous utiliserons des cartes de contrôle pour attributs, et plus précisément la carte c.

Les cartes de contrôle aux attributs s’appliquent lorsque la caractéristique de qualité n’est pas mesurable numériquement mais peut être classée en catégories (conforme/non conforme, nombre de défauts, etc.).

Types de cartes aux attributs :

  • Carte \(p\) : Proportion de non-conformes (taille variable)
  • Carte \(np\) : Nombre de non-conformes (taille fixe)
  • Carte \(c\) : Nombre de défauts par unité (taille fixe)

5.2.2 Théorie : Loi de Poisson (Cours MSP - Chapitre 4)

Quand on compte des événements rares sur une unité (défauts, non-conformités), le nombre \(C\) suit une loi de Poisson de paramètre \(\lambda\) :

\[C \sim \mathcal{P}(\lambda) \quad \Rightarrow \quad P(C = k) = \frac{\lambda^k e^{-\lambda}}{k!}\]

Propriétés de la loi de Poisson :

  • \(\mathbb{E}[C] = \lambda\)
  • \(\text{Var}(C) = \lambda\)
  • \(\sigma(C) = \sqrt{\lambda}\)

5.2.3 Carte de Contrôle de type \(c\) (Cours MSP - Chapitre 4)

La carte \(c\) est utilisée pour surveiller le nombre de défauts lorsque :

  1. La taille de l’unité inspectée est constante
  2. Les défauts sont rares et indépendants
  3. La probabilité d’occurrence d’un défaut est constante

5.2.3.1 Limites de Contrôle Classiques (Règle des 3σ)

Dans le cas standard, les limites de contrôle sont données par :

\[\begin{align} \text{LSC} &= \lambda_0 + 3\sqrt{\lambda_0} \\[0.3cm] \text{LC} &= \lambda_0 \\[0.3cm] \text{LCI} &= \lambda_0 - 3\sqrt{\lambda_0} \end{align}\]

Si LCI < 0, on pose LCI = 0.

5.2.3.2 Limites Probabilistes (Cours MSP - Chapitre 4)

Pour trouver les limites de contrôle avec un risque \(\alpha\), il est nécessaire de déterminer les quantiles de la distribution de Poisson avec \(\lambda = \lambda_0\) qui couvrent \((1-\alpha) \times 100\%\) de la probabilité.

Construction des limites probabilistes :

En pratique, pour une carte de contrôle en phase II avec limites probabilistes, les limites sont calculées en trouvant les valeurs \(c\) telles que :

\[P(C \leq \text{LCI}) \leq \frac{\alpha}{2} \quad \text{et} \quad P(C \geq \text{LSC}) \leq \frac{\alpha}{2}\]

\(\alpha\) est le risque total d’erreur de première espèce, donc \(\frac{\alpha}{2}\) de chaque côté.

Formulation mathématique :

  • LCI est la plus grande valeur telle que \(P(C \leq \text{LCI}) \leq \frac{\alpha}{2}\)
  • LSC est la plus petite valeur telle que \(P(C \geq \text{LSC}) \leq \frac{\alpha}{2}\)

En utilisant les quantiles de la loi de Poisson :

\[\begin{align} \text{LCI} &= Q_{\alpha/2}(\lambda_0) \\[0.3cm] \text{LC} &= \lambda_0 \\[0.3cm] \text{LSC} &= Q_{1-\alpha/2}(\lambda_0) \end{align}\]

\(Q_p(\lambda)\) désigne le quantile d’ordre \(p\) de la loi \(\mathcal{P}(\lambda)\).

# Chargement des données
Exemple4 <- read.csv("Exemple4.txt", header = FALSE)
x_ex4 <- as.numeric(Exemple4$V1)

Nos données comportent une variable et 50 observations.

lambda <- 8
sigma <- sd(Exemple4$V1)
alpha <- 0.10

# Limites probabilistes (quantiles de la loi de Poisson)
# Recherche de LIC
LIC_c <- 0
for (k in 0:20) {
    if (ppois(k, lambda) <= alpha/2) {
        LIC_c <- k
      } else {
          break
        }
  }

# Recherche de LSC
LSC_c <- 20
for (k in 1:20) {
    if (1 - ppois(k - 1, lambda) <= alpha/2) {
        LSC_c <- k
        break
      }
}

# Affichage des limites

writeLines(c(
  "",
  "================================================================",
  "   LIMITES PROBABILISTES (alpha = 10%)",
  "================================================================",
  sprintf("Risque total : alpha = %.0f%%", alpha*100),
  sprintf("Risque par queue : alpha/2 = %.0f%%", (alpha/2)*100),
  "",
  sprintf("LCI = %d", LIC_c),
  sprintf("  Cible : P(C <= LCI) = alpha/2 = %.0f%%", (alpha/2)*100),
  sprintf("  Reel  : P(C <= %d) = %.1f%%", LIC_c, 100*ppois(LIC_c, lambda)),
  "",
  sprintf("LC  = %d", lambda),
  "",
  sprintf("LSC = %d", LSC_c),
  sprintf("  Cible : P(C >= LSC) = alpha/2 = %.0f%%", (alpha/2)*100),
  sprintf("  Reel  : P(C >= %d) = %.1f%%", LSC_c, 100*(1-ppois(LSC_c-1, lambda))),
  "",
  sprintf("Probabilite d'etre dans les limites : %.1f%%", 
          100*(ppois(LSC_c-1, lambda) - ppois(LIC_c, lambda)),
  "",
  "NOTE : En raison de la nature discrete de la loi de Poisson,",
  "       les probabilites reelles different des cibles theoriques.",
  "================================================================",
  ""
)))

================================================================
   LIMITES PROBABILISTES (alpha = 10%)
================================================================
Risque total : alpha = 10%
Risque par queue : alpha/2 = 5%

LCI = 3
  Cible : P(C <= LCI) = alpha/2 = 5%
  Reel  : P(C <= 3) = 4.2%

LC  = 8

LSC = 14
  Cible : P(C >= LSC) = alpha/2 = 5%
  Reel  : P(C >= 14) = 3.4%

Probabilite d'etre dans les limites : 92.3%

Interprétation :

Les limites sont déterminées par les quantiles de la loi de Poisson : - LCI = 3 : Plus petit entier k tel que P(C ≤ k) ≥ α/2 - Valeur réelle : P(C ≤ 3) ≈ 4.2% - Cible théorique : 5% - LSC = 14 : Plus petit entier k tel que P(C ≤ k) ≥ 1-α/2
- Valeur réelle : P(C ≥ 14) ≈ 3.4% - Cible théorique : 5%

df_c <- data.frame(
  observation = 1:length(x_ex4),
  defauts = x_ex4,
  hors_limite = ifelse(x_ex4 > LSC_c | x_ex4 < LIC_c, 
                       "Hors contrôle", "Sous contrôle")
)

ggplot(df_c, aes(x = observation, y = defauts)) +
  annotate("rect", xmin = 0, xmax = length(x_ex4)+1, 
           ymin = LIC_c, ymax = LSC_c,
           alpha = 0.15, fill = "lightyellow") +
  geom_hline(yintercept = lambda, color = "#2E7D32", linewidth = 1.2) +
  geom_hline(yintercept = LSC_c, color = "#D32F2F", 
             linewidth = 1, linetype = "dashed") +
  geom_hline(yintercept = LIC_c, color = "#D32F2F", 
             linewidth = 1, linetype = "dashed") +
  geom_line(color = "#1976D2", linewidth = 1) +
  geom_point(aes(color = hors_limite), size = 3) +
  scale_color_manual(values = c("Sous contrôle" = "#1976D2", 
                                 "Hors contrôle" = "#D32F2F")) +
  labs(
    title = "Carte c - Nombre de Défauts d'Aspect",
    subtitle = "Loi de Poisson, lambda = 8, risque alpha = 10%",
    x = "Numéro d'observation",
    y = "Nombre de défauts",
    color = "État"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5),
    panel.grid.minor = element_blank(),
    legend.position = "bottom"
  ) +
  scale_y_continuous(breaks = seq(0, max(x_ex4), 2))
Carte c - Nombre de défauts avec limites probabilistes

Carte c - Nombre de défauts avec limites probabilistes

Le processus semble être hors de contrôle, car deux points dépassent les limites.

Interprétation : Les limites probabilistes sont plus larges que les limites \(3\sigma\) classiques car on accepte un risque de 10% au lieu de 0,27%. Cela réduit les fausses alarmes mais peut retarder la détection de déréglages.

6 Exemple 5 : Cartes de Contrôle pour Petits Déréglages

6.1 Contexte et Problématique

On considère ici un procédé industriel qui, sous contrôle, doit suivre une loi normale de type \(\mathcal{N}(50, 1)\). On aimerait savoir si le procédé est sous contrôle ou non en moyenne sachant qu’un déréglage lent est suspecté. Pour cela, 50 échantillons de 10 observations ont été prélevés.

Question : Proposer une méthode d’étude pour ces observations et commenter les résultats obtenus.

6.2 Analyse du Problème et Choix de la Méthode

6.2.1 Pourquoi les Cartes Classiques Ne Conviennent Pas ?

6.2.1.1 Limites de la Carte de Shewhart \(\bar{X}\) (Cours MSP - Chapitre 5)

D’après le Chapitre 5 du cours :

“Les cartes de contrôle de type Shewhart (\(\bar{X}\), \(R\), \(S\)) sont très efficaces pour détecter les grands déréglages (variations importantes et brutales), mais elles sont peu sensibles aux petits déréglages ou aux dérives lentes du processus.”

Démonstration pour notre cas :

Pour une carte \(\bar{X}\) classique avec \(n=10\), \(\mu_0 = 50\), \(\sigma_0 = 1\) :

\[\text{LSC} = \mu_0 + 3\frac{\sigma_0}{\sqrt{n}} = 50 + 3\frac{1}{\sqrt{10}} = 50 + 3 \times 0.316 = 50.949\] \[\text{LCI} = \mu_0 - 3\frac{\sigma_0}{\sqrt{n}} = 50 - 0.949 = 49.051\]

Problème : Si le processus dérive lentement (ex: \(+0.2\) par échantillon), chaque observation reste dans les limites \([49.051; 50.949]\) pendant plusieurs échantillons. La carte \(\bar{X}\) ne détecte rien car elle traite chaque échantillon indépendamment sans tenir compte de l’historique.

Exemple numérique :


================================================================
  SIMULATION : Derive lente (+0.05 par echantillon)
================================================================
Echantillon 1 : X̄ = 50.10  [Dans limites] V
Echantillon 2 : X̄ = 50.15  [Dans limites] V
Echantillon 3 : X̄ = 50.20  [Dans limites] V
Echantillon 4 : X̄ = 50.25  [Dans limites] V
Echantillon 5 : X̄ = 50.30  [Dans limites] V
Echantillon 6 : X̄ = 50.35  [Dans limites] V
Echantillon 7 : X̄ = 50.40  [Dans limites] V

-> Carte X-bar classique : AUCUNE DETECTION
-> Derive de 0.4 (soit 40%% de sigma) NON DETECTEE !
================================================================

6.2.2 Pourquoi Choisir des Cartes à Mémoire ?

Principe:

Les cartes à mémoire (MA et EWMA) accumulent l’information des échantillons passés pour détecter les tendances et les dérives progressives.

Deux approches complémentaires :

  1. Carte MA (Moving Average) : Moyenne mobile sur une fenêtre de \(h\) échantillons
  2. Carte EWMA (Exponentially Weighted Moving Average) : Moyenne pondérée exponentiellement

6.3 Carte de Contrôle du type MA

6.3.1 Contexte

On considère un procédé industriel qui, lorsqu’il est sous contrôle, suit une loi normale de type \(\mathcal{N}(50, 1)\). L’objectif est de déterminer si le procédé est sous contrôle, notamment en moyenne, en prenant en compte la possibilité d’un déréglage lent.

À cette fin, 50 échantillons de 10 observations chacun ont été prélevés.

6.3.2 Théorie (Cours MSP - Chapitre 5)

Une carte de contrôle de type \(\bar{X}\) repose sur la représentation des moyennes des sous-groupes rationnels \(\bar{x}_1, \bar{x}_2, \ldots, \bar{x}_k\). L’objectif des cartes de contrôle de type MA (Moving Average) est de remplacer ces moyennes par des moyennes mobiles d’ordre \(h\), afin de détecter les petits dérèglements dans le processus.

Définition 10 du cours : Une carte de contrôle de type MA, construite avec des moyennes mobiles d’ordre \(h\), consiste en la représentation des valeurs \(m_1, \ldots, m_k\) réalisations des variables aléatoires \(M_1, \ldots, M_k\) définies par :

\[M_i = \begin{cases} \displaystyle\frac{\bar{X}_i + \bar{X}_{i-1} + \ldots + \bar{X}_1}{i} & \text{si } i < h \\[0.5cm] \displaystyle\frac{\bar{X}_i + \bar{X}_{i-1} + \ldots + \bar{X}_{i-h+1}}{h} & \text{si } i \geq h \end{cases}\]

On parlera de moyennes mobiles incomplètes pour les \((h-1)\) premiers relevés et de moyennes mobiles complètes ensuite.

Remarque du cours : Il est clair que dans la situation où \(h = 1\) on retombe alors sur la carte classique de type \(\bar{X}\). Lorsque \(h \geq k\) alors la carte de contrôle utilisée tient compte de l’intégralité du passé quel que soit le sous-groupe rationnel considéré.

6.3.3 Limites de Contrôle (Proposition 11 du cours)

On utilise ici la méthode classique de construction avec la ligne centrale positionnée à la valeur moyenne théorique et les limites de contrôle découlant de la règle des \(3\sigma\). Il en découle que :

1. Positionnement de la ligne centrale à la valeur théorique \(\mathbb{E}[M_i]\) avec donc (valeur identique pour le cas des moyennes mobiles incomplètes) :

\[\mathbb{E}[M_i] = \mathbb{E}\left[\frac{\bar{X}_i + \bar{X}_{i-1} + \ldots + \bar{X}_{i-h+1}}{h}\right] = \frac{1}{h} \sum_{j=0}^{h-1} \mathbb{E}[\bar{X}_{i-j}] = \frac{h\mu_0}{h} = \mu_0\]

puisque si le processus est sous contrôle chaque observation est une réalisation de la loi normale \(\mathcal{N}(\mu_0, \sigma_0)\) et donc \(\mathbb{E}[\bar{X}_{i-j}] = \mu_0\).

2. Positionnement des limites de contrôle selon la règle des \(3\sigma\). Il faut alors distinguer le cas des moyennes mobiles complètes ou incomplètes puisqu’il vient (d’après l’indépendance des observations) :

  • Si \(M_i = \frac{\bar{X}_i + \bar{X}_{i-1} + \ldots + \bar{X}_1}{i}\) alors : \[\text{Var}(M_i) = \frac{1}{i^2} \sum_{j=0}^{i-1} \text{Var}(\bar{X}_{i-j}) = \frac{i \cdot \frac{\sigma_0^2}{n}}{i^2} = \frac{\sigma_0^2}{ni}\]

  • Si \(M_i = \frac{\bar{X}_i + \bar{X}_{i-1} + \ldots + \bar{X}_{i-h+1}}{h}\) alors : \[\text{Var}(M_i) = \frac{1}{h^2} \sum_{j=0}^{h-1} \text{Var}(\bar{X}_{i-j}) = \frac{h \cdot \frac{\sigma_0^2}{n}}{h^2} = \frac{\sigma_0^2}{nh}\]

Proposition 11 du cours : Une carte de contrôle de type MA, utilisée avec des moyennes mobiles d’ordre \(h\), est déterminée par :

  1. La ligne centrale à la valeur \(\mu_0\)

  2. Les limites de contrôle de valeurs (pour le sous-groupe rationnel \(i = 1, 2, \ldots, k\)) :

\[\text{LCI}_i = \mu_0 - 3 \cdot \frac{\sigma_0}{\sqrt{ni}} \quad \text{et} \quad \text{LSC}_i = \mu_0 + 3 \cdot \frac{\sigma_0}{\sqrt{ni}} \quad \text{si } i < h\]

\[\text{LCI}_i = \mu_0 - 3 \cdot \frac{\sigma_0}{\sqrt{nh}} \quad \text{et} \quad \text{LSC}_i = \mu_0 + 3 \cdot \frac{\sigma_0}{\sqrt{nh}} \quad \text{si } i \geq h\]

Ceci conduit graphiquement à des limites de contrôle en créneaux comme sur la carte suivante (construite ici avec des moyennes mobiles d’ordre \(h = 3\)).

# Chargement des données
Exemple5 <- read.csv("Exemple5.txt", sep = "", header = FALSE)

Nos données comportent deux variables et 500 observations, réparties en 50 échantillons, chacun comportant 10 éléments.

# Calcul unifié de toutes les moyennes mobiles (ordres 3, 4, 5)


# Calcul des moyennes des échantillons

x_ex5 <- numeric(50)
for (i in 1:50) {
  x_ex5[i] <- mean(Exemple5$V2[Exemple5$V1 == i])
}

# Paramètres
mu_0 <- 50
sigma_0 <- 1
n_obs <- 10

# -------------------- MA ORDRE 3 --------------------
h3 <- 3
M3 <- numeric(50)
LSC_ma3 <- numeric(50)
LIC_ma3 <- numeric(50)

for (i in 1:50) {
  if (i < h3) {
    M3[i] <- mean(x_ex5[1:i])
    LIC_ma3[i] <- mu_0 - 3 * sigma_0 / sqrt(i * n_obs)
    LSC_ma3[i] <- mu_0 + 3 * sigma_0 / sqrt(i * n_obs)
  } else {
    M3[i] <- mean(x_ex5[(i-h3+1):i])
    LIC_ma3[i] <- mu_0 - 3 * sigma_0 / sqrt(h3 * n_obs)
    LSC_ma3[i] <- mu_0 + 3 * sigma_0 / sqrt(h3 * n_obs)
  }
}

# -------------------- MA ORDRE 4 --------------------
h4 <- 4
M4 <- numeric(50)
LSC_ma4 <- numeric(50)
LIC_ma4 <- numeric(50)

for (i in 1:50) {
  if (i < h4) {
    M4[i] <- mean(x_ex5[1:i])
    LIC_ma4[i] <- mu_0 - 3 * sigma_0 / sqrt(i * n_obs)
    LSC_ma4[i] <- mu_0 + 3 * sigma_0 / sqrt(i * n_obs)
  } else {
    M4[i] <- mean(x_ex5[(i-h4+1):i])
    LIC_ma4[i] <- mu_0 - 3 * sigma_0 / sqrt(h4 * n_obs)
    LSC_ma4[i] <- mu_0 + 3 * sigma_0 / sqrt(h4 * n_obs)
  }
}

# -------------------- MA ORDRE 5 --------------------
h5 <- 5
M5 <- numeric(50)
LSC_ma5 <- numeric(50)
LIC_ma5 <- numeric(50)

for (i in 1:50) {
  if (i < h5) {
    M5[i] <- mean(x_ex5[1:i])
    LIC_ma5[i] <- mu_0 - 3 * sigma_0 / sqrt(i * n_obs)
    LSC_ma5[i] <- mu_0 + 3 * sigma_0 / sqrt(i * n_obs)
  } else {
    M5[i] <- mean(x_ex5[(i-h5+1):i])
    LIC_ma5[i] <- mu_0 - 3 * sigma_0 / sqrt(h5 * n_obs)
    LSC_ma5[i] <- mu_0 + 3 * sigma_0 / sqrt(h5 * n_obs)
  }
}

# -------------------- COMPTAGE POINTS HC --------------------
hors_ma3 <- sum(M3 > LSC_ma3 | M3 < LIC_ma3)
hors_ma4 <- sum(M4 > LSC_ma4 | M4 < LIC_ma4)
hors_ma5 <- sum(M5 > LSC_ma5 | M5 < LIC_ma5)

# Affichage résumé
writeLines(c(
  "",
  "================================================================",
  "     COMPTAGE POINTS HORS CONTROLE (CARTES MA)",
  "================================================================",
  sprintf("MA ordre 3 (h=3) : %d points HC / 50", hors_ma3),
  sprintf("MA ordre 4 (h=4) : %d points HC / 50", hors_ma4),
  sprintf("MA ordre 5 (h=5) : %d points HC / 50", hors_ma5),
  "================================================================",
  ""
))

================================================================
     COMPTAGE POINTS HORS CONTROLE (CARTES MA)
================================================================
MA ordre 3 (h=3) : 1 points HC / 50
MA ordre 4 (h=4) : 1 points HC / 50
MA ordre 5 (h=5) : 1 points HC / 50
================================================================
# Pour compatibilité avec le reste du code
M <- M3
LSC_ma <- LSC_ma3
LIC_ma <- LIC_ma3

Tableau récapitulatif des résultats :

# Sélection d'échantillons représentatifs
echantillons_cles <- c(1, 10, 20, 30, 40, 45, 50)

tableau_ma3 <- data.frame(
  Ech = echantillons_cles,
  LSC = round(LSC_ma[echantillons_cles], 3),
  M = round(M[echantillons_cles], 3),
  LIC = round(LIC_ma[echantillons_cles], 3)
)

kable(tableau_ma3,
      caption = "Résultats MA ordre 3 (échantillons sélectionnés)",
      align = "c",
      col.names = c("Éch.", "LSC", "M", "LIC")) |>
  kable_styling(bootstrap_options = c("striped", "condensed"), 
                full_width = FALSE, font_size = 10)
Résultats MA ordre 3 (échantillons sélectionnés)
Éch. LSC M LIC
1 50.949 50.333 49.051
10 50.548 50.235 49.452
20 50.548 50.231 49.452
30 50.548 50.222 49.452
40 50.548 50.218 49.452
45 50.548 50.461 49.452
50 50.548 50.396 49.452
df_ma <- data.frame(
  echantillon = 1:50,
  moyenne_mobile = M,
  LSC = LSC_ma,
  LIC = LIC_ma,
  hors_limite = ifelse(M > LSC_ma | M < LIC_ma, 
                       "Hors contrôle", "Sous contrôle")
)

ggplot(df_ma, aes(x = echantillon)) +
  # Zone de contrôle avec limites variables
  geom_ribbon(aes(ymin = LIC, ymax = LSC), 
              alpha = 0.2, fill = "lightgreen") +
  geom_line(aes(y = LSC), color = "#D32F2F", 
            linewidth = 0.8, linetype = "dashed") +
  geom_line(aes(y = LIC), color = "#D32F2F", 
            linewidth = 0.8, linetype = "dashed") +
  geom_hline(yintercept = mu_0, color = "#2E7D32", linewidth = 1.2) +
  geom_line(aes(y = moyenne_mobile), color = "#1976D2", linewidth = 1) +
  geom_point(aes(y = moyenne_mobile, color = hors_limite), size = 3) +
  scale_color_manual(values = c("Sous contrôle" = "#1976D2", 
                                 "Hors contrôle" = "#D32F2F")) +
  labs(
    title = "Carte MA (Moyennes Mobiles) - Ordre 3",
    subtitle = "Processus : moyenne = 50, ecart-type = 1, n = 10",
    x = "Numéro d'échantillon",
    y = "Moyenne mobile",
    color = "État"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5),
    panel.grid.minor = element_blank(),
    legend.position = "bottom"
  )
Carte MA ordre 3 - Détection des dérives lentes

Carte MA ordre 3 - Détection des dérives lentes

Avec la moyenne mobile d’ordre 3, on a un point qui sort, donc le processus semble ne pas être sous contrôle.

6.3.4 Comparaison avec ordre 4 et 5

h <- 4
M4 <- numeric(50)
for (i in 1:50) {
  if (i < h) {
    M4[i] <- mean(x_ex5[1:i])
  } else {
    M4[i] <- mean(x_ex5[(i-h+1):i])
  }
}

LIC_ma4 <- numeric(50)
LSC_ma4 <- numeric(50)
for (i in 1:50) {
  if (i < h) {
    LIC_ma4[i] <- mu_0 - 3 * sigma_0 / sqrt(i * n_obs)
    LSC_ma4[i] <- mu_0 + 3 * sigma_0 / sqrt(i * n_obs)
  } else {
    LIC_ma4[i] <- mu_0 - 3 * sigma_0 / sqrt(h * n_obs)
    LSC_ma4[i] <- mu_0 + 3 * sigma_0 / sqrt(h * n_obs)
  }
}

df_ma4 <- data.frame(
  echantillon = 1:50,
  moyenne_mobile = M4,
  LSC = LSC_ma4,
  LIC = LIC_ma4,
  hors_limite = ifelse(M4 > LSC_ma4 | M4 < LIC_ma4, 
                       "Hors contrôle", "Sous contrôle")
)

ggplot(df_ma4, aes(x = echantillon)) +
  geom_ribbon(aes(ymin = LIC, ymax = LSC), 
              alpha = 0.2, fill = "lightgreen") +
  geom_line(aes(y = LSC), color = "#D32F2F", 
            linewidth = 0.8, linetype = "dashed") +
  geom_line(aes(y = LIC), color = "#D32F2F", 
            linewidth = 0.8, linetype = "dashed") +
  geom_hline(yintercept = mu_0, color = "#2E7D32", linewidth = 1.2) +
  geom_line(aes(y = moyenne_mobile), color = "#1976D2", linewidth = 1) +
  geom_point(aes(y = moyenne_mobile, color = hors_limite), size = 3) +
  scale_color_manual(values = c("Sous contrôle" = "#1976D2", 
                                 "Hors contrôle" = "#D32F2F")) +
  labs(
    title = "Carte MA - Ordre 4",
    subtitle = "Lissage plus important, détection de dérive",
    x = "Numéro d'échantillon",
    y = "Moyenne mobile",
    color = "État"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5),
    panel.grid.minor = element_blank(),
    legend.position = "bottom"
  )
Carte MA ordre 4

Carte MA ordre 4

Avec la moyenne mobile d’ordre 4, on a un point qui sort, donc le processus semble ne pas être sous contrôle.

h <- 5
M5 <- numeric(50)
for (i in 1:50) {
  if (i < h) {
    M5[i] <- mean(x_ex5[1:i])
  } else {
    M5[i] <- mean(x_ex5[(i-h+1):i])
  }
}

LIC_ma5 <- numeric(50)
LSC_ma5 <- numeric(50)
for (i in 1:50) {
  if (i < h) {
    LIC_ma5[i] <- mu_0 - 3 * sigma_0 / sqrt(i * n_obs)
    LSC_ma5[i] <- mu_0 + 3 * sigma_0 / sqrt(i * n_obs)
  } else {
    LIC_ma5[i] <- mu_0 - 3 * sigma_0 / sqrt(h * n_obs)
    LSC_ma5[i] <- mu_0 + 3 * sigma_0 / sqrt(h * n_obs)
  }
}

df_ma5 <- data.frame(
  echantillon = 1:50,
  moyenne_mobile = M5,
  LSC = LSC_ma5,
  LIC = LIC_ma5,
  hors_limite = ifelse(M5 > LSC_ma5 | M5 < LIC_ma5, 
                       "Hors contrôle", "Sous contrôle")
)

ggplot(df_ma5, aes(x = echantillon)) +
  geom_ribbon(aes(ymin = LIC, ymax = LSC), 
              alpha = 0.2, fill = "lightgreen") +
  geom_line(aes(y = LSC), color = "#D32F2F", 
            linewidth = 0.8, linetype = "dashed") +
  geom_line(aes(y = LIC), color = "#D32F2F", 
            linewidth = 0.8, linetype = "dashed") +
  geom_hline(yintercept = mu_0, color = "#2E7D32", linewidth = 1.2) +
  geom_line(aes(y = moyenne_mobile), color = "#1976D2", linewidth = 1) +
  geom_point(aes(y = moyenne_mobile, color = hors_limite), size = 3) +
  scale_color_manual(values = c("Sous contrôle" = "#1976D2", 
                                 "Hors contrôle" = "#D32F2F")) +
  labs(
    title = "Carte MA - Ordre 5",
    x = "Numéro d'échantillon",
    y = "Moyenne mobile",
    color = "État"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5),
    panel.grid.minor = element_blank(),
    legend.position = "bottom"
  )
Carte MA ordre 5

Carte MA ordre 5

Résultat : Avec la moyenne mobile d’ordre 5, on observe un point hors contrôle (visible sur le graphique autour de l’échantillon 47), donc le processus n’est pas sous contrôle.

Observation importante : Le fait que même MA ordre 5 (avec le lissage le plus fort) détecte une anomalie confirme la présence d’un déréglage lent significatif dans le processus. On observe une tendance à la hausse progressive, particulièrement marquée dans les derniers échantillons (échantillons 40-50).

# Tableau comparatif des trois ordres MA
comparaison_ma <- data.frame(
  Ordre_h = c(3, 4, 5),
  LSC_final = c(round(LSC_ma3[50], 4), round(LSC_ma4[50], 4), round(LSC_ma5[50], 4)),
  LIC_final = c(round(LIC_ma3[50], 4), round(LIC_ma4[50], 4), round(LIC_ma5[50], 4)),
  Largeur = c(
    round(LSC_ma3[50] - LIC_ma3[50], 4),
    round(LSC_ma4[50] - LIC_ma4[50], 4),
    round(LSC_ma5[50] - LIC_ma5[50], 4)
  ),
  Points_HC = c(hors_ma3, hors_ma4, hors_ma5),
  Conclusion = c(
    ifelse(hors_ma3 == 0, "Sous controle", "Hors controle"),
    ifelse(hors_ma4 == 0, "Sous controle", "Hors controle"),
    ifelse(hors_ma5 == 0, "Sous controle", "Hors controle")
  )
)

kable(comparaison_ma,
      caption = "Comparaison des cartes MA d'ordres 3, 4 et 5",
      align = "c",
      col.names = c("Ordre h", "LSC", "LCI", "Largeur", "Points HC", "Conclusion")) |>
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = TRUE) |>
  column_spec(1, bold = TRUE, background = couleurs$zone_acceptable) |>
  column_spec(6, bold = TRUE,
              color = ifelse(comparaison_ma$Conclusion == "Sous controle", "darkgreen", "darkred"))
Comparaison des cartes MA d’ordres 3, 4 et 5
Ordre h LSC LCI Largeur Points HC Conclusion
3 50.5477 49.4523 1.0954 1 Hors controle
4 50.4743 49.5257 0.9487 1 Hors controle
5 50.4243 49.5757 0.8485 1 Hors controle

6.4 Carte de Contrôle du type EWMA

6.4.1 Théorie (Cours MSP - Chapitre 5)

La carte EWMA (Exponentially Weighted Moving Average) utilise une moyenne mobile à pondération exponentielle qui donne plus de poids aux observations récentes tout en conservant toute l’histoire du processus.

Définition : La statistique EWMA \(Z_i\) est définie récursivement par :

\[Z_i = \lambda \bar{X}_i + (1-\lambda) Z_{i-1} \quad \text{avec } Z_0 = \mu_0\]

où : - \(\lambda \in (0, 1]\) est la constante de lissage - \(\bar{X}_i\) est la moyenne de l’échantillon \(i\) - \(Z_{i-1}\) est la valeur EWMA de l’échantillon précédent

Développement : On peut montrer que :

\[Z_i = \lambda \sum_{j=0}^{i-1} (1-\lambda)^j \bar{X}_{i-j} + (1-\lambda)^i \mu_0\]

Interprétation : Les observations passées ont un poids qui décroît exponentiellement : - Observation actuelle \(\bar{X}_i\) : poids \(\lambda\) - Observation précédente \(\bar{X}_{i-1}\) : poids \(\lambda(1-\lambda)\) - Observation \(\bar{X}_{i-2}\) : poids \(\lambda(1-\lambda)^2\) - etc.

Remarque du cours : - \(\lambda\) proche de 1 (ex: 0.9) → carte réagit rapidement, peu de mémoire (≈ carte \(\bar{X}\) classique) - \(\lambda\) proche de 0 (ex: 0.1) → carte réagit lentement, forte mémoire du passé

Recommandation du cours : Pour détecter les petits déréglages (\(\leq 1.5\sigma\)), utiliser \(\lambda \in [0.1, 0.3]\).

6.4.2 Limites de Contrôle EWMA (Proposition 13 du cours)

Espérance de \(Z_i\) :

D’après le cours, si le processus est sous contrôle :

\[\mathbb{E}[Z_i] = \mu_0\]

Variance de \(Z_i\) :

D’après la Proposition 13 du cours :

\[\text{Var}(Z_i) = \frac{\omega^2 \sigma_0^2}{n} \cdot \frac{1 - (1-\omega)^{2i}}{1 - (1-\omega)^2}\]

En simplifiant \(\frac{1}{1 - (1-\omega)^2} = \frac{1}{2\omega - \omega^2} = \frac{1}{\omega(2-\omega)}\), on obtient :

\[\text{Var}(Z_i) = \frac{\sigma_0^2}{n} \cdot \frac{\omega}{2-\omega} \cdot \left[1 - (1-\omega)^{2i}\right]\]

Limites de contrôle exactes (Proposition 13) :

Selon la règle des \(3\sigma\), les limites de contrôle sont représentées par les fonctions :

\[t \to \mu_0 \pm 3\sigma_0\sqrt{\frac{\omega}{n(2-\omega)} \left[1 - (1-\omega)^{2t}\right]}\]

Pour l’échantillon \(i\), on a donc :

\[\text{LSC}_i = \mu_0 + 3\sigma_0\sqrt{\frac{\omega}{n(2-\omega)} \left[1 - (1-\omega)^{2i}\right]}\]

\[\text{LCI}_i = \mu_0 - 3\sigma_0\sqrt{\frac{\omega}{n(2-\omega)} \left[1 - (1-\omega)^{2i}\right]}\]

Remarque importante : Ces limites convergent lorsque \(i \to \infty\) vers les limites asymptotiques :

\[\text{LSC}_\infty = \mu_0 + 3\sigma_0\sqrt{\frac{\omega}{n(2-\omega)}}\]

\[\text{LCI}_\infty = \mu_0 - 3\sigma_0\sqrt{\frac{\omega}{n(2-\omega)}}\]

car \(\lim_{i \to \infty} (1-\omega)^{2i} = 0\).

Pourquoi utiliser les limites exactes plutôt qu’asymptotiques ?

  1. Précision : Les limites exactes tiennent compte de la convergence progressive de la variance de \(Z_i\)
  2. Premiers échantillons : Pour \(i\) petit, \((1-\omega)^{2i}\) n’est pas négligeable, donc les limites exactes sont plus larges
  3. Conformité au cours : La Proposition 13 définit les limites comme des fonctions de \(t\), pas comme des constantes
  4. Représentation graphique : Sur la carte EWMA, on observe des limites qui se resserrent progressivement jusqu’à converger

6.4.3 Application : EWMA avec \(\omega = 0.2\)

Note sur la notation : Dans le cours, le paramètre est noté \(\omega\) (oméga). Ici, nous utilisons \(\lambda = \omega = 0.2\).

# Paramètre de lissage (ω dans le cours, λ en pratique)
# Recommandé pour petits déréglages : ω ∈ [0.1, 0.3]
lambda <- 0.2  # Équivaut à ω = 0.2 dans le cours


# CALCUL DE LA STATISTIQUE EWMA (Définition 12 du cours)

# Relation de récurrence : Z_i = ω·X̄_i + (1-ω)·Z_{i-1}
# avec Z_0 = μ_0

Z <- numeric(50)
Z[1] <- mu_0  # Initialisation à la cible (Z_0 = μ_0)

for (i in 2:50) {
  Z[i] <- lambda * x_ex5[i] + (1 - lambda) * Z[i-1]
}


# CALCUL DES LIMITES DE CONTRÔLE (Proposition 13 du cours)


# Limites ASYMPTOTIQUES (pour i → ∞)
# LSC_∞ = μ_0 + 3σ_0√[ω / (n(2-ω))]
sigma_ewma_asymptotique <- sigma_0 * sqrt(lambda / (n_obs * (2 - lambda)))
LSC_ewma_asymptotique <- mu_0 + 3 * sigma_ewma_asymptotique
LIC_ewma_asymptotique <- mu_0 - 3 * sigma_ewma_asymptotique

# Limites EXACTES (Proposition 13 : fonctions de t)
# LSC_i = μ_0 + 3σ_0√[ω/(n(2-ω)) · (1-(1-ω)^{2i})]
# 
# IMPORTANT : On utilise les limites EXACTES car :
# 1. Conformité au cours (Proposition 13 définit des FONCTIONS de t)
# 2. Pour les premiers échantillons, (1-ω)^{2i} n'est pas négligeable
# 3. Les limites convergent progressivement vers les limites asymptotiques
# 4. Plus précis pour la détection sur tous les échantillons

LSC_ewma_exact <- numeric(50)
LIC_ewma_exact <- numeric(50)

for (i in 1:50) {
  # Facteur de correction temporel : 1 - (1-ω)^{2i}
  facteur_temps <- 1 - (1 - lambda)^(2*i)
  
  # Écart-type de Z_i (Proposition 13)
  sigma_i <- sigma_0 * sqrt((lambda / (n_obs * (2 - lambda))) * facteur_temps)
  
  # Limites exactes pour l'échantillon i
  LSC_ewma_exact[i] <- mu_0 + 3 * sigma_i
  LIC_ewma_exact[i] <- mu_0 - 3 * sigma_i
}

# Affichage des limites
writeLines(c(
  "",
  "================================================================",
  sprintf("  LIMITES DE CONTROLE EWMA (omega = %.1f)", lambda),
  "================================================================",
  "",
  "LIMITES ASYMPTOTIQUES (i -> infini) :",
  sprintf("  LSC_∞ = %.4f", LSC_ewma_asymptotique),
  sprintf("  LC    = %.4f", mu_0),
  sprintf("  LCI_∞ = %.4f", LIC_ewma_asymptotique),
  sprintf("  Largeur asymptotique : %.4f", LSC_ewma_asymptotique - LIC_ewma_asymptotique),
  "",
  "LIMITES EXACTES (Proposition 13 du cours) :",
  sprintf("  LSC_1  = %.4f  (échantillon 1)", LSC_ewma_exact[1]),
  sprintf("  LSC_10 = %.4f  (échantillon 10)", LSC_ewma_exact[10]),
  sprintf("  LSC_50 = %.4f  (échantillon 50)", LSC_ewma_exact[50]),
  sprintf("  → Convergence vers LSC_∞ = %.4f", LSC_ewma_asymptotique),
  "",
  sprintf("Écart entre LSC_50 et LSC_∞ : %.6f", abs(LSC_ewma_exact[50] - LSC_ewma_asymptotique)),
  "================================================================",
  ""
))

================================================================
  LIMITES DE CONTROLE EWMA (omega = 0.2)
================================================================

LIMITES ASYMPTOTIQUES (i -> infini) :
  LSC_∞ = 50.3162
  LC    = 50.0000
  LCI_∞ = 49.6838
  Largeur asymptotique : 0.6325

LIMITES EXACTES (Proposition 13 du cours) :
  LSC_1  = 50.1897  (échantillon 1)
  LSC_10 = 50.3144  (échantillon 10)
  LSC_50 = 50.3162  (échantillon 50)
  → Convergence vers LSC_∞ = 50.3162

Écart entre LSC_50 et LSC_∞ : 0.000000
================================================================

Tableau récapitulatif EWMA :

tableau_ewma <- data.frame(
  Echantillon = echantillons_cles,
  LSC = round(LSC_ewma_exact[echantillons_cles], 5),
  Z = round(Z[echantillons_cles], 5),
  LIC = round(LIC_ewma_exact[echantillons_cles], 5),
  Etat = ifelse(Z[echantillons_cles] > LSC_ewma_exact[echantillons_cles] | 
                Z[echantillons_cles] < LIC_ewma_exact[echantillons_cles], 
                "Hors controle", "Sous controle")
)

kable(tableau_ewma,
      caption = "Resultats EWMA (lambda = 0.2) pour echantillons selectionnes",
      align = "c",
      col.names = c("Echantillon", "LSC", "Z (Statistique EWMA)", "LIC", "Etat")) |>
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), 
                full_width = TRUE) |>
  column_spec(5, bold = TRUE, 
              color = ifelse(tableau_ewma$Etat == "Sous controle", "darkgreen", "darkred"))
Resultats EWMA (lambda = 0.2) pour echantillons selectionnes
Echantillon LSC Z (Statistique EWMA) LIC Etat
1 50.18974 50.00000 49.81026 Sous controle
10 50.31440 50.13906 49.68560 Sous controle
20 50.31621 50.17101 49.68379 Sous controle
30 50.31623 50.18417 49.68377 Sous controle
40 50.31623 50.24387 49.68377 Sous controle
45 50.31623 50.30441 49.68377 Sous controle
50 50.31623 50.34323 49.68377 Hors controle
df_ewma <- data.frame(
  echantillon = 1:50,
  Z = Z,
  LSC = LSC_ewma_exact,
  LIC = LIC_ewma_exact,
  hors_limite = ifelse(Z > LSC_ewma_exact | Z < LIC_ewma_exact, 
                       "Hors controle", "Sous controle")
)

ggplot(df_ewma, aes(x = echantillon)) +
  geom_ribbon(aes(ymin = LIC, ymax = LSC), 
              alpha = 0.25, fill = couleurs$zone_surveillance) +
  geom_line(aes(y = LSC), color = couleurs$rouge_principal, 
            linewidth = 0.8, linetype = "dashed") +
  geom_line(aes(y = LIC), color = couleurs$rouge_principal, 
            linewidth = 0.8, linetype = "dashed") +
  geom_hline(yintercept = mu_0, color = couleurs$vert_principal, linewidth = 1.2) +
  geom_line(aes(y = Z), color = couleurs$orange_principal, linewidth = 1.1) +
  geom_point(aes(y = Z, color = hors_limite), size = 3) +
  scale_color_manual(values = c("Sous controle" = couleurs$sous_controle, 
                                 "Hors controle" = couleurs$hors_controle)) +
  labs(
    title = "Carte EWMA (Exponentially Weighted Moving Average)",
    subtitle = expression(paste(mu[0], " = 50, ", sigma[0], " = 1, n = 10, ", lambda, " = 0.2")),
    x = "Numero d'echantillon",
    y = "Statistique EWMA (Z)",
    color = "Etat"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
    plot.subtitle = element_text(size = 10, hjust = 0.5),
    panel.grid.minor = element_blank(),
    legend.position = "bottom"
  )
Carte EWMA - Detection optimale des petits dereglages

Carte EWMA - Detection optimale des petits dereglages

Résultat EWMA :

hors_ewma <- sum(Z > LSC_ewma_exact | Z < LIC_ewma_exact)

writeLines(c(
  "",
  "================================================================",
  "           RESULTAT CARTE EWMA",
  "================================================================",
  sprintf("Points hors controle : %d / 50", hors_ewma),
  sprintf("Taux de conformite   : %.1f%%", 100*(1 - hors_ewma/50)),
  "",
  ifelse(hors_ewma == 0, 
         "-> Processus SOUS CONTROLE",
         "-> Processus HORS CONTROLE"),
  "================================================================",
  ""
))

================================================================
           RESULTAT CARTE EWMA
================================================================
Points hors controle : 3 / 50
Taux de conformite   : 94.0%

-> Processus HORS CONTROLE
================================================================

6.5 Synthèse Comparative : MA vs EWMA

6.5.1 Tableau Comparatif Global

# hors_ma3, hors_ma4, hors_ma5 sont déjà calculés
# On calcule seulement hors_ewma (déjà fait ci-dessus)

synthese_complete <- data.frame(
  Methode = c("Carte X-bar classique", "MA (h=3)", "MA (h=4)", "MA (h=5)", "EWMA (omega=0.2)"),
  Type = c("Shewhart", "A memoire", "A memoire", "A memoire", "A memoire"),
  Largeur_zone = c(
    round(2*0.949, 4),
    round(LSC_ma3[50] - LIC_ma3[50], 4),
    round(LSC_ma4[50] - LIC_ma4[50], 4),
    round(LSC_ma5[50] - LIC_ma5[50], 4),
    round(LSC_ewma_asymptotique - LIC_ewma_asymptotique, 4)  # Largeur asymptotique
  ),
  Points_HC = c("N/A", hors_ma3, hors_ma4, hors_ma5, hors_ewma),
  Sensibilite = c("Faible", "Elevee", "Moyenne", "Faible", "Tres elevee"),
  Conclusion = c(
    "Inadaptee",
    ifelse(hors_ma3 == 0, "Sous controle", "Hors controle"),
    ifelse(hors_ma4 == 0, "Sous controle", "Hors controle"),
    ifelse(hors_ma5 == 0, "Sous controle", "Hors controle"),
    ifelse(hors_ewma == 0, "Sous controle", "Hors controle")
  )
)

kable(synthese_complete,
      caption = "Synthese comparative de toutes les methodes (Exemple 5)",
      align = "c",
      col.names = c("Methode", "Type", "Largeur zone", "Points HC", "Sensibilite", "Conclusion")) |>
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = TRUE) |>
  column_spec(1, bold = TRUE) |>
  column_spec(6, bold = TRUE,
              color = c("gray", 
                       ifelse(synthese_complete$Conclusion[2] == "Sous controle", "darkgreen", "darkred"),
                       ifelse(synthese_complete$Conclusion[3] == "Sous controle", "darkgreen", "darkred"),
                       ifelse(synthese_complete$Conclusion[4] == "Sous controle", "darkgreen", "darkred"),
                       ifelse(synthese_complete$Conclusion[5] == "Sous controle", "darkgreen", "darkred"))) |>
  row_spec(1, background = "#FFEBEE")
Synthese comparative de toutes les methodes (Exemple 5)
Methode Type Largeur zone Points HC Sensibilite Conclusion
Carte X-bar classique Shewhart 1.8980 N/A Faible Inadaptee
MA (h=3) A memoire 1.0954 1 Elevee Hors controle
MA (h=4) A memoire 0.9487 1 Moyenne Hors controle
MA (h=5) A memoire 0.8485 1 Faible Hors controle
EWMA (omega=0.2) A memoire 0.6325 3 Tres elevee Hors controle

6.5.2 Avantages et Inconvénients

Carte MA (Moving Average) :

Avantages : - Calcul simple et intuitif (moyenne arithmétique) - Facile à expliquer aux opérateurs - Limites en créneaux visualisent bien la convergence

Inconvénients : - Mémoire limitée à \(h\) échantillons (oublie le passé lointain) - Pondération uniforme (pas de distinction ancien/récent) - Choix de \(h\) empirique

Carte EWMA (Exponentially Weighted Moving Average) :

Avantages : - Mémoire infinie avec pondération décroissante - Performance optimale théoriquement établie - Valeurs de \(\lambda\) recommandées - Convergence progressive des limites

Inconvénients : - ️ Moins intuitive (récursion, pondération exponentielle) - Plus difficile à calculer manuellement - Nécessite de stocker \(Z_{i-1}\)

6.5.3 Recommandations Selon le Contexte

D’après le Chapitre 5 du cours :

Pour déréglages très lents (dérive progressive) : → EWMA avec \(\lambda = 0.1\) ou \(\lambda = 0.15\)

Pour déréglages moyennement lents : → EWMA avec \(\lambda = 0.2\) ou MA avec \(h = 4\)

Pour contexte industriel : → EWMA (performance optimale, norme ISO)

6.5.4 Conclusion

6.5.5 Conclusion de l’Exemple 5

6.5.5.1 Réponse à la Question Initiale

Question : Le procédé est-il sous contrôle en moyenne sachant qu’un déréglage lent est suspecté ?

Réponse :

  1. La carte \(\bar{X}\) classique est inadaptée car elle ne détecte pas les dérives lentes (limites trop larges, pas de mémoire)

  2. Toutes les cartes à mémoire détectent une anomalie :

    • MA ordre 3 : 1 point hors contrôle → Processus hors contrôle
    • MA ordre 4 : 1 point hors contrôle → Processus hors contrôle
    • MA ordre 5 : 1 point hors contrôle → Processus hors contrôle
    • EWMA (\(\lambda=0.2\)) : résultat affiché ci-dessus
  3. Le choix du paramètre est crucial :

    • MA ordres 3, 4 et 5 détectent tous l’anomalie, mais avec des sensibilités différentes
    • Le fait que même \(h=5\) (lissage maximal) détecte le déréglage confirme qu’il est significatif
    • Pour EWMA : \(\lambda = 0.2\) est optimal pour détecter des déréglages \(\leq 1.5\sigma\)
  4. Interprétation des résultats :

    • Le processus présente une dérive progressive visible surtout dans les échantillons 40-50
    • Même avec un lissage fort (h=5), la tendance à la hausse est statistiquement significative
    • Cela confirme la suspicion initiale d’un déréglage lent mais continu
    • L’EWMA offre un compromis optimal avec mémoire infinie et pondération décroissante

Conclusion finale : Le processus présente une anomalie détectée par toutes les cartes à mémoire (MA ordres 3, 4, 5 et EWMA). Cette détection unanime confirme sans ambiguïté la présence d’un déréglage lent significatif.

Action recommandée : - Identifier la cause assignable (usure d’outil, dérive température, etc.) - Corriger le processus - Surveiller avec carte EWMA \(\lambda = 0.2\) en continu (recommandation industrie)

Cette analyse démontre l’importance capitale du choix de la carte adaptée au type de déréglage suspecté, conformément aux enseignements du Chapitre 5 du cours.

7 Synthèse et Conclusion

7.1 Tableau Récapitulatif des Cartes

recap <- data.frame(
  Carte = c("X barre", "S", "R", "c", "MA", "EWMA"),
  Objectif = c(
    "Surveiller moyenne",
    "Surveiller ecart-type",
    "Surveiller etendue",
    "Compter defauts",
    "Detecter derives",
    "Detecter petits dereglages"
  ),
  Phase = c("I et II", "I et II", "I", "II", "II", "II"),
  Sensibilite = c("Moyenne", "Moyenne", "Moyenne", "Faible", "Moyenne-Elevee", "Tres elevee")
)

kable(recap, 
      caption = "Synthese des cartes de controle",
      align = "c",
      col.names = c("Carte", "Objectif", "Phase", "Sensibilite")) |>
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE) |>
  column_spec(1, bold = TRUE) |>
  row_spec(6, background = "#E3F2FD")  # Highlighter EWMA
Synthese des cartes de controle
Carte Objectif Phase Sensibilite
X barre Surveiller moyenne I et II Moyenne
S Surveiller ecart-type I et II Moyenne
R Surveiller etendue I Moyenne
c Compter defauts II Faible
MA Detecter derives II Moyenne-Elevee
EWMA Detecter petits dereglages II Tres elevee

7.2 Bilan des Exemples Traités

Au cours de ce projet, nous avons exploré cinq exemples illustrant différentes facettes des cartes de contrôle :

Exemple 1 : Carte classique (\(\bar{X}\), \(S\)) en Phase II. Le processus est centré correctement mais présente une variabilité interne anormale (un point hors contrôle sur la carte \(S\)).

Exemple 2 : Analyse de valeurs aberrantes avec trois méthodes du cours (boîte de dispersion, test de Shapiro-Wilk, règle des 3σ). Détection d’une alarme défectueuse (17 secondes) identifiée comme valeur atypique, confirmant l’opinion du responsable sur un processus hors contrôle. Quatre critères indépendants valident cette conclusion.

Exemple 3 : Estimation des paramètres en Phase I avec cartes (\(\bar{X}\), \(R\)). Établissement des limites de référence pour un processus sous contrôle statistique.

Exemple 4 : Carte aux attributs (\(c\)) avec limites probabilistes adaptées au risque accepté (\(\alpha = 10\%\)). Deux points hors contrôle détectés.

Exemple 5 : Cartes MA et EWMA révélant l’importance du choix de l’ordre de la moyenne mobile et du paramètre de lissage pour la détection des déréglages lents.

Ces exemples démontrent la complémentarité des outils et l’importance de choisir la carte adaptée au contexte.

7.3 Recommandations Pratiques

Pour une mise en œuvre réussie de la MSP :

  1. Former les opérateurs : Compréhension des principes, pas seulement application mécanique
  2. Définir des procédures claires : Que faire quand un point sort ?
  3. Documenter les interventions : Traçabilité des causes et actions
  4. Réviser périodiquement : Les limites peuvent devenir obsolètes si le processus évolue
  5. Combiner avec d’autres outils : Ishikawa, Pareto, AMDEC pour l’analyse des causes( que j’utilise actuellement dans le cadre de mon alternance)

8 Annexes

8.1 Annexe : Tables de Constantes

constantes <- data.frame(
  n = c(2, 3, 4, 5, 6, 7, 8, 9, 10,
        11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
        21, 22, 23, 24, 25, 30, 35, 40, 45, 50),
  d2 = c(1.128, 1.693, 2.059, 2.326, 2.534, 2.704, 2.847, 2.970, 3.078,
         3.173, 3.258, 3.336, 3.407, 3.472, 3.532, 3.588, 3.640, 3.689, 3.735,
         3.778, 3.819, 3.858, 3.895, 3.931, 4.086, 4.213, 4.322, 4.415, 4.498),
  d3 = c(0.853, 0.888, 0.880, 0.864, 0.848, 0.833, 0.820, 0.808, 0.797,
         0.787, 0.778, 0.770, 0.763, 0.756, 0.750, 0.744, 0.739, 0.734, 0.729,
         0.724, 0.720, 0.716, 0.712, 0.708, 0.693, 0.680, 0.670, 0.660, 0.652),
  c4 = c(0.798, 0.886, 0.921, 0.940, 0.952, 0.959, 0.965, 0.969, 0.973,
         0.975, 0.978, 0.979, 0.981, 0.982, 0.984, 0.985, 0.986, 0.987, 0.988,
         0.988, 0.989, 0.990, 0.990, 0.991, 0.993, 0.994, 0.995, 0.996, 0.996)
)

kable(constantes,
      caption = "Constantes pour cartes de contrôle (n = 2 à 50)",
      col.names = c("n", "d2", "d3", "c4"),
      align = "c") |>
  kable_styling(bootstrap_options = c("striped"), 
                full_width = FALSE, font_size = 10)
Constantes pour cartes de contrôle (n = 2 à 50)
n d2 d3 c4
2 1.128 0.853 0.798
3 1.693 0.888 0.886
4 2.059 0.880 0.921
5 2.326 0.864 0.940
6 2.534 0.848 0.952
7 2.704 0.833 0.959
8 2.847 0.820 0.965
9 2.970 0.808 0.969
10 3.078 0.797 0.973
11 3.173 0.787 0.975
12 3.258 0.778 0.978
13 3.336 0.770 0.979
14 3.407 0.763 0.981
15 3.472 0.756 0.982
16 3.532 0.750 0.984
17 3.588 0.744 0.985
18 3.640 0.739 0.986
19 3.689 0.734 0.987
20 3.735 0.729 0.988
21 3.778 0.724 0.988
22 3.819 0.720 0.989
23 3.858 0.716 0.990
24 3.895 0.712 0.990
25 3.931 0.708 0.991
30 4.086 0.693 0.993
35 4.213 0.680 0.994
40 4.322 0.670 0.995
45 4.415 0.660 0.996
50 4.498 0.652 0.996