Exercice 2

Question 1

Faire une analyse descriptive de la base de données.
# Charger les données et définir les nouveaux noms de colonnes
abalone_data <- read.table("abalone.csv", sep = ",", header = TRUE)
colnames(abalone_data) <- c("sex", "length", "diameter", "height", "whole_weight",
                            "shucked_weight", "viscera_weight", "shell_weight",
                            "rings")

# Afficher un aperçu des données
head(abalone_data)
##   sex length diameter height whole_weight shucked_weight viscera_weight
## 1   M  0.350    0.265  0.090       0.2255         0.0995         0.0485
## 2   F  0.530    0.420  0.135       0.6770         0.2565         0.1415
## 3   M  0.440    0.365  0.125       0.5160         0.2155         0.1140
## 4   I  0.330    0.255  0.080       0.2050         0.0895         0.0395
## 5   I  0.425    0.300  0.095       0.3515         0.1410         0.0775
## 6   F  0.530    0.415  0.150       0.7775         0.2370         0.1415
##   shell_weight rings
## 1        0.070     7
## 2        0.210     9
## 3        0.155    10
## 4        0.055     7
## 5        0.120     8
## 6        0.330    20
summary(abalone_data)
##      sex                length         diameter          height      
##  Length:4176        Min.   :0.075   Min.   :0.0550   Min.   :0.0000  
##  Class :character   1st Qu.:0.450   1st Qu.:0.3500   1st Qu.:0.1150  
##  Mode  :character   Median :0.545   Median :0.4250   Median :0.1400  
##                     Mean   :0.524   Mean   :0.4079   Mean   :0.1395  
##                     3rd Qu.:0.615   3rd Qu.:0.4800   3rd Qu.:0.1650  
##                     Max.   :0.815   Max.   :0.6500   Max.   :1.1300  
##   whole_weight    shucked_weight   viscera_weight     shell_weight   
##  Min.   :0.0020   Min.   :0.0010   Min.   :0.00050   Min.   :0.0015  
##  1st Qu.:0.4415   1st Qu.:0.1860   1st Qu.:0.09337   1st Qu.:0.1300  
##  Median :0.7997   Median :0.3360   Median :0.17100   Median :0.2340  
##  Mean   :0.8288   Mean   :0.3594   Mean   :0.18061   Mean   :0.2389  
##  3rd Qu.:1.1533   3rd Qu.:0.5020   3rd Qu.:0.25300   3rd Qu.:0.3290  
##  Max.   :2.8255   Max.   :1.4880   Max.   :0.76000   Max.   :1.0050  
##      rings       
##  Min.   : 1.000  
##  1st Qu.: 8.000  
##  Median : 9.000  
##  Mean   : 9.932  
##  3rd Qu.:11.000  
##  Max.   :29.000
# Visualisation des données
library(ggplot2)

ggplot(abalone_data, aes(x = length, y = height)) +
  geom_point()

ggplot(abalone_data, aes(x = rings)) +
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Question 2

A l’aide de l’algorithme des 3 plus proches voisins, prédire la valeur de rings. Pour cela, on construira une base de données d’apprentissage sur laquelle on entraînera l’algorithme et on prédira les valeurs de rings sur une base de données test. Rappeler comment l’algorithme des k plus proches voisins fonctionne dans le cadre de la prédiction.
# Installation du package kknn si nécessaire
if (!requireNamespace("kknn", quietly = TRUE)) {
  install.packages("kknn")
}

library(kknn)

# Fixer la graine aléatoire pour la reproductibilité
set.seed(123)

# Séparation des données en ensembles d'apprentissage et de test
train_indices <- sample(nrow(abalone_data), nrow(abalone_data) * 0.8)
train_data <- abalone_data[train_indices, ]
test_data <- abalone_data[-train_indices, ]

# Entraîner le modèle k-NN avec k = 3
k <- 3
knn_model <- kknn(rings ~ ., train_data, test_data, k = k)

# Prédire les valeurs de rings sur l'ensemble de test
predictions <- predict(knn_model, newdata = test_data)

Question 3

Calculer l’erreur quadratique moyenne sur la base de données test. Sur un graphique, tracer les vraies valeurs de rings de la base de données test en abscisse et les valeurs prédites en ordonnées.
# Calcul de l'erreur quadratique moyenne (RMSE)
rmse <- sqrt(mean((test_data$rings - predictions)^2))
cat("RMSE:", rmse, "\n")
## RMSE: 2.599916
# Graphique des valeurs réelles vs. valeurs prédites
plot(test_data$rings, predictions,
     xlab = "Valeurs Réelles",
     ylab = "Valeurs Prédites",
     main = "Valeurs Réelles vs. Valeurs Prédites")

# Ajouter une ligne de référence (y = x)
abline(0, 1, col = "red")

# Ajouter une légende pour afficher le RMSE
legend("topleft", legend = paste("RMSE =", round(rmse, 2)), col = "red", lwd = 1)

