🏆 Solutions#
Nous vous fournissons des axes de réponses aux différents challenges proposés en fin d'atelier. Il est fortement conseillé d'essayer par vous-même avant de regarder les réponses proposées ci-dessous ! Dans tous les cas, il est possible de trouver d'autres réponses concluant à des résultats similaires.
⁉️ Niveau 1 : Questions#
Propositions de réponses aux questions, sous la forme de requêtes SQL. D'autres réponses sont possibles, d'ailleurs cela constitue un excellent entraînement aux requêtes SQL !
-
Combien d'appartements ont été vendus à Grenoble en 2022 ?
select count(*) as ventes from dvf where nature_mutation = 'Vente' and type_local = 'Appartement' and nom_commune = 'Grenoble' and strftime('%Y', date_mutation) = '2022'
-
Combien de DVF par année ont été enregistrées depuis 2018 ?
select strftime('%Y', date_mutation) as annee, count(*) as ventes from dvf group by annee order by annee asc
-
Quelle est la tendance de ventes de maisons depuis 2018 ?
select strftime('%Y', date_mutation) as annee, count(*) as ventes from dvf where type_local = 'Maison' and nature_mutation = 'Vente' group by annee order by annee asc
-
Quelles sont les villes avec le plus de maisons vendues en Isère en 2022 ?
select nom_commune, count(*) as ventes from dvf where type_local = 'Maison' and strftime('%Y', date_mutation) = '2022' group by nom_commune order by ventes desc
-
Quel est le prix de vente moyen au mètre carré des appartements en Isère en 2022 ?
select cast( avg(valeur_fonciere / surface_reelle_bati) as int ) as prix_metre_carre from dvf where nature_mutation = 'Vente' and type_local = 'Appartement' and strftime('%Y', date_mutation) = '2022'
-
Quelles sont les 10 rues de Grenoble où le prix de vente moyen au mètre carré des appartements est le plus faible en 2021 ?
select adresse_nom_voie, cast( avg(valeur_fonciere / surface_reelle_bati) as int ) as prix_metre_carre, avg(latitude) as latitude, avg(longitude) as longitude from dvf where nature_mutation = 'Vente' and type_local = 'Appartement' and strftime('%Y', date_mutation) = '2021' and nom_commune = 'Grenoble' group by adresse_nom_voie order by prix_metre_carre asc limit 10
-
Quelles sont les 20 villes avec le plus haut prix de vente moyen au mètre carré des appartements en 2022, ayant comptabilisé au moins 10 ventes ?
select nom_commune, count(*) as ventes, cast( avg(valeur_fonciere / surface_reelle_bati) as int ) as prix_metre_carre from dvf where nature_mutation = 'Vente' and type_local = 'Appartement' and strftime('%Y', date_mutation) = '2022' group by nom_commune having ventes > 10 order by prix_metre_carre desc limit 20
-
Quelles sont les 20 villes avec le plus bas prix de vente moyen au mètre carré des appartements en 2022, ayant comptabilisé au moins 10 ventes ?
select nom_commune, count(*) as ventes, cast( avg(valeur_fonciere / surface_reelle_bati) as int ) as prix_metre_carre from dvf where nature_mutation = 'Vente' and type_local = 'Appartement' and strftime('%Y', date_mutation) = '2022' group by nom_commune having ventes > 10 order by prix_metre_carre asc limit 20
-
Quelle est la tendance d'évolution du prix de vente moyen au mètre carré des studios à Grenoble, Gières, Saint-Martin-d'Hères, Echirolles, Meylan et la Tronche depuis 2018 ?
select strftime('%Y', date_mutation) as annee, nom_commune, cast( avg(valeur_fonciere / surface_reelle_bati) as int ) as prix_metre_carre from dvf where nature_mutation = 'Vente' and type_local = 'Appartement' and nom_commune in ( 'Grenoble', 'Gières', 'Saint-Martin-d''Hères', 'Echirolles', 'Meylan', 'La Tronche' ) and nombre_pieces_principales = 1 group by annee, nom_commune order by annee, nom_commune asc
-
Quelles sont les villes où aucune transaction immobilière n'a été enregistrée en 2022 ?
with dvf_2022 as ( select * from dvf where strftime('%Y', dvf.date_mutation) = '2022' ) select communes.nom as commune from communes left outer join dvf_2022 on dvf_2022.code_commune = communes.code group by commune having count(dvf_2022.id_mutation) = 0 order by commune
🎨 Niveau 2 : Tableau de bord#
Au préablable, installer le plugin datasette-dashboards
:
datasette install datasette-dashboards
Activer le plugin et déclarer un tableau de bord dans le fichier metadata.yml
:
plugins:
datasette-dashboards:
immobilier:
title: Tableau de bord immobilier
description: Métriques des transactions immobilières de l'Isère
layout: []
filters: {}
charts: {}
Ajouter les filtres demandés :
plugins:
datasette-dashboards:
immobilier:
...
filters:
date_depart:
name: Date de départ
type: date
date_fin:
name: Date de fin
type: date
commune:
name: Commune
type: select
db: immobilier
query: SELECT distinct nom_commune FROM dvf ORDER BY nom_commune ASC
On peut désormais ajouter nos graphiques avec les conditions de filtrage (syntaxe [[ condition ]]
, référence à la valeur du filtre par :nom_filtre
).
"Le nombre total de transactions immobilières" :
plugins:
datasette-dashboards:
immobilier:
...
layout:
- [total-transactions]
...
charts:
total-transactions:
title: Nombre total de transactions immobilières
db: immobilier
query: >-
SELECT count(*) AS transactions
FROM dvf
WHERE TRUE
[[ AND date(date_mutation) >= date(:date_depart) ]]
[[ AND date(date_mutation) <= date(:date_fin) ]]
[[ AND nom_commune = :commune ]]
"Le nombre total de ventes de maisons" :
plugins:
datasette-dashboards:
immobilier:
...
layout:
- [total-transactions, total-ventes-maisons]
...
charts:
...
total-ventes-maisons:
title: Nombre total de ventes de maisons
db: immobilier
query: >-
SELECT count(*) AS maisons
FROM dvf
WHERE
nature_mutation = 'Vente'
AND type_local = 'Maison'
[[ AND date(date_mutation) >= date(:date_depart) ]]
[[ AND date(date_mutation) <= date(:date_fin) ]]
[[ AND nom_commune = :commune ]]
library: metric
display:
field: maisons
"Le nombre total de ventes d'appartements" :
plugins:
datasette-dashboards:
immobilier:
...
layout:
- [total-transactions, total-ventes-maisons, total-ventes-appartements]
...
charts:
...
total-ventes-appartements:
title: Nombre total de ventes d'appartements
db: immobilier
query: >-
SELECT count(*) AS appartements
FROM dvf
WHERE
nature_mutation = 'Vente'
AND type_local = 'Appartement'
[[ AND date(date_mutation) >= date(:date_depart) ]]
[[ AND date(date_mutation) <= date(:date_fin) ]]
[[ AND nom_commune = :commune ]]
library: metric
display:
field: appartements
"L'évolution du nombre de transactions mois par mois" :
plugins:
datasette-dashboards:
immobilier:
...
layout:
- [total-transactions, total-ventes-maisons, total-ventes-appartements]
- [transactions-mois, transactions-mois, transactions-mois]
...
charts:
...
transactions-mois:
title: Evolution du nombre de transactions mois par mois
db: immobilier
query: >-
SELECT
date(date_mutation, 'start of month') as month,
count(*) as transactions
FROM dvf
WHERE TRUE
[[ AND date(date_mutation) >= date(:date_depart) ]]
[[ AND date(date_mutation) <= date(:date_fin) ]]
[[ AND nom_commune = :commune ]]
GROUP BY month
ORDER BY month
library: vega-lite
display:
mark: { type: line, tooltip: true }
encoding:
x: { field: month, type: temporal, timeUnit: yearmonth }
y: { field: transactions, type: quantitative }
"Une carte choroplèthe du volume de transactions par commune" :
plugins:
datasette-dashboards:
immobilier:
...
layout:
- [total-transactions, total-ventes-maisons, total-ventes-appartements]
- [transactions-mois, transactions-mois, transactions-commune]
...
charts:
...
transactions-commune:
title: Volume de transactions par commune
db: immobilier
query: >-
WITH dvf_stats AS (
SELECT code_commune, nom_commune, count(*) AS transactions
FROM dvf
WHERE TRUE
[[ AND date(date_mutation) >= date(:date_depart) ]]
[[ AND date(date_mutation) <= date(:date_fin) ]]
[[ AND nom_commune = :commune ]]
GROUP BY code_commune, nom_commune
ORDER BY code_commune, nom_commune
)
SELECT
communes.nom AS commune,
coalesce(dvf_stats.transactions, 0) AS transactions
FROM
communes
LEFT OUTER JOIN dvf_stats ON dvf_stats.code_commune = communes.code
library: vega-lite
display:
mark: geoshape
projection: { type: mercator }
transform:
- lookup: commune
from:
data:
url: https://raw.githubusercontent.com/gregoiredavid/france-geojson/master/departements/38-isere/communes-38-isere.geojson
format: { type: json, property: features }
key: properties.nom
fields: [type, geometry]
encoding:
fill:
field: transactions
type: quantitative
scale: { scheme: blues }
stroke: { value: white }
tooltip:
- { field: commune, type: nominal }
- { field: transactions, type: quantitative }
🔮 Niveau 3 : Prédictions#
Au préalable, installer le plugin datasette-ml
:
datasette install datasette-ml
Avant de commencer à entraîner un modèle, il est nécessaire de préparer le jeu de données. Nous allons créer une vue SQL pour :
- Filtrer les données sur les ventes d'appartements à Grenoble en 2021
- Sélectionner les caractéristiques utiles : surface réelle, nombre de pièces principales, latitude, longitude
- Sélectionner la colonne cible : valeur foncière
- Transformer les caractéristiques en valeurs réelles flottantes
Dans un terminal, ouvrir la base SQLite avec l'interpréteur en ligne de commande :
sqlite3 data/immobilier.db
Puis entrer la requête SQL suivante :
CREATE VIEW appartements_grenoble_2021 AS
SELECT
CAST(surface_reelle_bati AS REAL) AS surface,
CAST(nombre_pieces_principales AS REAL) AS pieces,
CAST(latitude AS REAL) as latitude,
CAST(longitude AS REAL) as longitude,
CAST(valeur_fonciere AS REAL) AS valeur
FROM dvf
WHERE
nature_mutation = 'Vente'
AND type_local = 'Appartement'
AND nom_commune = 'Grenoble'
AND date_mutation >= '2021-01-01'
AND date_mutation <= '2021-12-31'
AND latitude != ''
AND longitude != ''
;
Fermer l'interpréteur :
.quit
Configurer le plugin datasette-ml
dans le fichier metadata.yml
:
plugins:
datasette-ml:
db: immobilier
Redémarrer Datasette et passons à l'entraînement d'un modèle de régression à partir de la vue créée, le tout directement via des requêtes SQL :
SELECT sqml_train(
'Prediction appartements Grenoble',
'regression',
'linear_regression',
'appartements_grenoble_2021',
'valeur'
) AS training;
Nous pouvons désormais effectuer des prédictions de valeur foncière pour les appartements à Grenoble !
Par exemple, pour prédire la valeur foncière d'un T3 de 50m2 place Victor Hugo :
SELECT round(
sqml_predict(
'Prediction appartements Grenoble',
json_object(
'surface', 50,
'pieces', 3,
'latitude', 45.1893525,
'longitude', 5.7216074
)
)
) AS prediction
Par exemple, pour prédire la valeur foncière d'un T4 100m2 place Victor Hugo :
SELECT round(
sqml_predict(
'Prediction appartements Grenoble',
json_object(
'surface', 100,
'pieces', 4,
'latitude', 45.1893525,
'longitude', 5.7216074
)
)
) AS prediction