Main.TutoStat History
Show minor edits - Show changes to markup
data = pkl.load(f)
data = pkl.load(f, encoding='latin1') # option encoding pour le passage py2 => py3
Distributions de probabilités
Distributions de probabilités
Tracer un histogramme
Tracer un histogramme
Calcul et tracé d'une probabilité conditionnelle
Calcul et tracé d'une probabilité conditionnelle
Tracer la population des stations
Tracer la population des stations
Récupération des données
Récupération des données
Solution 2: les API rest
Solution 2: les API rest [Pour jouer A LA MAISON]
keyG = "GGG" # facultatif
alt = requests.get(urlGoogleAPI+position+"&key="+keyG)
alt = requests.get(urlGoogleAPI+position)
time.sleep(0.2) # pour ne pas se faire bannir par Google
time.sleep(0.1) # pour ne pas se faire bannir par Google
- Les challenges Kaggle: www.kaggle.com
- Les challenges Kaggle: http://www.kaggle.com
Quel facteur est le plus lié au fait qu'(au moins) un vélo soit disponible dans une station?
Quel facteur est le plus lié au fait qu'(au moins) un vélo soit disponible dans une station?
Pour s'amuser avec d'autres données:
- Beaucoup de choses sur Paris: http://opendata.paris.fr
- Les données classique UCI: https://archive.ics.uci.edu/ml/datasets.html
- Les challenges Kaggle: www.kaggle.com
Disponibilité:
Moyenne, Médiane...
Sur différentes cartes, afficher les stations suivantes:
- stations dont l'altitude est inférieure à la moyenne (en conservant le code couleur précédent)
- stations dont l'altitude est supérieure à la médiane (en conservant le code couleur précédent)
- Calculer {$P[Vd=1|Al]$} [={$P[Vd=1|Al]*1 + P[Vd=0|Al]*0$}estimation de l'espérance conditionnelle]
- Tracer {$P[Vd=1|Al]$} [={$P[Vd=1|Al]*1 + P[Vd=0|Al]*0$}estimation de l'espérance conditionnelle]
On s'intéresse à {$P[Vd | Al]$}, c'est à dire, la probabilité d'avoir un vélo disponible en fonction de l'altitude.
On s'intéresse à {$E[P[Vd | Al]]$}, c'est à dire, la probabilité d'avoir un vélo disponible en fonction de l'altitude.
- Pour chaque altitude
- Chercher les stations concernées [=réduction de l'univers pour les probas conditionnelles]
- Calculer la moyenne des Vd [=estimation de l'espérance conditionnelle]
- Construire la table à 2 lignes et 30 colonnes de {$P[Vd | Al]$} en cherchant pour chaque altitude:
- Chercher les stations concernées [=réduction de l'univers pour les probas conditionnelles]
- Calculer la fréquence de Vd=1
- Calculer la fréquence de Vd=0
- Calculer {$P[Vd=1|Al]$} [={$P[Vd=1|Al]*1 + P[Vd=0|Al]*0$}estimation de l'espérance conditionnelle]
- Construire la table à 2 lignes et 30 colonnes de {$P[Vd | Al]$} en cherchant pour chaque altitude:
Quel facteur est le plus lié au fait qu'(au moins) un vélo soit disponible dans une station?
Quel facteur est le plus lié au fait qu'(au moins) un vélo soit disponible dans une station?
- Au moins 3 vélos disponibles (variable binaire) (Vd) [comme il y a souvent des vélos en panne, on considère qu'il faut 3 vélos dans une stations pour être sûr de pouvoir en prendre un.]
- Au moins 2 vélos disponibles (variable binaire) (Vd) [comme il y a souvent des vélos en panne, on considère qu'il faut 2 vélos dans une stations pour être sûr de pouvoir en prendre un.]
Tracer la population des stations
Sanity check: affichage des arrondissements pour vérifier que tout est OK:
Calcul et tracé d'une probabilité conditionnelle
On s'intéresse à {$P[Vd | Al]$}, c'est à dire, la probabilité d'avoir un vélo disponible en fonction de l'altitude. Voici les étapes à respecter
- calculer pour toutes les stations
- Vd = 1 si au moins 2 vélos dispos, Vd = 0 sinon
- Al = [0,...,29] catégorie d'altitude (cf aide ci-dessous pour ce calcul)
- Pour chaque altitude
- Chercher les stations concernées [=réduction de l'univers pour les probas conditionnelles]
- Calculer la moyenne des Vd [=estimation de l'espérance conditionnelle]
- retrouver les catégories
- première colonne de station = altitude
- intervalle = largeur d'un intervalle
catAlt = np.floor((stations[:,1]-stations[:,1].min()) / intervalle)
- le début du code suivant peut-être
pDispoSAlt = np.zeros(np.unique(catAlt).shape[0]) for a in np.unique(catAlt): # fonction pratique pour isoler les valeurs uniques
[...]
(:sourceend:)
Tracer la population des stations
Sanity check: affichage des arrondissements pour vérifier que tout est OK:
(:source lang=python:)
Tests de corrélation
- Calculer les corrélations entre les variables Altitude et Vélo disponible
- Calculer les corrélations entre les variables Arrondissement et Vélo disponible
Quel facteur est le plus lié au fait qu'(au moins) un vélo soit disponible dans une station?
Tout est OK, on peut passer à l'exercice!
Sanity check: affichage des arrondissements pour vérifier que tout est OK:
(:source lang=python:) x1 = stations[:,3] # recuperation des coordonnées x2 = stations[:,2]
- définition de tous les styles (pour distinguer les arrondissements)
style = [(s,c) for s in "o^+*" for c in "byrmck" ]
- tracé de la figure
plt.figure() for i in range(1,21):
ind, = np.where(stations[:,0]==i) # scatter c'est plus joli pour ce type d'affichage plt.scatter(x1[ind],x2[ind],marker=style[i-1][0],c=style[i-1][1],linewidths=0)
plt.axis('equal') # astuce pour que les axes aient les mêmes espacements plt.legend(range(1,21), fontsize=10) plt.savefig("carteArrondissements.pdf") (:sourceend:)
Afin de réviser les usages de np.where
Utiliser la méthode scatter.
Tracer la population des stations
Projeter les stations sur la carte en mettant en:
- rouge les stations pleines,
- jaune les vides,
- verte les autres.
Utiliser la méthode scatter.
Tracer l'histogramme correspondant à la distribution {$P[Al]$}
Tracer l'histogramme correspondant à la distribution {$P[Al]$}.
Attention: pour faire un tracé correct, il faut que l'aire de l'histogramme somme à 1. Il est donc nécessaire de réfléchir à la hauteur et largeur des différentes barres.
(:source lang=python:)
- stocker les altitudes + définir la largeur des intervalles:
alt = res[1] intervalle = alt[1]-alt[0]
- définir la fréquence de répartition de la population dans les intervalles
pAlt = res[0]/res[0].sum()
- puis diviser la fréquence par la base de l'intervalle pour que ça somme à 1
pAlt /= intervalle [...] # créer une figure plt.bar((alt[1:]+alt[:-1])/2,pAlt, alt[1]-alt[0])
- NB: dans bar, on donne: abscisse, ordonnées, largeur des barres
(:sourceend:)
Questions
Distributions de probabilités
Distributions de probabilités
(:source lang=python:) nItervalles = 30 res = plt.hist(altitudes, nIntervalles) print res[0] # effectif dans les intervalles print res[1] # definition des intervalles (ATTENTION: 31 valeurs) (:sourceend:)
- {$P[Vd | Ar]$}
- {$P[Vd | Ar]$}
Tracer un histogramme
Tracer l'histogramme correspondant à la distribution {$P[Al]$}
Mise en forme:
Mise en forme et élimination du bruit
fname = "nomDeFichier.pkl" f= open(fname,'rb') data = pkl.load(f) f.close()
(:source lang=python:)
(:sourceend:)
f.close()
Réflexe pickle: chaque fois que vous avez effectué des opérations coûteuses, penser à sauver le résultat! Le module pickle offre la possibilité de le faire en très peu de ligne! (:source lang=python:) f= open('coordVelib.pkl','wb') pkl.dump(data,f) # penser à sauver les données pour éviter de refaire les opérations f.close() (:sourceend:)
Le fichier suivant regroupe les informations sur les stations velib au 11/09/2014 à 16h enrichi avec les altitudes (API Google)
Le fichier suivant regroupe les informations sur les stations Vélib enrichies avec les altitudes (API Google)
Quelques exercices sur des données réelles
Velib
Quelques exercices sur des données réelles (Vélib)
Nous faisons l'hypothèse que les étudiants ont les connaissances de base en numpy
et matplotlib
. Dans le cas contraire, se référer au premier tutoriel lien
keyG = "GGG"
keyG = "GGG" # facultatif
assert(alt.json()['status'] == "OK")
assert(alt.json()['status'] == "OK") # verification de la réussite
f= open('coordVelib.pkl','w')
f= open('coordVelib.pkl','wb')
Mise en forme:
Les données ne sont pas toutes correctes (comme la plupart des données réelles). Nous souhaitons aussi les mettre en forme dans un tableau.
- Faire défiler les stations
- Extraire l'arrondissement [Champ 'number' / 1000 en division entière] et vérifier qu'il est compris entre 1 et 20
- Eliminer les autres stations
- Définir une matrice du bon nombre de lignes avec les colonnes contenant: 3 coordonnées géographiques, Arrondissement, Places totales, Places dispo.
- Arrondissement (Ar) [Premiers chiffres du champ 'number'
- Arrondissement (Ar)
urlG = "http://maps.googleapis.com/maps/api/elevation/json?locations="
urlGoogleAPI = "https://maps.googleapis.com/maps/api/elevation/json?locations=" keyG = "GGG"
alt = requests.get(urlGoogleAPI+position)
alt = requests.get(urlGoogleAPI+position+"&key="+keyG) assert(alt.json()['status'] == "OK")
- {$P{Vd | Al]$}
- {$P{Vd | Ar]$}
- {$P[Vd | Al]$}
- {$P[Vd | Ar]$}
- Places totales (Ps)
- Places dispo (Pd)
- Borne pleine (Bp)
- Station pleine (Sp) [variable binaire: valeur 1 si la station est pleine]
- {$P[Sp | Al]$}
- {$P{Vd | Al]$}
- {$P{Vd | Ar]$}
Dans notre population, les individus sont des stations, qui ont différents caractères.
- Borne pleine (Bp)
- Au moins 3 vélos disponibles (variable binaire) (Vd) [comme il y a souvent des vélos en panne, on considère qu'il faut 3 vélos dans une stations pour être sûr de pouvoir en prendre un.]
{$P$}
- {$P[Ar]$}
- {$P[Al]$} nous utiliserons une discrétisation de l'altitude en 100 intervalles de mêmes tailles
Questions
Distributions de probabilités
Nous allons étudier les variables aléatoires suivantes:
- Arrondissement (Ar) [Premiers chiffres du champ 'number'
- Altitude (Al)
- Places totales (Ps)
- Places dispo (Pd)
Construire les matrices suivantes: {$P$}
- 'status': u'OPEN'}
- 'status': u'OPEN'}
Pour faire défiler les stations dans la structure data
:
(:source lang=python:)
for station in data:
...
(:sourceend:)
Pour accéder à un champ d'une station: (:source lang=python:) for station in data:
nbVeloDispo = station['available_bikes'] ...
(:sourceend:)
(:sourceend:)
(:sourceend:)
Structure des données
Les données sont dans une liste de dictionnaire (ie chaque station est un dictionnaire python). Les champs du dictionnaire sont:
- 'address': u"57 RUE DU CHATEAU D'EAU - 75010 PARIS",
- 'alt': 35.79555130004883,
- 'available_bike_stands': 2,
- 'available_bikes': 17,
- 'banking': True,
- 'bike_stands': 19,
- 'bonus': False,
- 'contract_name': u'Paris',
- 'last_update': 1410442143000,
- 'name': u"10007 - CHATEAU D'EAU",
- 'number': 10007,
- 'position': {u'lat': 48.87242997325711, u'lng': 2.355489390173873},
- 'status': u'OPEN'}
pkl.dump(data,f)(:sourceend:)
pkl.dump(data,f) # penser à sauver les données pour éviter de refaire les opérations (:sourceend:)
import requests import pickle as pkl import time
pkl.dump(data,f)(:sourceend:)
pkl.dump(data,f)(:sourceend:)
(:sourceend:)
(:sourceend:)
- enrichissement avec l'altitude à partir de l'API Google:
(:source lang=python:) urlG = "http://maps.googleapis.com/maps/api/elevation/json?locations=" for s in data:
position = "f"%(s['position']['lat'],s['position']['lng'])
alt = requests.get(urlGoogleAPI+position)
s[u'alt'] = alt.json()['results'][0]['elevation'] # enrichissement
time.sleep(0.2) # pour ne pas se faire bannir par Google
f= open('coordVelib.pkl','w') pkl.dump(data,f)(:sourceend:)
Solution 1: télécharger un fichier
Le fichier suivant regroupe les informations sur les stations velib au 11/09/2014 à 16h enrichi avec les altitudes (API Google) dataVelib.pkl
Solution 2: les API rest
Récupération des données
- récupération d'une clé
- récupération d'une clé (XXX)
- Début du code:
(:source lang=python:) url = "https://api.jcdecaux.com/vls/v1/stations?contract=Paris&apiKey=XXX" dataStation = requests.get(url) data = dataStation.json() (:sourceend:)
- première étape: récupération des données, création d'un compte sur: https://developer.jcdecaux.com/#/signup
- première étape: récupération des données, création d'un compte sur: https://developer.jcdecaux.com/#/signup
- récupération d'une clé
Quelques exercices sur des données réelles
Velib
Nous proposons de tracer quelques courbes de probabilité sur des données velib récupérée directement sur le web.
- première étape: récupération des données, création d'un compte sur: https://developer.jcdecaux.com/#/signup