Data Science Hacking Basics


avec Linux, R, et Chrome

Master, Paris Est MLV

@comeetie

Trouver et enrichir des données,


Scrapping, API et Base de données en ligne

Master, Paris Est-MLV

@comeetie

Où trouver des données sur le web

Open data ?

L'open data ou donnée ouverte est une donnée numérique d'origine publique ou privée. Elle peut être notamment produite par une collectivité, un service public (éventuellement délégué) ou une entreprise. Elle est diffusée de manière structurée selon une méthode et une licence ouverte garantissant son libre accès et sa réutilisation par tous, sans restriction technique, juridique ou financière. L'ouverture des données (open data) représente à la fois un mouvement, une philosophie d'accès à l'information et une pratique de publication de données librement accessibles et exploitables. Elle s'inscrit dans une tendance qui considère l'information publique comme un bien commun dont la diffusion est d'intérêt public et général.

En Europe et dans certains pays, des directives et lois imposent aux collectivités de publier certaines données publiques sous forme numérique.

Où trouver des données sur le web

Jeux de données, déjà mis en forme

Où trouver des données sur le web

Jeux de données à mettre en forme

Scrapping

API

Scrapping

Extraire des informations spécifiques

d'une ou plusieurs pages web

en vu de constituer un jeu de données

Scrapping, le html

<!DOCTYPE html>
<head><meta charset="utf-8"></head>
<body>
<section style="padding-top:6em;text-align:center">
<h1 class="purple"> Scrapping </h1>
<h4 class="purple">Extraire des informations spécifiques</h4>
<h4 class="purple">d'une ou plusieurs pages web</h4>
<h4 class="purple">en vu de constituer un jeu de données</h4>
</section>
</body>
</html>

Scrapping, les package RCurl et XML

Request (URL Request Library)

le web en ligne de commande : get, post, https, ftp, ...
import requests
from lxml import html

LXML

requests.get(), html.fromstring(), doc.xpath() :
# parse du html
page = requests.get("http://www.leboncoin.fr/jardinage/offres/centre/").text
doc  = html.fromstring(page)
element = doc.xpath('//*[@id="ContainerMain"]/nav[2]/ul/li[1]/span[2]/b')[0]
print(element.text_content())

Scrapping, les package Request et LXML

Xpath, extraire des informations d'un arbre DOM

Syntaxe pour se promener dans l'abre dom et en extraire des partie (noeuds, attributs, ...), plus détails sur w3schools.
Expression Description
nodename Selects all nodes with the name "nodename"
/ Selects from the root node
// Selects nodes in the document from the current node that match the selection no matter where they are
. Selects the current node
.. Selects the parent of the current node
@ Selects attributes

Scrapping, les package RCurl et XML

Xpath, extraire des informations d'un arbre DOM

Syntaxe pour se promener dans l'abre dom et en extraire des partie (noeuds, attributs, ...), plus détails sur w3schools.
Expression Description
/bookstore/book[1] Selects the first book element that is the child of the bookstore element.
//title[@lang] Selects all the title elements that have an attribute named lang
//title[@lang='en'] Selects all the title elements that have an attribute named lang with a value of 'en'
/bookstore/book[price>35.00] Selects all the book elements of the bookstore element that have a price element with a value greater than 35.00

Scrapper leboncoin.fr

Ecrire un script R permettant de scrapper le nombre d'annonce du site dans la catégorie "Jardinage" en région centre.

Scrapper leboncoin.fr

page = requests.get("http://www.leboncoin.fr/jardinage/offres/centre/").text
doc  = html.fromstring(page)
element = doc.xpath('//nav/ul/li/span[@class="value"]/b')[0]
print(element.text_content())

Scrapper stackoverflow.com

Ecrire un script R permettant de scrapper le nombre de question publier sur les sites ayant les tags : 'python','julia-lang','r','sas','matlab','ggplot2' et 'd3.js'. Réaliser un graphique à partir de ces données.

Scrapper stackoverflow.com

import pandas as pd
# definition des termes à scrapper 
languages=['python','julia-lang','r','sas','matlab','ggplot2','d3.js']
# initialisation de la table
stackOF=pd.DataFrame({'lang' : languages, 'questions': [0,0,0,0,0,0,0]})
stackOF=stackOF.set_index(["lang"])
for lc in languages:
    # récupérer la page
    base = "http://stackoverflow.com/questions/tagged/"
    page = requests.get(base+lc).text
    # la parser et récupérer le noeud désiré (xpath)
    doc  = html.fromstring(page)
    element  = doc.xpath( "//div[@class='summarycount al']")[0]
    # récupérer la valeure, supprimer la virgule et convertir en numérique 
    print lc + " : " + element.text_content()
    stackOF.ix[lc] = int(element.text_content().replace(',',''))
%matplotlib inline
stackOF.sort_values(by="questions",ascending=False).plot(kind="bar",title="Nombre de questions sur SOF 22/02/2016")

Scrapper stackoverflow.com

Scrapper les résultats de ligue 1

sur footballstats.fr

Récupérer les dix dernières années de résultats du championnat de france

API
Application Programming Interface

Vélib' et altitude des stations

Utiliser les fichiers http://vlsstats.ifsttar.fr/data/input_Paris.json et http://vlsstats.ifsttar.fr/data/spatiotemporalstats_Paris.json ainsi que l'api google maps pour calculer un indicateur de charge moyenne des stations Vélib' et mettre celui-ci en relation avec l'altitude des stations.

Vélib' et altitude des stations

# récupérer la liste des stations et la mettre en forme
import numpy as np
stations=requests.get("http://vlsstats.ifsttar.fr/data/input_Paris.json").json()
stations = pd.DataFrame(stations)
stations["lat"]=stations.apply(lambda l : l.position["lat"],axis=1)
stations["lng"]=stations.apply(lambda l : l.position["lng"],axis=1)
stations["latlng"]=stations.apply(lambda l : str(l.position["lat"])+","+str(l.position["lng"]),axis=1)
stations["altitude"]=np.nan

Vélib' et altitude des stations

API google maps

# récupérer les altitudes
ns = stations.shape[0]
ng = ns/50
base  = "https://maps.googleapis.com/maps/api/elevation/json?locations="
for i in range(ng+1):
    print(i)
    ind   = range(i*50,min((i+1)*50-1,ns))
    query = stations["latlng"][ind].str.cat(sep='|')
    url   = base+query
    res   = requests.get(url).json()
    stations.loc[ind,"altitude"]=map(lambda l:l["elevation"],res["results"])

Vélib' et altitude des stations

API google maps


url = "http://vlsstats.ifsttar.fr/data/spatiotemporalstats_Paris.json"
data = requests.get(url).json()
usage=pd.DataFrame({"usage" : map(lambda l: np.mean(l["available_bikes"]),data),"number":map(lambda l: l["_id"],data)})
resf=pd.merge(stations,usage,on='number')
resf.plot(kind='scatter',x='altitude',y='usage')

TP Exercice : Mettez en forme un jeu de données sur les monuments historiques de Paris

Celui-ci devra contenir tant que faire ce peux des informations sur leurs localisation (latitude/longitude) et une description iconographique.

Pour vous aider les corrections des exemples du cours sont disponnibles dans ce notebook (html,ipynb)

Monuments historiques

Point projet