Question 4

Écrire un code permettant d’évaluer l’erreur de prédiction de l’algorithme des k plus proches voisins pour différentes valeurs de k. Discuter d’un choix de k optimal.
# Créer une fonction pour calculer le RMSE pour une valeur donnée de k
calculate_rmse <- function(k, train_data, test_data) {
  # Entraîner le modèle k-NN avec la valeur de k spécifiée
  knn_model <- kknn(rings ~ ., train_data, test_data, k = k)
  
  # Prédire les valeurs de rings sur l'ensemble de test
  predictions <- predict(knn_model, newdata = test_data)
  
  # Calculer le RMSE
  rmse <- sqrt(mean((test_data$rings - predictions)^2))
  
  return(rmse)
}

# Créer une séquence de valeurs de k à tester (par exemple, de 1 à 100)
k_values <- 1:100

# Initialiser un vecteur pour stocker les résultats du RMSE
rmse_results <- numeric(length(k_values))

# Calculer le RMSE pour chaque valeur de k
for (i in 1:length(k_values)) {
  rmse_results[i] <- calculate_rmse(k_values[i], train_data, test_data)
}

# Trouver le minimum de la séquence de valeurs de k
minimum_k <- k_values[which.min(rmse_results)]

cat("La valeur minimale de k est:", minimum_k, "\n")
## La valeur minimale de k est: 25
maximum_k <- k_values[which.max(rmse_results)]

cat("La valeur maximale de k est:", maximum_k, "\n")
## La valeur maximale de k est: 1
# Afficher les résultats du RMSE pour chaque valeur de k
print(data.frame(K = k_values, RMSE = rmse_results))
##       K     RMSE
## 1     1 2.971153
## 2     2 2.754163
## 3     3 2.599916
## 4     4 2.503379
## 5     5 2.439459
## 6     6 2.395794
## 7     7 2.364032
## 8     8 2.340641
## 9     9 2.322797
## 10   10 2.308928
## 11   11 2.298443
## 12   12 2.289234
## 13   13 2.280464
## 14   14 2.273297
## 15   15 2.267736
## 16   16 2.263252
## 17   17 2.259586
## 18   18 2.256857
## 19   19 2.254937
## 20   20 2.253133
## 21   21 2.251531
## 22   22 2.250455
## 23   23 2.249573
## 24   24 2.248985
## 25   25 2.248898
## 26   26 2.248998
## 27   27 2.249087
## 28   28 2.249253
## 29   29 2.249400
## 30   30 2.249526
## 31   31 2.249743
## 32   32 2.250007
## 33   33 2.250367
## 34   34 2.250911
## 35   35 2.251598
## 36   36 2.252190
## 37   37 2.252722
## 38   38 2.253302
## 39   39 2.253761
## 40   40 2.254214
## 41   41 2.254779
## 42   42 2.255403
## 43   43 2.256058
## 44   44 2.256712
## 45   45 2.257362
## 46   46 2.258006
## 47   47 2.258600
## 48   48 2.259213
## 49   49 2.259877
## 50   50 2.260554
## 51   51 2.261226
## 52   52 2.261883
## 53   53 2.262534
## 54   54 2.263162
## 55   55 2.263802
## 56   56 2.264478
## 57   57 2.265190
## 58   58 2.265930
## 59   59 2.266685
## 60   60 2.267443
## 61   61 2.268187
## 62   62 2.268914
## 63   63 2.269631
## 64   64 2.270330
## 65   65 2.271024
## 66   66 2.271715
## 67   67 2.272381
## 68   68 2.273025
## 69   69 2.273659
## 70   70 2.274266
## 71   71 2.274838
## 72   72 2.275425
## 73   73 2.276034
## 74   74 2.276653
## 75   75 2.277269
## 76   76 2.277881
## 77   77 2.278501
## 78   78 2.279126
## 79   79 2.279761
## 80   80 2.280399
## 81   81 2.281027
## 82   82 2.281658
## 83   83 2.282290
## 84   84 2.282916
## 85   85 2.283552
## 86   86 2.284209
## 87   87 2.284881
## 88   88 2.285568
## 89   89 2.286278
## 90   90 2.286998
## 91   91 2.287702
## 92   92 2.288405
## 93   93 2.289114
## 94   94 2.289810
## 95   95 2.290487
## 96   96 2.291158
## 97   97 2.291831
## 98   98 2.292500
## 99   99 2.293176
## 100 100 2.293859
# Tracer un graphique pour visualiser les résultats
library(ggplot2)

ggplot(data = data.frame(K = k_values, RMSE = rmse_results), aes(x = K, y = RMSE)) +
  geom_line() +
  geom_point() +
  labs(x = "Nombre de voisins (k)", y = "RMSE") +
  ggtitle("Évolution du RMSE en fonction de k")

# Trouver la valeur de k optimale (celle qui minimise le RMSE)
optimal_k <- k_values[which.min(rmse_results)]
cat("Le choix optimal de k est:", optimal_k, "\n")
## Le choix optimal de k est: 25

