"c:\\Users\\samys\\OneDrive\\Bureau\\last_test\\projet-python-m2-ds-2024\\src\\data_processing\\preprocessing.py:30: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n",
"c:\\Users\\samys\\OneDrive\\Bureau\\verylasttest\\projet-python-m2-ds-2024\\src\\data_processing\\preprocessing.py:30: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n",
" data=data.replace({'yes': 1, 'no': 0})\n"
]
}
...
...
@@ -281,7 +270,7 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 149,
"metadata": {},
"outputs": [],
"source": [
...
...
@@ -297,7 +286,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 150,
"metadata": {},
"outputs": [
{
...
...
@@ -329,7 +318,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 151,
"metadata": {},
"outputs": [],
"source": [
...
...
@@ -346,7 +335,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 152,
"metadata": {},
"outputs": [
{
...
...
@@ -477,29 +466,17 @@
"</div>"
],
"text/plain": [
" price area bedrooms bathrooms stories mainroad guestroom \\\n",
"# on réalise une boucle sur différentes tailles de l'ensemble d'entrainement\n",
...
...
@@ -780,15 +744,14 @@
" #calcul de la prédiction\n",
" y_pred=lin_reg.predict(X_test)\n",
" \n",
" # calcul de l'erreur R2\n",
" error_mse=np.mean((y_test-y_pred)**2)\n",
" print(r2_score(y_test,y_pred))\n",
" # calcul du MSE\n",
" error_mse=mean_squared_error(y_test,y_pred)\n",
" list_error.append(error_mse)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 161,
"metadata": {},
"outputs": [
{
...
...
@@ -819,7 +782,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"L'ajout de données améliore la performance du modèle cependant on constate une très faible amélioration du score à partir de n=100, mais qui est très forte entre n=10 et n=100"
"L'ajout de données améliore la performance du modèle cependant on constate une très faible amélioration du score à partir de n=100, mais qui est très forte entre n=10 et n=100, cet exemple met en évidence l'importance de la taille de l'ensemble d'entrainement pour avoir de meilleurs résultats."
"</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>RandomForestRegressor(max_depth=15, n_estimators=50, random_state=42)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\"> RandomForestRegressor<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.ensemble.RandomForestRegressor.html\">?<span>Documentation for RandomForestRegressor</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>RandomForestRegressor(max_depth=15, n_estimators=50, random_state=42)</pre></div> </div></div></div></div>"
"</style><div id=\"sk-container-id-5\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>RandomForestRegressor(max_depth=15, n_estimators=50, random_state=42)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-5\" type=\"checkbox\" checked><label for=\"sk-estimator-id-5\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\"> RandomForestRegressor<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.ensemble.RandomForestRegressor.html\">?<span>Documentation for RandomForestRegressor</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>RandomForestRegressor(max_depth=15, n_estimators=50, random_state=42)</pre></div> </div></div></div></div>"
"print(\"Score R2 sur l'ensemble de test :\", r2_test_grid)"
"print(\"Score MSE sur l'ensemble de test :\", mse_test_grid)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"On constate qu'on a pas les memes meilleurs hyperparamètres entre GridSearchCV et RandomSearchCV, et on obtient une meilleure MSE avec GridSearchCV sur l'ensemble de test ce qui est prévisible car GridSearchCV explore toutes les combinaisons d'hyperparamètres possibles contrairement à RandomSearchCV."
"On constate qu'on a pas les memes hyperparamètres optimaux entre GridSearchCV et RandomSearchCV ce qui est normal, et on obtient une meilleure MSE avec RandomSearchCV sur l'ensemble de test, ce qui est possible car les meilleurs hyperparamètres sur l'ensemble d'entrainement ne sont pas forcément meilleurs sur l'ensemble de test"
]
}
],
...
...
%% Cell type:markdown id: tags:
<center>
<h1 style="color:green">
<b>
<u> PROJECT </u>
</b>
</h1>
</center>
%% Cell type:code id: tags:
``` python
import pandas as pd
import missingno as msno
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from src.data_processing.load_data import load_data
from src.data_processing.preprocessing import rename_data
from src.data_processing.preprocessing import cat_to_quant
from src.data_processing.preprocessing import delete_feature
from src.data_processing.preprocessing import encode_and_bind
from src.data_processing.preprocessing import impute_mean
from src.figures.figures import plot_area_price_relationship, plot_correlation_matrix, plot_air_conditioning_presence, plot_bedrooms_distribution, plot_price_distribution
from src.data_science.data import split_data
from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import GridSearchCV
from config.config import TEST_RATIO, SEED, SIZE_TRAIN
```
%% Cell type:code id: tags:
``` python
print(TEST_RATIO, SEED)
```
%% Output
0.2 5
%% Cell type:markdown id: tags:
# EDA
%% Cell type:markdown id: tags:
## Chargement et prétraitement des données
%% Cell type:code id: tags:
``` python
df = load_data('data/raw/house_prices.csv')
```
%% Cell type:code id: tags:
``` python
df.head()
```
%% Output
price AreA bedrooms BATHROOMS stories mainroad guestroom \
0 4543000.0 4990.0 4.0 2.0 2.0yes yes
1 8080940.0 7000.0 3.0 2.04.0yes no
2 8750000.0 4321.0 3.0 2.02.0yes no
3 1890000.0 1700.0 3.0 1.02.0yes no
4 12215000.0 7500.0 4.0 2.0 2.0 yes no
price AreA bedrooms ... prefarea furnishing STATUS houSeaGe
0 4543000.0 4990.0 4.0 ... yesfurnished15.0
1 8080940.0 7000.0 3.0 ...no FURNISHED11.0
2 8750000.0 4321.0 3.0 ...noFURNISHEDNaN
3 1890000.0 1700.0 3.0 ...nounfurnishedNaN
4 12215000.0 7500.0 4.0 ... yesfurnishedNaN
basement hotwaterheating air conditioning parking prefarea \
0 yes no no 0.0 yes
1 no no yes 2.0 no
2 yes yes no 2.0 no
3 no no no 0.0 no
4 yes no yes 3.0 yes
furnishing STATUS houSeaGe
0 furnished 15.0
1 FURNISHED 11.0
2 FURNISHED NaN
3 unfurnished NaN
4 furnished NaN
[5 rows x 14 columns]
%% Cell type:code id: tags:
``` python
df = rename_data(df) # On renomme correctement les noms de variable
```
%% Cell type:code id: tags:
``` python
df = cat_to_quant(df) # On transforme les données catégorielles en données quantitatives
```
%% Output
c:\Users\samys\OneDrive\Bureau\last_test\projet-python-m2-ds-2024\src\data_processing\preprocessing.py:30: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
c:\Users\samys\OneDrive\Bureau\verylasttest\projet-python-m2-ds-2024\src\data_processing\preprocessing.py:30: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
data=data.replace({'yes': 1, 'no': 0})
%% Cell type:markdown id: tags:
On transforme la variable 'furnishing_status' en variable numérique
%% Cell type:code id: tags:
``` python
df=encode_and_bind(df,'furnishing_status')
```
%% Cell type:markdown id: tags:
Visualisons les données manquantes dans le jeu de données
On décide de virer la colonne 'houseage' car elle contient quasiment exclusivement des données manquantes et d'imputer le reste des variables avec leurs moyennes respectives.
%% Cell type:code id: tags:
``` python
df = delete_feature(df,'houseage') #Suppresion de la variable 'housage'
df = impute_mean(df)
```
%% Cell type:markdown id: tags:
Voici un aperçu notre jeu de données après le prétraitement des données :
%% Cell type:code id: tags:
``` python
df.head()
```
%% Output
price area bedrooms bathrooms stories mainroad guestroom \
price area bedrooms ... prefarea furnished semi-furnished
0 4543000 4990 4 ... 1 1 0
1 8080940 7000 3 ... 0 1 0
2 8750000 4321 3 ... 0 1 0
3 1890000 1700 3 ... 0 0 0
4 12215000 7500 4 ... 1 1 0
semi-furnished
0 0
1 0
2 0
3 0
4 0
[5 rows x 14 columns]
%% Cell type:markdown id: tags:
## Exploration des données
%% Cell type:code id: tags:
``` python
# histogramme de la distribution des prix de vente
plot_price_distribution(df)
#diagramme de presence ou non de la climatisation
plot_air_conditioning_presence(df)
# Diagramme en barres pour une variable catégorielle (Nombre de chambres)
plot_bedrooms_distribution(df)
```
%% Output
%% Cell type:code id: tags:
``` python
# Scatter plot pour les relations entre variables numériques (ex. SalePrice et LotArea)
plot_area_price_relationship(df)
# Heatmap pour visualiser la corrélation entre les variables numériques
plot_correlation_matrix(df)
```
%% Output
%% Cell type:markdown id: tags:
On remarque que la plus forte corrélation est entre la variable 'price' et 'bathrooms', ce qui pouvait etre attendu etant donné qu'avoir plusieurs salles de bain est réservé aux maisons assez luxueuses, la seconde plus forte corrélation est entre la variable 'price' et 'area' ce qui est aussi prévisible.
# Affichage du graphique représentant l'erreur en fonction de la taille de l'ensemble d'entraînement
plt.plot(size_train, list_error, marker='o')
plt.xlabel("Taille de l'ensemble d'entraînement")
plt.ylabel("Erreur (MSE)")
plt.title("Erreur en fonction de la taille de l'ensemble d'entraînement")
plt.show()
```
%% Output
%% Cell type:markdown id: tags:
On voit un optimum de la taille de l'ensemble d'entrainement pourn n=648 (l'ensemble du jeu d'entrainements), on remarque aussi une que l'erreur MSE est plus grande pour n=250 et n=450 que pour n=100 et n=50, ce qui montre qu'un ensemble d'entrainement plus grand n'implique pas systématiquement de meilleures performances, meme si ici cela pourrait etre lié à la simplicité du modèle
%% Cell type:markdown id: tags:
## Entrainement d'une regression linéaire sur toutes les données
%% Cell type:code id: tags:
``` python
list_error=[]
# on réalise une boucle sur différentes tailles de l'ensemble d'entrainement
for n in size_train:
X_train_subset = X_train[:n]
y_train_subset = y_train[:n]
# entrainement du modele
lin_reg = LinearRegression()
lin_reg.fit(X_train_subset,y_train_subset)
#calcul de la prédiction
y_pred=lin_reg.predict(X_test)
# calcul de l'erreur R2
error_mse=np.mean((y_test-y_pred)**2)
print(r2_score(y_test,y_pred))
# calcul du MSE
error_mse=mean_squared_error(y_test,y_pred)
list_error.append(error_mse)
```
%% Output
-0.18908813220600074
0.49828257362511363
0.6595360217499793
0.6738827057529093
0.6710848125168165
0.6714672798459871
%% Cell type:code id: tags:
``` python
# affichage du graphique représentant l'erreur en fonction de la taille de l'ensemble d'entrainement
plt.plot(size_train, list_error, marker='o')
plt.xlabel("Taille de l'ensemble d'entraînement")
plt.ylabel("Erreur")
plt.title("Erreur en fonction de la taille de l'ensemble d'entraînement")
plt.show()
```
%% Output
%% Cell type:markdown id: tags:
L'ajout de données améliore la performance du modèle cependant on constate une très faible amélioration du score à partir de n=100, mais qui est très forte entre n=10 et n=100
L'ajout de données améliore la performance du modèle cependant on constate une très faible amélioration du score à partir de n=100, mais qui est très forte entre n=10 et n=100, cet exemple met en évidence l'importance de la taille de l'ensemble d'entrainement pour avoir de meilleurs résultats.
On voit que la meilleure MSE a lieu pour un nombre d'estimateurs à 50 et une maximum de profondeur de 15 (pour plus de profondeur ça stagne), on constate aussi qu'on a une meilleure MSE que pour la régression linéaire
Etant donné que le jeu de données a été centré réduit nous pouvons directement analysé l'importance de chaque feature par son coefficient associé. On constate donc que les coefficients les plus forts sont associés d'abord à la variable 'bathrooms' avec un coefficient associé de 0.36 puis à la variable 'area' avec un coefficient associé de 0.244, ces résultats concordent avec notre visualisation des corrélations entre variables.
Ici encore plus que pour la régression linéaire les 2 variables les plus importantes dans le modèle sont 'bathrooms' et 'area'
%% Cell type:markdown id: tags:
## Bonus: RandomizedSearchCV and GridSearchCV
%% Cell type:markdown id: tags:
GridSearchCV fait de la validation croisée sur toutes les combinaisons de paramètres qu'on lui fournit, RandomSearchCV quant à elle fait de la validation croisée avec un nombre de combinaisons spécifiées par la paramètre "n_iter" de manière aléatoire.
##### Avantages et inconvénients :
- Testant toutes les combinaisons de paramètres GridSearchCV va fournir la meilleure combinaison possible de paramètre mais est plus couteuse computationnellement que RandomSearchCV inversement RandomSearchCV ne va pas forcément sortir la combinaison optimale mais la méthode est moins couteuse, en pratique pour des modèles complexes et sur de gros jeu de données RandomSearchCV va etre plus utilisé.
Score R2 sur l'ensemble de test : 0.17383407975848472
c:\Users\samys\anaconda\envs\jpp\Lib\site-packages\numpy\ma\core.py:2881: RuntimeWarning: invalid value encountered in cast
_data = np.array(data, dtype=dtype, copy=copy,
Score MSE sur l'ensemble de test : 0.17383407975848472
%% Cell type:markdown id: tags:
On constate qu'on a pas les memes meilleurs hyperparamètres entre GridSearchCV et RandomSearchCV, et on obtient une meilleure MSE avec GridSearchCV sur l'ensemble de test ce qui est prévisible car GridSearchCV explore toutes les combinaisons d'hyperparamètres possibles contrairement à RandomSearchCV.
On constate qu'on a pas les memes hyperparamètres optimaux entre GridSearchCV et RandomSearchCV ce qui est normal, et on obtient une meilleure MSE avec RandomSearchCV sur l'ensemble de test, ce qui est possible car les meilleurs hyperparamètres sur l'ensemble d'entrainement ne sont pas forcément meilleurs sur l'ensemble de test