Le Jeu du Six Sigma: le jeu de fléchettes
Ce fichier vise à utiliser des outils clés pour analyser et améliorer la performance des lancers de fléchettes dans un jeu pédagogique inspiré de la méthode Six Sigma. Les outils suivants sont mis en œuvre :
En simplifiant ces concepts, on peut mieux apprendre à résoudre des problèmes concrets et à améliorer les performances de manière structurée.
Le plan d’expériences (PlanEx) est utilisé pour comprendre comment les facteurs influencent la réponse YYY (performance). Dans ce projet, la taille du joueur est considérée comme un facteur non contrôlable, et au moins deux variables contrôlables parmi les suivantes sont étudiées :
Distance (m) : 3, 5, 7 mètres
Poids des fléchettes (g) : Le poids des fléchettes suit une distribution normale, définie mathématiquement comme suit :
\[\text{Poids des fléchettes} \sim \mathcal{N}(\mu = 50, \sigma =5)\]
Vent : Faible, Moyen, Fort
Éclairage : 50%, 75%, 100%
Étudier l’effet combiné de la taille du joueur et des deux variables contrôlables choisies.
Identifier les niveaux de facteurs qui maximisent ou stabilisent la réponse Y.
Quantifier les interactions entre ces facteurs.
Un plan factoriel complet est utilisé pour tester toutes les combinaisons possibles des niveaux des facteurs sélectionnés. Chaque combinaison est répétée 3 fois pour garantir une robustesse statistique.
Voici un exemple de conception avec Distance et Vent comme facteurs contrôlables :
\[ \text{Combinaisons} = \text{Taille du joueur} \times \text{Distance} \times \text{Vent} \]
# Chargement des bibliothèques nécessaires
library(dplyr)
##
## Anexando pacote: 'dplyr'
## Os seguintes objetos são mascarados por 'package:stats':
##
## filter, lag
## Os seguintes objetos são mascarados por 'package:base':
##
## intersect, setdiff, setequal, union
# Création des niveaux pour chaque facteur
taille <- c("Faible", "Moyen", "Élevé") # Taille du joueur (non contrôlable)
distance <- c(3, 5, 7) # Distance (mètres)
vent <- c("Faible", "Moyen", "Fort") # Vent
eclairage <- c("50%", "75%", "100%") # Éclairage
set.seed(42) # Fixer la graine pour reproduire les résultats
poids_des_flechettes <- round(rnorm(9, mean = 50, sd = 5), 2) # Poids aléatoires autour de 50 g
# Liste des variables disponibles pour le plan expérimental
variables_disponibles <- list(
Distance_m = distance,
Vent = vent,
Éclairage = eclairage,
Taille_du_joueur = taille
)
# Sélection manuelle des variables à inclure dans le plan expérimental
variables_choisies <- list(
Distance_m = distance, # Inclure la Distance
Vent = vent # Inclure le Vent
# Taille_du_joueur = taille, # Supprimez le # pour inclure
# Éclairage = eclairage # Supprimez le # pour inclure
)
# Générer toutes les combinaisons possibles avec 'Poids des fléchettes' aléatoires inclus
plan_experiment <- expand.grid(
Poids_des_fléchettes_g = poids_des_flechettes # Toujours inclus
)
# Ajouter dynamiquement les variables choisies
for (variable in names(variables_choisies)) {
new_combinations <- expand.grid(
Variable = variables_choisies[[variable]]
)
colnames(new_combinations)[1] <- variable # Renommer la colonne
plan_experiment <- merge(plan_experiment, new_combinations, all = TRUE)
}
# Affichage des 10 premières combinaisons
head(plan_experiment, 10)
## Poids_des_fléchettes_g Distance_m Vent
## 1 56.85 3 Faible
## 2 47.18 3 Faible
## 3 51.82 3 Faible
## 4 53.16 3 Faible
## 5 52.02 3 Faible
## 6 49.47 3 Faible
## 7 57.56 3 Faible
## 8 49.53 3 Faible
## 9 60.09 3 Faible
## 10 56.85 5 Faible
L’objectif de cette analyse est de mesurer la variabilité des performances observées en fonction des facteurs étudiés, tout en distinguant les sources de variabilité entre la répétabilité (intra-joueur) et la reproductibilité (inter-joueur).
# Chargement des bibliothèques nécessaires
library(readxl)
library(curl)
## Using libcurl 8.10.1 with Schannel
# Lien direct pour le téléchargement
file_path <- "C:/Users/Cliente/OneDrive/Desktop/Matheus/UTT/2024-2/GP28/Projet_GP28_rempli.xlsx"
# Lecture du fichier Excel
data <- as.data.frame(read_excel(file_path, sheet = "Donnees"))
# Renommer les colonnes
colnames(data) <- c("Ronde", "Joueur", "Distance_m", "Taille_du_joueur", "Poids_des_fléchettes_g", "Vent", "Éclairage", "Score", "Quadrant", "Bonus_de_précision", "Score_Total")
# Affichage des premières lignes des données
head(data)
## Ronde Joueur Distance_m Taille_du_joueur Poids_des_fléchettes_g Vent
## 1 1 Joueur 1 3 Moyen 44.81783 Fort
## 2 1 Joueur 1 5 Moyen 46.38760 Faible
## 3 1 Joueur 1 7 Moyen 47.08579 Moyenne
## 4 1 Joueur 2 3 Élevé 45.51763 Moyenne
## 5 1 Joueur 2 5 Élevé 46.62755 Fort
## 6 1 Joueur 2 7 Élevé 47.01120 Faible
## Éclairage Score Quadrant Bonus_de_précision Score_Total
## 1 100% 6 1 0 6
## 2 50% 8 1 5 13
## 3 75% 9 8 7 16
## 4 75% 5 3 0 5
## 5 100% 10 8 0 10
## 6 50% 9 2 2 11
<br>
Dans le cadre de ce projet, la génération de nouvelles données corrélées est essentielle pour :
Compléter les données existantes : Lorsque les données originales sont insuffisantes pour une analyse complète ou présentent des lacunes (valeurs manquantes, faible variabilité), la génération de données corrélées permet d’élargir l’ensemble tout en conservant les propriétés statistiques des données réelles.
Préserver la cohérence statistique : Les nouvelles données sont créées en suivant les distributions observées dans les données originales, garantissant que les caractéristiques et les relations entre les variables sont respectées.
Simuler différents scénarios expérimentaux : En élargissant les combinaisons possibles des facteurs étudiés, il devient possible d’explorer des conditions qui n’ont pas été directement observées dans les données originales.
Renforcer l’analyse R&R : Avec un ensemble de données plus robuste et varié, la répétabilité et la reproductibilité peuvent être évaluées de manière plus précise, garantissant des résultats statistiquement significatifs.
En résumé, cette approche permet de compléter et enrichir l’analyse tout en préservant la fiabilité des conclusions tirées du projet.
library(dplyr)
# Paramètres pour forcer une variabilité suffisante
set.seed(123)
# Obtenir les statistiques des données originales
mean_score <- mean(data$Score_Total, na.rm = TRUE)
sd_score <- max(sd(data$Score_Total, na.rm = TRUE), 5)
mean_poids <- mean(data$Poids_des_fléchettes_g, na.rm = TRUE)
sd_poids <- max(sd(data$Poids_des_fléchettes_g, na.rm = TRUE), 2)
# Génération de nouvelles données avec plus de diversité
generated_data <- expand.grid(
Joueur = unique(data$Joueur), # Tous les joueurs
Distance_m = unique(data$Distance_m), # Toutes les distances
Taille_du_joueur = unique(data$Taille_du_joueur), # Toutes les tailles
Vent = unique(data$Vent), # Toutes les catégories de vent
Éclairage = unique(data$Éclairage), # Toutes les catégories d'éclairage
Poids_des_fléchettes_g = round( # Variabilité forcée pour le poids
rnorm(500, mean = mean_poids, sd = sd_poids), 2
)
) %>%
mutate(
Score_Total = round( # Variabilité forcée pour le score
rnorm(n(), mean = mean_score, sd = sd_score), 2
),
Répétition = sample(1:3, n(), replace = TRUE) # Répétitions aléatoires
) %>%
filter(Poids_des_fléchettes_g > 0 & Score_Total > 0) # Supprimer les valeurs négatives
# Vérifier que les données générées sont suffisantes
if (var(generated_data$Score_Total, na.rm = TRUE) == 0) {
stop("La variabilité dans Score_Total est insuffisante. Des données supplémentaires sont nécessaires.")
}
# Affichage des premières lignes des données générées
head(generated_data)
## Joueur Distance_m Taille_du_joueur Vent Éclairage Poids_des_fléchettes_g
## 1 Joueur 1 3 Moyen Fort 100% 48.57
## 2 Joueur 2 3 Moyen Fort 100% 48.57
## 3 Joueur 3 3 Moyen Fort 100% 48.57
## 4 Joueur 4 3 Moyen Fort 100% 48.57
## 5 Joueur 5 3 Moyen Fort 100% 48.57
## 6 Joueur 1 5 Moyen Fort 100% 48.57
## Score_Total Répétition
## 1 5.32 1
## 2 3.36 3
## 3 13.47 2
## 4 12.09 3
## 5 0.79 3
## 6 7.86 3
library(dplyr)
library(knitr)
library(kableExtra)
##
## Anexando pacote: 'kableExtra'
## O seguinte objeto é mascarado por 'package:dplyr':
##
## group_rows
# Préparer les données pour l'analyse R&R
rr_data <- generated_data %>%
select(Joueur, Distance_m, Taille_du_joueur, Poids_des_fléchettes_g, Score_Total) %>%
arrange(Joueur, Distance_m)
# Vérifier la variabilité dans Score_Total
if (var(rr_data$Score_Total, na.rm = TRUE) == 0) {
stop("La variabilité dans Score_Total est nulle. Veuillez vérifier les données.")
}
# Analyser les moyennes et écarts-types par joueur et combinaison
rr_results <- rr_data %>%
group_by(Joueur, Distance_m, Poids_des_fléchettes_g) %>%
summarise(
Mean_Score = mean(Score_Total, na.rm = TRUE),
SD_Score = ifelse(n() > 1, sd(Score_Total, na.rm = TRUE), NA_real_),
.groups = "drop"
)
# Filtrer les groupes avec des valeurs invalides
rr_results <- rr_results %>%
filter(!is.na(SD_Score))
# Calculer la variabilité totale
total_variance <- var(rr_data$Score_Total, na.rm = TRUE)
if (total_variance == 0) {
stop("La variance totale est nulle. Les données ne permettent pas une analyse R&R significative.")
}
# Calculer la variabilité intra-joueur (répétabilité)
repeatability_variance <- rr_results %>%
summarise(Variance = mean(SD_Score^2, na.rm = TRUE)) %>%
pull(Variance)
# Vérifier que repeatability_variance est valide
if (is.na(repeatability_variance) || repeatability_variance > total_variance) {
stop("La variance de répétabilité est invalide. Veuillez vérifier les données.")
}
# Calculer la variabilité inter-joueur (reproductibilité)
reproducibility_variance <- total_variance - repeatability_variance
# Calcul des pourcentages
percent_repeatability <- (repeatability_variance / total_variance) * 100
percent_reproducibility <- (reproducibility_variance / total_variance) * 100
# Résumé des Variabilités
rr_summary <- tibble(
"Source de Variabilité" = c("Répétabilité", "Reproductibilité"),
"Variance (%)" = c(percent_repeatability, percent_reproducibility)
)
# Exibir o resumo em formato de tabela para Markdown
rr_summary %>%
kable(format = "markdown", align = "c", caption = "Résumé des Variabilités") %>%
kable_styling(full_width = FALSE)
| Source de Variabilité | Variance (%) |
|---|---|
| Répétabilité | 99.8283525 |
| Reproductibilité | 0.1716475 |
L’ANOVA (Analyse de Variance) est une méthode statistique qui permet de comparer les moyennes de plusieurs groupes et d’évaluer si les différences observées entre ces groupes sont statistiquement significatives. Dans le cadre de ce projet, elle est utilisée pour :
Identifier les facteurs influents :
Analyser les interactions entre facteurs :
Optimiser les performances :
L’ANOVA est essentielle dans le cadre d’expériences comme celles-ci pour transformer les observations en informations exploitables.
# Charger les bibliothèques nécessaires
library(dplyr)
# Variables disponibles
variables_disponibles <- list(
Poids_des_fléchettes_g = "Poids_des_fléchettes_g", # Toujours inclus
Distance_m = "Distance_m",
Eclairage = "Éclairage",
Taille_du_joueur = "Taille_du_joueur",
Vent = "Vent"
)
# Choisir les variables à inclure dans l'ANOVA
variables_choisies <- list(
Poids_des_fléchettes_g = "Poids_des_fléchettes_g", # Toujours inclus
Distance_m = "Distance_m", # Supprimez le # pour inclure
#Eclairage = "Éclairage", # Ajoutez le # pour exclure
#Taille_du_joueur = "Taille_du_joueur", # Ajoutez le # pour exclure
Vent = "Vent" # Supprimez le # pour inclure
)
# Fonction pour exécuter l'ANOVA avec les facteurs choisis
realiser_anova <- function(data, facteurs) {
# Construire dynamiquement la formule
formule <- as.formula(
paste("Score_Total ~", paste(facteurs, collapse = " * "))
)
# Ajuster le modèle ANOVA
modele_anova <- aov(formule, data = data)
# Résumé du modèle
print(summary(modele_anova))
# Extraire les coefficients
coeficients <- coef(modele_anova)
# Construire l'équation
equa <- paste("Score_Total = ", round(coeficients[1], 2))
for (i in 2:length(coeficients)) {
equa <- paste(
equa, "+", round(coeficients[i], 2), "*", names(coeficients)[i]
)
}
# Afficher l'équation
cat("\nÉquation du modèle ANOVA :", equa, "\n")
}
# Construire dynamiquement les combinaisons des facteurs sélectionnés
facteurs_inclus <- unlist(variables_choisies)
if (length(facteurs_inclus) < 2) {
stop("Au moins deux facteurs doivent être inclus pour exécuter l'ANOVA.")
}
# Appliquer l'ANOVA pour les facteurs choisis
cat("\n--- Modèle ANOVA pour les facteurs :", paste(facteurs_inclus, collapse = ", "), "---\n")
##
## --- Modèle ANOVA pour les facteurs : Poids_des_fléchettes_g, Distance_m, Vent ---
realiser_anova(data = generated_data, facteurs = facteurs_inclus)
## Df Sum Sq Mean Sq F value Pr(>F)
## Poids_des_fléchettes_g 1 10 9.69 0.475 0.4908
## Distance_m 1 1 1.13 0.055 0.8140
## Vent 2 81 40.30 1.975 0.1387
## Poids_des_fléchettes_g:Distance_m 1 1 1.40 0.068 0.7936
## Poids_des_fléchettes_g:Vent 2 104 51.92 2.545 0.0785 .
## Distance_m:Vent 2 13 6.71 0.329 0.7196
## Poids_des_fléchettes_g:Distance_m:Vent 2 29 14.47 0.709 0.4920
## Residuals 192735 3932179 20.40
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Équation du modèle ANOVA : Score_Total = 9.19 + -0.01 * Poids_des_fléchettes_g + 0.07 * Distance_m + 0.62 * VentFaible + -1.64 * VentMoyenne + 0 * Poids_des_fléchettes_g:Distance_m + -0.01 * Poids_des_fléchettes_g:VentFaible + 0.03 * Poids_des_fléchettes_g:VentMoyenne + -0.23 * Distance_m:VentFaible + 0.11 * Distance_m:VentMoyenne + 0 * Poids_des_fléchettes_g:Distance_m:VentFaible + 0 * Poids_des_fléchettes_g:Distance_m:VentMoyenne
Les graphiques de contrôle sont des outils essentiels dans le contrôle statistique des processus (SPC). Ils permettent de surveiller la stabilité d’un processus au fil du temps, en identifiant les variations normales (à l’intérieur des limites de contrôle) et anormales (à l’extérieur des limites de contrôle). Dans le cadre de ce projet, un graphique de contrôle X-bar est utilisé pour évaluer la moyenne du Score_Total lors des différentes répétitions.
Identifier les variations anormales dans le processus : Détecter les points qui se situent en dehors des limites de contrôle supérieure (UCL) et inférieure (LCL).
Surveiller la stabilité du processus : Vérifier si le processus reste statistiquement sous contrôle ou si des ajustements sont nécessaires.
Prendre des décisions basées sur des données : Analyser les tendances et agir de manière proactive pour améliorer les performances du processus.
# Charger les bibliothèques nécessaires
library(dplyr)
library(qcc)
## Package 'qcc' version 2.7
## Type 'citation("qcc")' for citing this R package in publications.
# Préparer les données pour le graphique de contrôle
control_chart_data <- generated_data %>%
group_by(Répétition) %>%
summarise(
Mean_Score = mean(Score_Total, na.rm = TRUE),
SD_Score = sd(Score_Total, na.rm = TRUE),
.groups = "drop"
)
# Vérifier que les données sont suffisantes
if (nrow(control_chart_data) < 2) {
stop("Les données ne sont pas suffisantes pour un graphique de contrôle.")
}
# Créer un graphique de contrôle (X-bar chart)
qcc_object <- qcc(
data = control_chart_data$Mean_Score,
type = "xbar.one", # Utiliser un graphique X-bar pour les moyennes
title = "Graphique de Contrôle pour Score_Total",
xlab = "Répétition",
ylab = "Score Moyen",
labels = control_chart_data$Répétition
)
# Ajouter des limites de contrôle
abline(h = qcc_object$limits[, 1], col = "red", lty = 2) # Limite inférieure
abline(h = qcc_object$limits[, 2], col = "red", lty = 2) # Limite supérieure
# Résumé des limites de contrôle
cat("\nLimites de Contrôle (UCL et LCL):\n")
##
## Limites de Contrôle (UCL et LCL):
print(qcc_object$limits)
## LCL UCL
## 8.842629 8.906318