Exercice 3

Question 1

Faire une analyse descriptive de la base de données. En particulier, on traitera les données manquantes présentes dans certaines variables.
# Charger la base de données
diabetes <- read.table("diabetes.csv", sep = ",", header = TRUE)

# Vérifier les premières lignes de la base de données
head(diabetes)
##   Pregnancies Glucose BloodPressure SkinThickness Insulin  BMI
## 1           6     148            72            35       0 33.6
## 2           1      85            66            29       0 26.6
## 3           8     183            64             0       0 23.3
## 4           1      89            66            23      94 28.1
## 5           0     137            40            35     168 43.1
## 6           5     116            74             0       0 25.6
##   DiabetesPedigreeFunction Age Outcome
## 1                    0.627  50       1
## 2                    0.351  31       0
## 3                    0.672  32       1
## 4                    0.167  21       0
## 5                    2.288  33       1
## 6                    0.201  30       0
# Résumé statistique des données
summary(diabetes)
##   Pregnancies        Glucose      BloodPressure    SkinThickness  
##  Min.   : 0.000   Min.   :  0.0   Min.   :  0.00   Min.   : 0.00  
##  1st Qu.: 1.000   1st Qu.: 99.0   1st Qu.: 62.00   1st Qu.: 0.00  
##  Median : 3.000   Median :117.0   Median : 72.00   Median :23.00  
##  Mean   : 3.845   Mean   :120.9   Mean   : 69.11   Mean   :20.54  
##  3rd Qu.: 6.000   3rd Qu.:140.2   3rd Qu.: 80.00   3rd Qu.:32.00  
##  Max.   :17.000   Max.   :199.0   Max.   :122.00   Max.   :99.00  
##     Insulin           BMI        DiabetesPedigreeFunction      Age       
##  Min.   :  0.0   Min.   : 0.00   Min.   :0.0780           Min.   :21.00  
##  1st Qu.:  0.0   1st Qu.:27.30   1st Qu.:0.2437           1st Qu.:24.00  
##  Median : 30.5   Median :32.00   Median :0.3725           Median :29.00  
##  Mean   : 79.8   Mean   :31.99   Mean   :0.4719           Mean   :33.24  
##  3rd Qu.:127.2   3rd Qu.:36.60   3rd Qu.:0.6262           3rd Qu.:41.00  
##  Max.   :846.0   Max.   :67.10   Max.   :2.4200           Max.   :81.00  
##     Outcome     
##  Min.   :0.000  
##  1st Qu.:0.000  
##  Median :0.000  
##  Mean   :0.349  
##  3rd Qu.:1.000  
##  Max.   :1.000
# Vérifier les valeurs manquantes
sapply(diabetes, function(x) sum(is.na(x)))
##              Pregnancies                  Glucose            BloodPressure 
##                        0                        0                        0 
##            SkinThickness                  Insulin                      BMI 
##                        0                        0                        0 
## DiabetesPedigreeFunction                      Age                  Outcome 
##                        0                        0                        0

Question 2

A l’aide de l’algorithme des 3 plus proches voisins, classifier le risque d’être diabétique. Pour cela, on construira une base de données d’apprentissage sur laquelle on entraînera l’algorithme et on évaluera le taux de mauvaise classification sur la base de données test.
# Diviser la base de données en ensemble d'apprentissage (70%) et ensemble de test (30%)
set.seed(123)  # Pour reproduire les résultats
index <- sample(1:nrow(diabetes), 0.7 * nrow(diabetes))
train_data <- diabetes[index, ]
test_data <- diabetes[-index, ]

# Charger la bibliothèque 'class' pour l'algorithme des k-NN
library(class)

# Entraîner le modèle des 3 plus proches voisins
k <- 3
predicted <- knn(train = train_data[, -9], test = test_data[, -9], cl = train_data[, 9], k = k)

# Évaluer le taux de mauvaise classification
error_rate <- sum(predicted != test_data[, 9]) / length(predicted)
error_rate
## [1] 0.2813853

Question 3

Écrire un code permettant d’évaluer le risque de classification de l’algorithme des k plus proches voisins pour différentes valeurs de k. Discuter d’un choix de k optimal.
# Initialiser un vecteur pour stocker les taux d'erreur
error_rates <- numeric(0)

# Créer une séquence de valeurs de k (par exemple, de 1 à 20)
k_values <- 1:20

# Boucle pour calculer les taux d'erreur pour différentes valeurs de k
for (k in k_values) {
  predicted <- knn(train = train_data[, -9], test = test_data[, -9], cl = train_data[, 9], k = k)
  error_rate <- sum(predicted != test_data[, 9]) / length(predicted)
  error_rates <- c(error_rates, error_rate)
}

# Trouver la valeur de k avec le taux d'erreur le plus bas
optimal_k <- k_values[which.min(error_rates)]
optimal_k
## [1] 17