BioDataScience2::learnr_setup() SciViews::R("model", lang = "fr") # Required for RSConnect # SciViews::R library(rlang) library(data.table) library(ggplot2) library(tibble) library(tidyr) library(dplyr) library(dtplyr) library(broom) library(forcats) library(collapse) library(fs) library(svMisc) library(svBase) library(svFlow) library(data.io) library(chart) library(tabularise) library(SciViews) # model library(modelit) # ... more library(testthat) library(equatags) rice <- read("rice", package = "BioDataScience2") rice <- labelise(rice, label = list(area = "Surface", major_axis_length = "Longueur"), units = list(area = "pixels^2", major_axis_length = "pixels") ) rice_lm <- lm(data = rice, area ~ major_axis_length) lm_result <- tidy(rice_lm) lm_param <- glance(rice_lm)
BioDataScience2::learnr_banner()
BioDataScience2::learnr_server(input, output, session)
Utiliser la fonction lm()
pour obtenir un modèle de régression linéaire simple
Étudier le résumé et le graphique du modèle linéaire
Paramétriser l'équation de la régression linéaire
Découvrir l'analyse des résidus du modèle
@Cinar_Koklu_2019 s'intéressent à deux variétés de riz cultivées en Turquie . Ils ont pour objectif de mettre en place un outil capable, sur base d'analyse d'image, de classer des grains de riz. Une copie de leurs données est disponible dans rice
du package BioDataScience2
. Les dimensions mesurées sur les images ne sont pas calibrées et sont exprimées en pixels. Nous rajoutons cette information dans notre jeu de données à l'aide de labelise()
.
rice <- read("rice", package = "BioDataScience2") rice <- labelise(rice, label = list(area = "Surface", major_axis_length = "Longueur"), units = list(area = "pixels^2", major_axis_length = "pixels") )
Vous avez à disposition le tableau rice
constitué des variables suivantes :
r paste0("<code>", names(rice), "</code>")
Consultez la page d'aide avec ?BioDataScience2::rice
et la publication (référence en fin de document et dans la page d'aide) pour en apprendre davantage.
Votre objectif est de réaliser une régression linéaire de la variable area
en fonction de major_axis_length
, parce que vous soupçonnez cette relation d'être importante pour discriminer les deux variétés de riz plus tard. Vous devrez ensuite analyser le résumé de cette régression et utiliser les outils de diagnostic des résidus.
Débutez cette analyse en réalisant un nuage de point de area
en fonction de major_axis_length
pour voir comment se présentent les données.
chart(data = ___, ___ ~ ___) ___ ___()
chart(data = rice, ___ ~ ___) + ___() #### ATTENTION: Hint suivant = solution !####
## Solution ## chart(data = rice, area ~ major_axis_length) + geom_point()
grade_code("Ce graphique en nuage de points est un pré-requis indispensable pour visualiser vos données avant de modéliser. C'est une bonne habitude à prendre que de l'étudier systématiquement avant de faire un régression. Vous noterez que le nuage de point s'étire le long d'une droite... C'est plutôt bon signe, non ?")
Nous pouvons continuer la description des données avec une matrice de corrélation de Pearson :
correlation(num_vars(rice), method = "pearson") |> tabularise()
Nous voyons que area
est raisonnablement bien corrélé à major_axis_length
, même si ce n'est pas la corrélation la plus forte. Ensuite une description générale des données, notamment pour voir comment elles se répartissent et s'il y a des valeurs manquantes, complète notre description du jeu de données.
skimr::skim(rice)
Les distributions des deux variables sont univariées et les moyennes assez proches des médianes, ce qui est bon signe (symétrie). Il n'y a pas de données manquantes. Avec r nrow(rice)
, nous avons un nombre bien suffisant de cas pour réaliser notre régression linéaire.
Réalisez à présent la régression linéaire demandée de la variable area
en fonction de la variable major_axis_length
du tableau rice
.
rice_lm <- lm(data = ___, ___ ~ ___) # Résumé de la régression linéaire summary(___) |> tabularise() # Graphique de la régression chart(___)
rice_lm <- lm(data = rice, ___ ~ ___) # Résumé de la régression linéaire summary(rice_lm) |> tabularise() # Graphique de la régression chart(rice_lm) #### ATTENTION: Hint suivant = solution !####
## Solution ## rice_lm <- lm(data = rice, area ~ major_axis_length) # Résumé de la régression linéaire summary(rice_lm) |> tabularise() # Graphique de la régression chart(rice_lm)
grade_code("Vous avez calculé votre objet `lm_rice`. Vous l'avez résumé et représenté graphiquement. Vous avez du matériel à examiner pour déterminer si cette régression tient la route. Avec un R^2 de 0.815, la régression est bonne, mais pouvez-vous repérer des éléments importants dans le tableau via le Quiz ci-dessous ?")
quiz( question(text = "Quelle est la valeur de l'ordonnée à l'origine ?", answer(sprintf("%.2f", lm_result$estimate[1]), correct = TRUE), answer(sprintf("%.2f", lm_result$estimate[2])), answer(sprintf("%.2f", lm_result$std.error[1])), answer(sprintf("%.2f", lm_result$std.error[2])), answer(sprintf("%.2f", lm_result$statistic[1])), answer(sprintf("%.2f", lm_result$statistic[2])), answer(sprintf("%.2f", lm_param$r.squared[1])), allow_retry = TRUE, random_answer_order = TRUE, correct = "Vous semblez comprendre ce qu'il y a dans le tableau des résultats.", incorrect = "Oups, il semble que vous avez mal lu le tableau résumé de la régression linéaire.", submit_button = "Soumettre une réponse", try_again_button = "Resoumettre une réponse"), question(text = "Quelle est la valeur de la pente ?", answer(sprintf("%.2f", lm_result$estimate[1])), answer(sprintf("%.2f", lm_result$estimate[2]), correct = TRUE), answer(sprintf("%.2f", lm_result$std.error[1])), answer(sprintf("%.2f", lm_result$std.error[2])), answer(sprintf("%.2f", lm_result$statistic[1])), answer(sprintf("%.2f", lm_result$statistic[2])), answer(sprintf("%.2f", lm_param$r.squared[1])), allow_retry = TRUE, random_answer_order = TRUE, correct = "Vous avez repéré les valeurs estimées des deux paramètres du modèle, pente et ordonnée à l'origine. Un aspect très important est la paramétrisation du modèle.", incorrect = "Oups, il semble que vous avez mal lu le tableau résumé de la régression linéaire.", submit_button = "Soumettre une réponse", try_again_button = "Resoumettre une réponse") )
Une fois que vous avez les estimateurs des différents paramètres de votre modèle, vous pouvez placer ces valeurs dans son équation. Cette étape importante se nomme la paramétrisation du modèle.
Dans la SciViews Box 2024, vous avez des outils pour vous y aider. La fonction eq__()
extrait l'équation du modèle et son argument use_coefs = TRUE
indique de remplacer les paramètres par les valeurs estimées. Ainsi, pour obtenir cette équation, vous pouvez écrire un chunk en ligne `r eq__(rice_lm, use_coefs = TRUE)`
à l'intérieur de balises Markdown d'équation dite "display" (équation sur sa propre ligne, hors texte, par opposition à l'équation "inline", directement dans le texte). Cela s'écrit comme suit :
$$
, c'est la balise Markdown d'entrée d'une équation "display"`r eq__(...)`
qui viendra placer le contenu de l'équation calculé par R lors du rendu du document$$
et prenez soin d'encadrer le tout par deux lignes vides (une au-dessus de la balise d'entrée, et une au-dessous de la balise de sortie)Cela donne ceci :
$$
r eq__(rice_lm, use_coefs = TRUE, coef_digits = c(0, 1))
$$
Astuce: vous contrôlez le nombre de chiffres derrière la virgule pour chaque estimateur à l'aide de l'argument supplémentaire coef_digits =
qui accepte un nombre entier (même nombre de chiffres derrière la virgule pour tous les estimateurs), ou un vecteur d'entiers pour varier la précision de chaque estimateur successif. Il est important de limiter les valeurs à un nombre de chiffres significatifs par rapport au calcul qui est réalisé. Ne jamais conserver un grand nombre de décimales inutiles dans les équations ! L'équation ci-dessus a été obtenue à l'aide de `r eq__(rice_lm, use_coefs = TRUE, coef_digits = c(0, 1))`
.
Maintenant que les aspects techniques sont expliqués, concentrez-vous sur le contenu de cette dernière équation et sa signification.
Rappelez-vous que $Y = \hat{Y} + \epsilon$, les valeurs de la variable réponse $Y$ sont égales à leurs valeurs estimées par le modèle notées $\hat{Y}$ (on prononce "i grec chapeau" en français, ou "waïe hat" en anglais) additionnées des résidus $\epsilon$ et
$\epsilon \sim N(0, \sigma^2)$, les résidus forment la composante statistique du modèle et suivent une distribution Normale de moyenne nulle et de variance constante $\sigma^2$ (à garder à l'esprit pour comprendre ce que l'on vérifiera ensuite lors de l'analyse des résidus).
Comparez l'équation du modèle paramétrisé avec l'équation générale du modèle qui est présentée dans le tableau résumé plus haut. Assurez-vous d'avoir bien compris la logique de la paramétrisation pour passer de l'une à l'autre avant de passer à la suite.
Pour vous faciliter la comparaison, l'équation générale du modèle est reproduite ci-dessous avec `r eq__(rice_lm)`
:
$$
r eq__(rice_lm)
$$
Le graphique et le tableau ci-dessous vous rappellent les informations importantes de votre régression rice_lm
.
# Graphique de la régression `rice_lm` chart(rice_lm) # Tableau résumé court de la régression `rice_lm` tabularise$tidy(rice_lm)
Vous avez toujours à disposition l'objet rice_lm
. Construisez quatre graphiques afin d'étudier :
area
,area
et# Résidus en fonction des valeurs prédites de area chart$___(___) # Graphique quantile-quantile chart$___(___) # Echelle et position des résidus chart$___(___) # Effet de levier chart$___(___)
# Consultez la page d'aide `?modelit::chart.lm` # Résidus en fonction des valeurs prédites de area chart$___(___) # Graphique quantile-quantile chart$___(___) # Echelle et position des résidus chart$___(___) # Effet de levier chart$___(___) #### ATTENTION: Hint suivant = solution !####
## Solution ## # Résidus en fonction des valeurs prédites de area chart$resfitted(rice_lm) # Graphique quantile-quantile chart$qqplot(rice_lm) # Echelle et position des résidus chart$scalelocation(rice_lm) # Effet de levier chart$resleverage(rice_lm)
grade_code("Ce sont les quatre graphiques les plus courants de l'analyse des résidus. Êtes-vous capable à présent de répondre à la question qui suit ?")
question("Sélectionnez parmi les éléments suivants les affirmations vraies.", answer("Les résidus sont contenus et se répartissent de manière équilibrée et linéaire.", correct = TRUE, message = "**Graphique1** La répartition des résidus sur le premier graphique permet d'observer sur l'axe des ordonnées des valeurs entre - 2000 et +2000 pour les résidus, par rapport à un plage plus élevée pour les valeurs prédites de 10000 à 17000. Les résidus sont donc, comparativement, raisonnables. La répartition des résidus est homogène autour de l'axe horizontal à zéro et il n'y a pas de dérive non linéaire (la courbe de tendance générale en bleu est pratiquement linéaire et reste proche de zéro)."), answer("Les résidus suivent une distribution Normale.", correct = TRUE, message = "<br/><br/>**Graphique 2** Le graphique quantile-quantile permet de vérifier si la distribution des résidus est Normale. On observe que les résidus les plus faibles et les plus élevés ne s'éloigne de la droite de référence que très légèrement. La distribution des résidus est donc Normale ou proche de la Normale."), answer("Il y a homoscédasticité des résidus.", correct = TRUE, message = "<br/><br/>**Graphique 3** La position et l'échelle des résidus sur le graphique 3, en représentant leur valeur absolue sur l'axe des ordonnées, superpose les résidus négatifs sur les résidus positifs. Cette représentation est la meilleure pour vérifier l'homoscédasticité, c'est-à-dire, la variance homogène en fonction des valeurs prédites sur l'axe des abscisses. La courbe de tendance en bleu est horizontale, ce qui le confirme. Nous avons bien ici homoscédasticité des résidus."), answer("Aucune valeur n'influence trop fortement la régression linéaire.", correct = TRUE, message = "<br/><br/>**Graphique 4** La régression linéaire par les moindres carrés est très influencée par les valeurs extrêmes. L'effet de levier compare les distances des points entres eux sur l'axe des abscisses et vérifie q'il n'y en a pas trop éloigné des autres, la distance de Cook (taille des points sur le quatrième graphique) quantifie l'impact de chaque observation sur la position de la droite de régression. Ici, le graphique 4 présente un comportement sain du point de vue des observations potentiellement influentes ou extrêmes."), correct = "Vous avez sélectionné les affirmations correctes.", incorrect = "Oups, il semble que vous avez mal interpété les graphiques ci-dessus. Observez bien, relisez la section correspondante du cours et retentez l'exercice.", allow_retry = TRUE, random_answer_order = FALSE, submit_button = "Soumettre une réponse", try_again_button = "Resoumettre une réponse" )
L'analyse des résidus est importante pour déterminer la validité de votre modèle, mais ce n'est pas une tâche facile. Au début, ces graphiques ne paraissent pas des plus clairs. Vous apprendrez par la pratique et en faisant d'autres exercices dans la suite du cours.
Ici, le nombre important d'observations donne une réponse claire... et de plus, les résidus sont pratiquement parfaits. Retenez ceci comme un exemple d'excellents résultats. Avec moins de points (voyez par exemple le cas des cerisiers noirs développé dans le cours) il faut bien aiguiser son œil pour discerner les résultats corrects ou acceptables de ceux qui invalident votre modèle.
Vous progressez dans votre apprentissage. Vous venez de découvrir comment réaliser une régression linéaire simple dans R, d'en produire un tableau résumé et une visualisation graphique. Vous avez abordé la paramétrisation de l'équation du modèle et vous avez entrepris une première approche de l'analyse des résidus du modèle.
question_text( "Laissez-nous vos impressions sur ce learnr", answer("", TRUE, message = "Pas de commentaires... C'est bien aussi."), incorrect = "Vos commentaires sont enregistrés.", placeholder = "Entrez vos commentaires ici...", allow_retry = TRUE, submit_button = "Soumettre une réponse", try_again_button = "Resoumettre une réponse" )
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.