Chapitre 3 DOCUMENTS SEMI-STRUCTURÉS ET BASES DE DONNEES NOSQL Mineure « Data Science » Frédéric Pennerath Rappel sur les données structurées et les bases relationnelles Données structurées ou tables : Liste de n-uplets à champs nommés et typés selon un schéma fixe Articles Réf. Nom Catégorie Stock Base de données relationnelles Ensemble de tables et leurs schémas 1 Raquette Master 300 exp 40 Remarques : • Chaque table a une clé primaire (pas de doublons) • Langage de requête SQL fondé sur l’algèbre relationnelle : sélection, projection, jointure • Optimisation des requêtes : index (B-tree), optimiseur de plans d’exécution, cache mémoire • Données utilisées après jointure par les méthodes de machine learning (Weka, scikit-learn) 2 Raquette First Smash deb 2000 Mineure « Data Science » Frédéric Pennerath … Transactions Réf. Client Article Quantité 1 1 1 4 2 2 2 400 … Les différents types de base de données NoSQL (not only SQL) Type de données Base de données Produits Données structurées typées Bases de données relationnelles (SQL) MySQL, PostgreSQL, SQLite, Oracle, … Données de type objets Bases de données orientées objet Idem + surcouche (Hibernate, etc) BigTable (Google), HBase (Apache), Cassandra (Apache), Hypertable, « Pandas », etc Données semi-structurées Arbres Bases de données orientées documents MongoDB, CouchDB, etc Graphes, Réseaux d’objets Bases de données orientées graphes Entrepôts RDF (Allegro), Neo4j, Oracle, IBM, etc Mineure « Data Science » Frédéric Pennerath Bases de données NoSQL Données structurées creuses Bases de données orientées colonnes Equivalence entre bases de données orientée objets et relationnelles Bases de données orientées objet Bases de données relationnelles Classe Table Attributs typés d’une classe Schéma d’une table Adresse des objets Clé primaire Référence sur un objet Clé étrangère Méthodes des objets Procédures stockées Mineure « Data Science » Frédéric Pennerath Données semi-structurées Données semi-structurées : Données de type arbre dont les nœuds peuvent être nommés et où les feuilles sont des valeurs (entiers, chaînes de caractère, etc) Adaptées aux documents : documents, pages Web, etc livre titre date Livre I des fables de la Fontaine 1668 chapitre titre La Cigale et la Fourmi Mineure « Data Science » Frédéric Pennerath chapitre titre La Cigale ayant chantée tout l’été Le Corbeau et le Renard Maître Corbeau sur un arbre perché Langages à balise et XML XML est un langage à balise : une balise est une paire de parenthèses typées XML Schema : possibilité de spécifier un schéma de données Inconvénients : verbeux, assez lourd à manipuler Interfaces de programmation : DOM et SAX (pour les gros fichiers) <livre date = "1668"> <titre>Livre I des fables de la Fontaine</titre> <chapitre> <titre>La Cigale et la Fourmi</titre> La Cigale ayant chantée tout l’été … </chapitre> <chapitre> <titre>Le Corbeau et le Renard</titre> Maître Corbeau sur un arbre perché … </chapitre> </livre> Mineure « Data Science » Frédéric Pennerath Le format d’échange JSON JSON est un langage de sérialisation d’objets (au départ pour JavaScript) • Types de base : chaînes de caractères entre "…", nombre, booléen (true/false), null • Dictionnaires {…} dont les clés sont des chaînes de caractères. • Tableau […] { } "date": 1668, "titre": "Livre I des fables de la Fontaine", "chapitres": [ { "titre": "La Cigale et la Fourmi", "texte": "La Cigale ayant chantée tout l’été … " },{ "titre": "Le Corbeau et le Renard", "texte": "Maître Corbeau sur un arbre perché … " } ] Avantages : plus concis que XML, Facile à manipuler car en bijection avec les représentations mémoire des langages faiblement typés (JavaScript, Python, Perl,…) Mineure « Data Science » Frédéric Pennerath La manipulation des fichiers JSON en Python • Bijection évidente entre les structures Python et JSON … mais – Les clés JSON sont uniquement des chaînes de caractères entre "". – Les tuples de Python n’existent pas en JSON. – Pas de distinction entre int et float. • Le module json réalise cette bijection en chargeant un document JSON en mémoire. • json est à JSON ce qu’est DOM à XML import json fichier = open('input.json') data = json.load(fichier)) json.dump(data, open('output.json','w')) Mineure « Data Science » Frédéric Pennerath La lecture séquentielle d’un fichier JSON • Certains fichiers sont trop volumineux pour être chargés en mémoire. • Le module ijson permet la lecture séquentielle des fichiers JSON volumineux • ijson est à JSON ce qu’est SAX à XML • Attention à utiliser un générateur paresseux et non une liste en compréhension import ijson fichier = open('fables.json') # Renvoie un itérateur sur les chapitres (item désigne les cases d’un tableau) fables = ijson.items(fichier, 'chapitres.item') fablesAvecRenard = (f for f in fables if 'renard' in f['titre']) for f in fablesAvecRenard: print f Mineure « Data Science » Frédéric Pennerath Les bases de données orientée documents Bases de données orientées documents Bases de données relationnelles Donnée atomique Document semi-structuré (XML, JSON) Ligne dans une table (n-uplet) Structure d’une base de données Ensemble de collections de documents Ensemble de tables contraintes par un schéma Taille d’une donnée Extensible Fixe Avantages Flexibilité Fortement typé Inconvénients Risque élevé de corruption des données Inadapté aux documents semistructurés même respectant un schéma Principes communs Clé primaire, langage de requête, index (Btree), optimiseur de requête, cache, réplication, etc Mineure « Data Science » Frédéric Pennerath Une base de données NoSQL orientée documents Logiciel libre (www.mongodb.org) • Pour stocker des documents « au sens large » : tout objet de type JSON • Stockage au format optimisé BSON (JSON binaire) • Padding des documents BSON (avec redimensionnement constant ou de loi géométrique) • Longueur d’un document < 16Mo • Langage de requête CRUD (Create Read Update Delete) en JSON – Exemples de requêtes en lecture – Exemples de requêtes en écriture – Possibilité de trier et agréger les résultats (Map/Reduce) • Possibilité de distribuer les grosses collections(sharding) Mineure « Data Science » Frédéric Pennerath Documents MongoDB Document : structure JSON Collection : ensemble de documents plus ou moins homogènes partageant un jeu d’index Clé primaire : champ _id obligatoire toujours indexé – UID défini par l’utilisateur – ObjectID() Attention : • Les clés sont des chaînes • Les valeurs sont typées (contrairement à JSON) – Float (défaut), double – int32, int64 – String, boolean, date, etc Mineure « Data Science » Frédéric Pennerath { _id : NumberInt(201501011), date : ISODate("2015-01-01T10:00:00Z"), oriente-document : [ { nom : "mongodb", version : 2.6 }, { nom : "couchdb", version : 1.6 } ], sql : [ { nom : "mysql", version : 5.6 }, { nom : "postgresql", version : 9.4 } ] } Insérer des données dans MongoDB en Python import pymongo client = MongoClient('localhost', 27017) db = client.TP trajectories = [ { "_id" : "1-1", "drv": 1, "speed": {"max": 100, "avg": 60}, "pts": [ (0.,0.), (1.,0.) ] }, { "_id" : "1-2", ... } ] # Insertion d’une seule trajectoire db.trajectories.insert(trajectories[0]) # Insertion de plusieurs trajectoires (opération “bulk”) db.trajectories.insert(trajectories) NB : en Python, les clés sont des chaînes entre "…" Mineure « Data Science » Frédéric Pennerath Faire des requêtes MongoDB en Python ... # Renvoie une trajectoire du conducteur 1 traj = db.trajectories.findone({ "drv": 1 }) # Toutes les trajectoires des conducteurs de 10 à 20 trajs = db.trajectories.find({ "drv": {"$gt": 10, "$lt": 20 } }) # Trajectoires du cond. 1 dont la vitesse maximale est sup. à 50 km/h trajs = db.trajectories.find({ "drv": 1 , "speed.max": {"$gt": 50 }}) # Les vitesses moyennes de toutes les trajectoires du cond. 1 trajs = db.trajectories.find({ "drv": 1 }, {"speed.avg": 1}) # Trajectoires du cond. 1 triées par ordre croissant de vit. moyenne from pymongo import ASCENDING, DESCENDING trajs = db.trajectories.find({ "drv": 1}).sort("speed.avg", ASCENDING) NB : trajs est un curseur itérable (évaluation paresseuse) Mineure « Data Science » Frédéric Pennerath Faire des mises à jour dans MongoDB en Python ... # Met à jour les vitesses moyenne et maximale du conducteur 1 db.trajectories.update({ "drv": 1 }, {$set: {"speed.avg": 40, "speed.max": 90}}) # Ajoute à tous les conducteurs une vitesse minimale nulle db.trajectories.update({}, {$set: {"speed.min": 0}}, { "multi": True} ) # Supprime le champ vitesse db.trajectories.update({}, {$unset: {"speed": 1}}, { "multi": True}) # Insère ou met à jour une nouvelle trajectoire db.trajectories.update({"_id": "1-10" }, {...}, { "upsert": True} ) Mineure « Data Science » Frédéric Pennerath Créer un index ... # Crée un index triant les trajectoires par ordre décroissant de vitesse maximale db.trajectories.ensure_index("speed.max") # Crée un index composé triant les trajectoires par ordre décroissant de vitesse moyenne puis par ordre croissant de conducteur db.trajectories.ensure_index([("speed.moy", DESCENDING), ("drv", ASCENDING)]) # Efface l’index db.trajectories.drop_index("speed.max") Mineure « Data Science » Frédéric Pennerath Index de type B-tree Dictionnaire ordonné (valeur d’un champ → n-uplet) • Permet l’énumération efficace des n-uplets tiés dont la clé est compris dans un intervalle • Possibilité de regrouper plusieurs attributs selon l’ordre lexicographique Codage sous forme de B-Tree : – Généralisation des arbres binaires équilibrés (e.g red-black tree) aux arbres n-aires – Très gros arbre équilibré conçu pour un stockage sur disque (1 nœud = 1 bloc) – Nombre de blocs lus = O( log 𝑑+1 𝑛 ) où d = ordre du B-tree Bloc disque bob as baba sirop Minimum : d éléments Maximum : 2d éléments zéro star bidon dodo Mineure « Data Science » Frédéric Pennerath lion nylon rhum tour Principe des B-Trees Bloc disque bob as baba sirop bidon lion Insertion de télé ? star Insertion de carré ? dodo zéro nylon rhum Mineure « Data Science » Frédéric Pennerath tour télé tour Principe des B-Trees Bloc disque bob as baba carré sirop zéro bidon dodo star lion nylon Mineure « Data Science » Frédéric Pennerath rhum nylon rhum télé tour Principe des B-Trees Bloc disque bob as baba carré lion sirop zéro bidon dodo Mineure « Data Science » Frédéric Pennerath star nylon rhum télé tour En résumé Structures de données Python Module pymongo Modules json / ijson Fichiers d’échange JSON Documents MongoDB Mongo shell (mongoimport/export) Mineure « Data Science » Frédéric Pennerath San Francisco Crime Classification Challenge 1. 2. 3. Télécharger les données du challenge https://www.kaggle.com/c/sf-crime Charger les données dans une base Mongo avec pymongo Enrichir les données de descripteurs supplémentaires – Quartier Regarder le module Python de geocodage geopy – Heures de la journée – Autre ? 4. 5. Appliquer un algorithme de classification de scikit-learn Estimer le logloss Mineure « Data Science » Frédéric Pennerath