# Chargement des packages
pacman::p_load(tidyverse, readr, GGally, corrplot, FactoMineR, factoextra)
library(knitr)
library(kableExtra)
##
## Attachement du package : 'kableExtra'
## L'objet suivant est masqué depuis 'package:dplyr':
##
## group_rows
Description du jeu de données:
Le jeu de données utilisé dans ce projet est “House Prices: Advanced Regression Techniques”, disponible sur la plateforme Kaggle. Il s’agit d’un ensemble de données décrivant des caractéristiques de maisons situées dans la ville d’Ames (États-Unis), avec pour objectif principal l’analyse et la prédiction du prix de vente des logements.
Ce jeu de données contient des informations détaillées sur les habitations, notamment leur taille, leur qualité, leur localisation ainsi que divers aspects structurels et qualitatifs.
Taille du jeu de données
#Lecture des données
houses <- read.csv("train.csv")
view(houses)
#Voir les premières lignes
head(houses)
# Voir les dernières lignes
tail(houses)
# Les dimensions
dim(houses)
## [1] 1460 81
Le jeu de données contient : Nombre d’observations (lignes) : 1460 maisons Nombre de variables (colonnes) : 81 variables Chaque ligne correspond à une maison, et chaque colonne représente une caractéristique descriptive ou le prix de vente.
Dans le cadre de ce projet, je ne vais pas travailler sur toutes les variables du jeu de données. Je vais me concentrer uniquement sur un sous-ensemble de variables ( variables) que j’ai sélectionnées, afin de faciliter l’analyse et de me concentrer sur les informations les plus importantes pour l’étude.
# Extraction des variables choisies
house <- houses[, c("Id","MSSubClass","MSZoning","LotFrontage","LotArea","Street","LotShape","LandContour","Utilities","LotConfig","LandSlope","Neighborhood","Condition1","Condition2","BldgType","HouseStyle","OverallQual","OverallCond","YearBuilt","YearRemodAdd","ExterQual","TotalBsmtSF","BsmtQual","BsmtCond","BsmtExposure","GrLivArea","GarageArea","FullBath","SalePrice")]
#view(house)
dim(house)
## [1] 1460 29
Valeurs manquantes
# Nombre total de valeurs manquantes dans le dataset
sum(is.na(house))
## [1] 371
# Nombre de valeurs manquantes par variable
na_counts <- colSums(is.na(house))
na_table <- data.frame(
Variable = names(na_counts),
Nb_valeurs_manquantes = as.vector(na_counts)
)
na_table
Les valeurs manquantes sont identifiées à l’aide de la fonction is.na().
Dans le jeu de données, certaines variables contiennent des valeurs manquantes, notamment celles liées à des caractéristiques optionnelles des maisons (par exemple : sous-sol, ruelle, garage).
Que faire des valeurs manquantes ? Dans ce projet, plusieurs choix sont possibles :
Suppression
Remplacement On peut remplacer les valeurs manquantes par : 0 pour les variables numériques “None” pour les variables qualitatives
Je vais choisir de remplacer les valeurs manquantes plutôt que de les supprimer
Pourquoi ce choix ?
Ce choix est justifié car dans ce dataset :
les valeurs manquantes ne sont pas aléatoires elles signifient souvent absence d’un élément (ex : pas de ruelle, pas de sous-sol fini) et supprimer les lignes ferait perdre beaucoup d’informations
# 🔢 Remplacement des NA numériques par 0
num_vars <- sapply(house, is.numeric)
house[num_vars] <- lapply(house[num_vars], function(x) {
x[is.na(x)] <- 0
return(x)
})
# 🏷️ Remplacement des NA catégorielles par "None"
cat_vars <- sapply(house, is.character)
house[cat_vars] <- lapply(house[cat_vars], function(x) {
x[is.na(x)] <- "None"
return(x)
})
view(house)
Description des variables utilisées
Variables générales
Id → Identifiant unique de la maison (qualitative / non exploitable)
MSSubClass → Type de logement (1 étage, 2 étages…) (qualitative)
MSZoning → Zone d’urbanisme (qualitative)
Terrain LotFrontage → Largeur du terrain côté rue (quantitative)
LotArea → Surface du terrain (quantitative)
Street → Type de route d’accès (qualitative)
Alley → Présence d’une ruelle (qualitative)
LotShape → Forme du terrain (qualitative)
LandContour → Relief du terrain (qualitative)
Utilities → Services disponibles (qualitative)
LotConfig → Configuration du terrain (qualitative)
LandSlope → Pente du terrain (qualitative)
Localisation
Neighborhood → Quartier (qualitative)
Condition1 → Condition principale autour de la maison (qualitative)
Condition2 → Condition secondaire (qualitative)
Type de construction
BldgType → Type de bâtiment (qualitative)
HouseStyle → Style architectural (qualitative)
Qualité et état
OverallQual → Qualité globale (score 1–10) (quantitative ordinale)
OverallCond → État général (quantitative ordinale)
YearBuilt → Année de construction (quantitative)
YearRemodAdd → Année de rénovation (quantitative)
ExterQual → Qualité extérieure (qualitative ordinale)
Sous-sol
TotalBsmtSF → Surface totale du sous-sol (quantitative)
BsmtQual → Qualité du sous-sol (qualitative ordinale)
BsmtCond → État du sous-sol (qualitative ordinale)
BsmtExposure → Exposition du sous-sol (qualitative)
Surfaces et garage
GrLivArea → Surface habitable (quantitative)
GarageArea → Surface du garage (quantitative)
FullBath → Nombre de salles de bain (quantitative discrète)
SalePrice → Prix de vente de la maison (quantitative)
# voire les variable num et les variables qualitative
glimpse(house)
## Rows: 1,460
## Columns: 29
## $ Id <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17…
## $ MSSubClass <dbl> 60, 20, 60, 70, 60, 50, 20, 60, 50, 190, 20, 60, 20, 20, …
## $ MSZoning <chr> "RL", "RL", "RL", "RL", "RL", "RL", "RL", "RL", "RM", "RL…
## $ LotFrontage <dbl> 65, 80, 68, 60, 84, 85, 75, 0, 51, 50, 70, 85, 0, 91, 0, …
## $ LotArea <dbl> 8450, 9600, 11250, 9550, 14260, 14115, 10084, 10382, 6120…
## $ Street <chr> "Pave", "Pave", "Pave", "Pave", "Pave", "Pave", "Pave", "…
## $ LotShape <chr> "Reg", "Reg", "IR1", "IR1", "IR1", "IR1", "Reg", "IR1", "…
## $ LandContour <chr> "Lvl", "Lvl", "Lvl", "Lvl", "Lvl", "Lvl", "Lvl", "Lvl", "…
## $ Utilities <chr> "AllPub", "AllPub", "AllPub", "AllPub", "AllPub", "AllPub…
## $ LotConfig <chr> "Inside", "FR2", "Inside", "Corner", "FR2", "Inside", "In…
## $ LandSlope <chr> "Gtl", "Gtl", "Gtl", "Gtl", "Gtl", "Gtl", "Gtl", "Gtl", "…
## $ Neighborhood <chr> "CollgCr", "Veenker", "CollgCr", "Crawfor", "NoRidge", "M…
## $ Condition1 <chr> "Norm", "Feedr", "Norm", "Norm", "Norm", "Norm", "Norm", …
## $ Condition2 <chr> "Norm", "Norm", "Norm", "Norm", "Norm", "Norm", "Norm", "…
## $ BldgType <chr> "1Fam", "1Fam", "1Fam", "1Fam", "1Fam", "1Fam", "1Fam", "…
## $ HouseStyle <chr> "2Story", "1Story", "2Story", "2Story", "2Story", "1.5Fin…
## $ OverallQual <dbl> 7, 6, 7, 7, 8, 5, 8, 7, 7, 5, 5, 9, 5, 7, 6, 7, 6, 4, 5, …
## $ OverallCond <dbl> 5, 8, 5, 5, 5, 5, 5, 6, 5, 6, 5, 5, 6, 5, 5, 8, 7, 5, 5, …
## $ YearBuilt <dbl> 2003, 1976, 2001, 1915, 2000, 1993, 2004, 1973, 1931, 193…
## $ YearRemodAdd <dbl> 2003, 1976, 2002, 1970, 2000, 1995, 2005, 1973, 1950, 195…
## $ ExterQual <chr> "Gd", "TA", "Gd", "TA", "Gd", "TA", "Gd", "TA", "TA", "TA…
## $ TotalBsmtSF <dbl> 856, 1262, 920, 756, 1145, 796, 1686, 1107, 952, 991, 104…
## $ BsmtQual <chr> "Gd", "Gd", "Gd", "TA", "Gd", "Gd", "Ex", "Gd", "TA", "TA…
## $ BsmtCond <chr> "TA", "TA", "TA", "Gd", "TA", "TA", "TA", "TA", "TA", "TA…
## $ BsmtExposure <chr> "No", "Gd", "Mn", "No", "Av", "No", "Av", "Mn", "No", "No…
## $ GrLivArea <dbl> 1710, 1262, 1786, 1717, 2198, 1362, 1694, 2090, 1774, 107…
## $ GarageArea <dbl> 548, 460, 608, 642, 836, 480, 636, 484, 468, 205, 384, 73…
## $ FullBath <dbl> 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 1, 3, 1, 2, 1, 1, 1, 2, 1, …
## $ SalePrice <dbl> 208500, 181500, 223500, 140000, 250000, 143000, 307000, 2…
OBJECTIF:
L’objectif de cette étude est d’analyser les prix de vente des maisons et d’identifier les facteurs qui influencent ces prix à partir des caractéristiques des logements.
Etudier la distribution des prix de vente des maisons ; Comprendre l’impact des caractéristiques du logement (surface, qualité, localisation, etc.) sur le prix ; Mettre en évidence les relations entre les variables quantitatives et le prix de vente ; Comparer les prix selon certaines caractéristiques qualitatives (quartier, type de maison, etc.) ; Construire un modèle explicatif permettant de mieux comprendre les déterminants du prix immobilier.
Analyse univariée de la variable quantitative SalePrice
tableau_stats <- data.frame(
"Moyenne" = mean(house$SalePrice),
"Médiane" = median(house$SalePrice),
"Écart-type" = sd(house$SalePrice),
"Variance" = var(house$SalePrice),
"Minimum" = min(house$SalePrice),
"Maximum" = max(house$SalePrice),
"Q1" = as.numeric(quantile(house$SalePrice, 0.25)),
"Q3" = as.numeric(quantile(house$SalePrice, 0.75)),
"Asymétrie" = moments::skewness(house$SalePrice),
"Aplatissement" = moments::kurtosis(house$SalePrice)
)
knitr::kable(tableau_stats,
caption = "<span style='color:blue; font-size:16px'><b>Résumé statistique de la variable SalePrice</b></span>",
escape = FALSE) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE)
| Moyenne | Médiane | Écart.type | Variance | Minimum | Maximum | Q1 | Q3 | Asymétrie | Aplatissement |
|---|---|---|---|---|---|---|---|---|---|
| 180921.2 | 163000 | 79442.5 | 6311111264 | 34900 | 755000 | 129975 | 214000 | 1.880941 | 9.509812 |
La forme de distribution
La variable SalePrice présente une distribution asymétrique à droite car moyenne > médiane → asymétrie à droite
# Création des classes (intervalles)
breaks <- seq(min(house$SalePrice), max(house$SalePrice), length.out =80 )
# Découpage en classes
classes <- cut(house$SalePrice, breaks = breaks, include.lowest = TRUE)
# Tableau des effectifs et fréquences
table_freq <- as.data.frame(table(classes))
# Ajout des fréquences relatives
table_freq$Frequence <- round(table_freq$Freq / sum(table_freq$Freq), 3)
table_freq
Histogramme de SalePrice
ggplot(house, aes(x = SalePrice)) +
geom_histogram(bins = 80, fill = "blue", color = "white") +
labs(title = "Histogramme de SalePrice",
x = "Prix de vente",
y = "Fréquence")
Courbe de densité de SalePrice
ggplot(house, aes(x = SalePrice)) +
geom_density(fill = "red", alpha = 0.5) +
labs(title = "Courbe de densité de SalePrice",
x = "Prix de vente",
y = "Densité")
Histogramme et densité de SalePrice
ggplot(house, aes(x = SalePrice)) +
geom_histogram(aes(y = ..density..),
bins = 80,
fill = "blue",
color = "white") +
geom_density(alpha=.6,fill="red") +
labs(title = "Histogramme et densité de SalePrice",
x = "Prix de vente",
y = "Densité")
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
L’histogramme et la courbe de densité de SalePrice montrent une distribution asymétrique à droite. On observe que la majorité des maisons sont concentrées dans les intervalles de prix moyens, ce qui correspond à la zone la plus dense de la distribution. Cette concentration est visible à la fois dans les barres les plus élevées de l’histogramme et dans le pic de la courbe de densité. En revanche, les prix élevés sont peu fréquents et s’étendent progressivement vers la droite, formant une longue queue, ce qui traduit la présence de valeurs extrêmes.
Boxplot de SalePrice
ggplot(house, aes(y = SalePrice)) +
geom_boxplot(fill = "orange") +
labs(title = "Boxplot de SalePrice",
y = "Prix de vente")
Le boxplot de SalePrice montre que la moitié des prix des maisons se
situe dans une zone centrale comprise entre le premier et le troisième
quartile. La médiane représente le prix typique des logements et se
situe autour des valeurs moyennes du marché. On observe également que la
distribution n’est pas symétrique, car les valeurs supérieures
s’étendent plus loin que les valeurs inférieures. Enfin, plusieurs
points situés au-dessus des moustaches indiquent la présence de valeurs
extrêmes, correspondant à des maisons beaucoup plus chères que la
majorité des observations. Cela confirme que la distribution des prix de
vente est asymétrique à droite et contient des observations
atypiques.
Analyse univariée de la variable qualitative MSZoning
Tableau des effectifs et fréquences
# Tableau des effectifs
tab_eff <- table(house$MSZoning)
# Tableau des fréquences
tab_freq <- prop.table(tab_eff)
# Tableau final
table_final <- data.frame(
Modalité = names(tab_eff),
Effectif = as.vector(tab_eff),
Pourcentage = round(as.vector(tab_freq) * 100, 2)
)
table_final
Diagrammes en barres (MSZoning)
# Calcul des pourcentages
df <- as.data.frame(table(house$MSZoning))
df$Perc <- round(df$Freq / sum(df$Freq) * 100, 1)
# Diagramme
ggplot(df, aes(x = Var1, y = Perc)) +
geom_bar(stat = "identity", fill = "#FFD700", color = "black") +
geom_text(aes(label = paste0(Perc, "%")), vjust = -0.5) +
labs(title = "Diagramme en barres de MSZoning (en %)",
x = "Zone d'urbanisme",
y = "Pourcentage") +
ylim(0, max(df$Perc) + 10) +
theme_minimal()
Le diagramme en barres de la variable MSZoning montre la répartition des
maisons selon les différentes zones d’urbanisme. On observe que la
catégorie RL (résidentiel faible densité) est largement la plus
représentée, ce qui indique que la majorité des logements du jeu de
données se situent dans des zones résidentielles classiques. Les autres
catégories comme RM( appartements), FV(zones spécifiques planifiées),
RH(zones plus denses) et C (commercial) sont beaucoup moins fréquentes,
ce qui traduit une distribution déséquilibrée des types de zones dans
l’échantillon. Ainsi, le dataset est principalement composé de maisons
situées en zones résidentielles à faible densité