forked from becodeorg/becodeorg-classroom-thomas5-immo-eliza-machine-learning-ai-track-immo-eliza-ml
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_code_data_cleaning
More file actions
156 lines (118 loc) · 6.17 KB
/
Copy pathtest_code_data_cleaning
File metadata and controls
156 lines (118 loc) · 6.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import zscore
# from sklearn.impute import KNNImputer
# def clean_data(df):
# # Drop columns: 'id', 'url' and 25 other columns
# df = df.drop(columns=['id', 'url', 'province', 'monthlyCost', 'hasAttic', 'hasBasement', 'hasDressingRoom', 'diningRoomSurface', 'hasDiningRoom', 'roomCount', 'streetFacadeWidth', 'hasLift', 'hasHeatPump', 'hasPhotovoltaicPanels', 'hasThermicPanels', 'kitchenSurface', 'hasLivingRoom', 'livingRoomSurface', 'hasBalcony', 'gardenOrientation', 'hasAirConditioning', 'hasArmoredDoor', 'hasVisiophone', 'hasOffice', 'terraceOrientation', 'accessibleDisabledPeople', 'Unnamed: 0'])
# # Drop 'APARTMENT_GROUP' and 'HOUSE_GROUPR values in type column
# df = df[~df['type'].isin(['APARTMENT_GROUP', 'HOUSE_GROUP'])]
# # Drop 'APARTMENT_BLOCK' in subtype column
# df = df[~df['subtype'].isin(['APARTMENT_BLOCK'])]
# return df
# Loaded variable 'df'
df = pd.read_csv('./data/Kangaroo.csv')
# # # df_clean = clean_data(df.copy())
# # # df_clean.head()
# # # Select column: 'bathroomCount'
# # mode_bedrooms = df['bathroomCount'].mode()[0]
# # print(mode_bedrooms)
# # # Median of bed rooms by type
# # median_by_type = df.groupby('type')['bathroomCount'].median()
# # print("Médianes par type de bien:", median_by_type)
# # print(df.shape)
# df = df.drop(columns=['id', 'url', 'province', 'monthlyCost', 'hasAttic', 'hasBasement', 'hasDressingRoom', 'diningRoomSurface', 'hasDiningRoom', 'roomCount', 'streetFacadeWidth', 'hasLift', 'hasHeatPump', 'hasPhotovoltaicPanels', 'hasThermicPanels', 'kitchenSurface', 'hasLivingRoom', 'livingRoomSurface', 'hasBalcony', 'gardenOrientation', 'hasAirConditioning', 'hasArmoredDoor', 'hasVisiophone', 'hasOffice', 'terraceOrientation', 'accessibleDisabledPeople', 'Unnamed: 0'])
# # 1. Calculer la médiane du nombre de chambres par sous-type
# # (avant toute imputation)
# median_by_subtype = df.groupby('subtype')['bathroomCount'].median()
# print("Médianes par type de bien:")
# print(median_by_subtype)
# # 2. Pour chaque sous-type, remplacer les valeurs manquantes par la médiane correspondante
# for subtype in df['subtype'].unique():
# # Créer un masque qui identifie les lignes où:
# # - Le sous-type correspond à celui qu'on traite actuellement
# # - ET la valeur de bathroomCount est manquante
# mask = (df['subtype'] == subtype) & (df['bathroomCount'].isna())
# # Remplacer ces valeurs par la médiane du sous-type
# df.loc[mask, 'bathroomCount'] = median_by_subtype[subtype]
# # 3. Vérifier s'il reste des valeurs manquantes
# remaining_missing = df['bathroomCount'].isna().sum()
# print(f"Valeurs manquantes restantes: {remaining_missing}")
# # 4. Si certains sous-types n'ont pas de médiane (tous NaN),
# # utiliser la médiane globale pour les valeurs encore manquantes
# if remaining_missing > 0:
# global_median = df['bathroomCount'].dropna().median()
# df['bathroomCount'].fillna(global_median, inplace=True)
# print(f"Médiane globale utilisée pour les cas restants: {global_median}")
# # Change column type to int64 for column: 'buildingConstructionYear'
# df = df.astype({'buildingConstructionYear': 'Int64'})
# # Vérification
# print(f"Type: {df['buildingConstructionYear'].dtype}")
# print(f"Valeurs manquantes: {df['buildingConstructionYear'].isna().sum()}")
# # 1. Convertir en Int64 pour supporter les valeurs manquantes
# df['buildingConstructionYear'] = df['buildingConstructionYear'].astype('Int64')
# # 2. Corriger les années futures (tout ce qui dépasse 2023)
# current_year = 2025
# df.loc[df['buildingConstructionYear'] > current_year, 'buildingConstructionYear'] = pd.NA
# # 3. Vérifier le résultat
# print(f"Valeurs manquantes après correction: {df['buildingConstructionYear'].isna().sum()}")
# #print unique value of epcScore column
# print(df['epcScore'].unique())
# print(df.columns)
#Datavisualization for outliers
plt.figure(figsize=(12,6))
sns.boxplot(x=df['habitableSurface'], color='skyblue')
plt.title('habitableSurface ', fontsize=16)
plt.xlabel('habitableSurface', fontsize=14)
plt.show()
# p90 and p95
percentiles = df['habitableSurface'].quantile([0.10, 0.90, 0.95])
p90 = percentiles.loc[0.90]
p95 = percentiles.loc[0.95]
p10 = percentiles.loc[0.10]
print(f"90ᵉ percentile : {p90:.0f} ")
print(f"95ᵉ percentile : {p95:.0f} ")
print(f"10ᵉ percentile : {p10:.0f} ")
n_above_p90 = (df['habitableSurface'] > p90).sum()
n_above_p95 = (df['habitableSurface'] > p95).sum()
n_below_p10 = (df['habitableSurface'] < p10).sum()
total = len(df)
print(f"Biens > p90 : {n_above_p90} soit {n_above_p90/total:.2%}")
print(f"Biens > p95 : {n_above_p95} soit {n_above_p95/total:.2%}")
print(f"Biens < p10 : {n_below_p10} soit {n_below_p10/total:.2%}")
# # 1. Affiche toutes les colonnes si besoin
# pd.set_option('display.max_columns', None)
# pd.set_option('display.width', 1200)
# # 2. Définis les colonnes à voir
# cols = ['bathroomCount', 'price', 'locality', 'postCode', 'subtype']
# # 3. Sample et affiche
# small_sample = df[df['bathroomCount'] > 10][cols].sample(10)
# print(small_sample)
# # 1) Nombre total de biens avant nettoyage
# initial_count = len(df)
# print(f"Nombre de lignes avant drop : {initial_count}")
# # 2) On filtre et on crée une nouvelle DataFrame
# df_clean = df[df['bathroomCount'] <= 3].copy()
# # 3) Nombre de biens supprimés et pourcentage
# removed = initial_count - len(df_clean)
# pct = removed / initial_count * 100
# print(f"Biens supprimés (>7 chambres) : {removed} soit {pct:.2f}% du dataset")
# # 4) Réinitialiser l’index (optionnel mais conseillé)
# df_clean.reset_index(drop=True, inplace=True)
# # 5) Remplacer l’ancien df si tu veux travailler sur df_clean
# df = df_clean
#bedroomCount
# 1) On retire d’abord les NaN pour le calcul des stats
ls = df['bedroomCount'].dropna()
# 2) On calcule les statistiques
stats = ls.describe(percentiles=[.1, .25, .5, .75, .9, .95])
print(stats)
plt.hist(ls, bins=50, edgecolor='k')
plt.xlim(0, 5000) # pour te concentrer sur 99% des données
plt.xlabel('Surface du terrain (m²)')
plt.ylabel('Nombre de biens')
plt.title('Distribution de bedroomCount')
plt.show()