Data-science – et méthodes de hackers – Objectif



Data-science – et méthodes de hackers – Objectif

10 0


training

Slides for the hacker training

On Github anthill / training

Data-science

et méthodes de hackers

par ants / @beingAnts

Objectif

Vous rendre organisés, armés et autonomes pour apprendre de la data-science par la pratique.

Programme

travailler à plusieurs (git/github) les langages du web (html, css, javascript) dataviz: tableau de bord de consommation d'eau (3 jours) docker, déploiement ? ...

Spirit

NOS outils sur VOS projets avec VOS data on couvre large, vous hackez le reste support

Git

organiser son code et son travail

Git / GitHub

Git: gestionnaire de version (sur votre ordinateur)

GitHub: plateforme de collaboration (sur le cloud)

Git évite de dupliquer du code pour le versioner, permet de revenir en arrière et surtout permet de toujours savoir où on en est.

Outils indispensable pour organiser son travail sur un gros projet.

GitHub permet de s'échanger du code, de travailler à plusieurs sur un même projet et de communiquer sur les problèmes.

GitHub permet en outre de déployer des services et de recruter.

Environnement de travail

Configurer git

// dans le cas où vous êtes derrière un proxy
git config --global http.proxy http://proxyuser:proxypwd@proxy.server.com:8080
git config --global https.proxy https://proxyuser:proxypwd@proxy.server.com:8080

// si vous ne l'avez jamais fait auparavant
git config --global user.name "Your Name"
git config --global user.email "your_email@whatever.com"

// pour windows
git config --global core.autocrlf true
git config --global core.safecrlf true

Init

// créer un dossier
mkdir testgit
// s'y déplacer
cd testgit
// initialison git
git init

ce qui crée un dossier `.git` contenant tout ce qui concerne git. C'est léger.

Status

git status

donne:

On branch master

Initial commit

nothing to commit (create/copy files and use "git add" to track)

Status

touch testFile.txt

après ce fichier crée, status donne:

Untracked files:
(use "git add <file>..." to include in what will be committed)

	testFile.txt

add

git add testFile.txt

indique a git qu'on veut le versioner

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   testFile.txt

commit

git commit

ouvre un éditeur (vim, nano) pour nommer le commit.

Une alternative rapide:

git commit -m"added empty file to project"

faites un status pour voir...

On itère au fur et a mesure des changements qu'on veut persister :

// on ajoute une ligne au fichier (normalement utiliser l'éditeur)
echo "hello" > testFile.txt
git status
git commit -am"added hello to the file"

diff

faites une modification

git diff

indique les changements par rapport au dernier commit

-hello
+bonjour

Résumé

Chaque commit permet de poser une bouée pour repérer un état du code.

log

Pour avoir une vue de l'histoire

git log
commit 5bf345af8448979acd16ec07621561f8628211fa
Author: vallettea <vallettea@gmail.com>
Date:   Mon Jan 11 19:53:32 2016 +0100

    changed hello in bonjour

commit 2dc24bc314fc92fcbf20261ef80ec203088044d9
Author: vallettea <vallettea@gmail.com>
Date:   Mon Jan 11 19:32:26 2016 +0100

    added hello to the file

commit c04b81108300ebbe9d367d21c603ae9e3089d55e
Author: vallettea <vallettea@gmail.com>
Date:   Mon Jan 11 19:22:51 2016 +0100

    added empty file to project

checkout #commit

Pour se déplacer dans l'histoire

git checkout 2dc24bc314f

Si vous regardez votre fichier, vous verrez qu'il est revenu à l'état où il y avait hello. Pour revenir au dernier état

git checkout master

Attention: pour se déplacer dans l'histoire, il faut être "clean", c'est-à-dire ne pas avoir de modifications non-commitées.

checkout #file

Pour revenir au dernier commit

git checkout testFile.txt

va remmetre le fichier tel qu'il était au dernier commit. Pour faire la même chose avec tous les fichiers à la fois (dans le cas d'un projet complet):

git checkout --hard HEAD

Résumé

On utilise log et checkout pour naviguer dans l'histoire des commits

branch

Pour créer une branche quand on est clean:

git branch newVersion

Lister les branches

git branch

se mettre sur la branche

git checkout newVersion

ou, si on a déjà fait des modifications, qu'elles parraissent importantes et qu'on veut les séparer sur une nouvelle branche

git checkout -b newVersion

branch

Pour voir où on en est:

git log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short --all

(se faire un alias) donne:

* ae5830b 2016-01-11 | added a third file (HEAD -> newVersion) [vallettea]
| * 58f41af 2016-01-11 | added a second file (master) [vallettea]
|/
* 5bf345a 2016-01-11 | changed hello in bonjour [vallettea]
* 2dc24bc 2016-01-11 | added hello to the file [vallettea]
* c04b811 2016-01-11 | added empty file to project [vallettea]

Résumé

Les branches permettent d'organiser ses modifications

merge

Remettons nous sur master

git checkout master

et apportons tous les changements fait sur newVersion sur master :

git merge newVersion

merge

Pour voir où on en est:

git log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short --all

(se faire un alias) donne:

*   867fdd6 2016-01-11 | Merge branch 'newVersion' (HEAD -> master) [vallettea]
|\
| * ae5830b 2016-01-11 | added a third file (newVersion) [vallettea]
* | 58f41af 2016-01-11 | added a second file [vallettea]
|/
* 5bf345a 2016-01-11 | changed hello in bonjour [vallettea]
* 2dc24bc 2016-01-11 | added hello to the file [vallettea]
* c04b811 2016-01-11 | added empty file to project [vallettea]

Résumé

Merger sert a faire converger les modifications crées sur les branches vers une version finale.

Pour aller plus loin :

Ressources :

GitHub

Travailler à plusieurs

GitHub permet de :

  • stocker son code en ligne
  • travailler à plusieurs sur un même code
  • communiquer entre membre d'une équipe
  • documenter
  • déployer
  • embaucher ...

Crée un répertoire (repo)

Remote

Remote indique le chemin entre ce repo vers un dépot github :

git remote add anthill https://github.com/anthill/training.git
git push -u anthill master

où anthill est le nom du dépot. Un repo peut avoir plusieur remote (voir fork).

push

Pour synchroniser un repo local avec un remote, on utilise d'une part :

git push -u anthill master

où master est le nom de la branche qu'on veut synchroniser.

push s'utilise lorsque le repo local est en avance sur le remote.

Counting objects: 101, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (93/93), done.
Writing objects: 100% (101/101), 1.46 MiB | 145.00 KiB/s, done.
Total 101 (delta 17), reused 0 (delta 0)

pull

Si le remote est en avance sur le repo local (quelqu'un a ajouté du code) on utilise :

git pull anthill master

où master est le nom de la branche qu'on veut synchroniser.

Résumé

Avec remote, push et pull vous pouvez synchoniser votre code dans le cloud (sauvegarde)

clone

Un autre dévelopeur veut travailler sur votre code :

git clone https://github.com/anthill/training.git

va crée une copie locale de votre remote.

(que donne git remote -v ?)

fork

Au lieu de créer une copie de votre remote sur son local, il vaut mieux que le contributeur fasse une copie de votre remote sur un remote à lui. C'est la combinaison fork/clone.

(que donne git remote -v ?)

pull request

Lorsqu'un contributeur estime que les modification de son code devraient être incorporées à la version principale, il met synchronise son remote et crée un pull request

Résumé

Les pull request de forks permettent d'intégrer les contributions:

Ecrire vite et bien en markdown

Toutes les zones de texte de github permettent d'écrire en markdown

Les incontournables de github :

  • issues
  • pull request
  • milestones
  • wiki
  • metriques

html / css

Les langages du web

HTML

structurer le contenu

balise

Les elements d'une page sont représenté par une balise :

<element attribut="valeur" ...>contenu</element>

Certains éléments sont solitaires d'autres s'associent.

balises de méta-données

se placent dans l'en-tête de la page :

<meta name="description" content="The slides used to teach companies how to code like hackers.">
<link rel="stylesheet" href="css/reveal.css">

Ils servent à charger des ressources extérieures (css, javascript, données ...)

balises de méta-données

web sémantique

un type de balise = un rôle sémantique

les balises servent à structurer l'information pour que les machines (navigateur, moteur de recherche ...) puissent la comprendre

web sémantique

Par exemple, h (header) peut avoir différents poids :

<h1>Titre très important</h1>
<h2>Titre important</h2>
<h3>Titre moins important</h3>	
...

Structure d'une page

An illustrative guide to front-end developement

Structure d'une page

An illustrative guide to front-end developement

balises de section

balises de groupement

balises de tableau

Pour les tableaux :

<table>
  <thead>
    <tr>
      <th>Header content 1</th>
      <th>Header content 2</th>
    </tr>
  </thead>
  <tfoot>
    <tr>
      <td>Footer content 1</td>
      <td>Footer content 2</td>
    </tr>
  </tfoot>
  <tbody>
    <tr>
      <td>Body content 1</td>
      <td>Body content 2</td>
    </tr>
  </tbody>
</table>

balises de tableau

Le code précédent donne :

Header content 1 Header content 2 Footer content 1 Footer content 2 Body content 1 Body content 2

balises de formulaire

Pour les formulaires :

<form action="">
  <label for="GET-name">Nom :</label>
  <input id="GET-name" type="text">
  <input type="submit" value="Save">
</form>

<!-- Simple form which will send a POST request -->
<form action="" method="post">
  <label for="POST-name">Prénom :</label>
  <input id="POST-name" type="text">
  <input type="submit" value="Save">
</form>

balises de formulaire

Le code précédent donne :

Nom : Prénom:

balises d'interaction

balises de contenu

balises textuelles

Choisir sa balise :

Attributs globaux :

Attributs spécifiques :

CSS

donner du style...

CSS

Tous les éléments html ont un style par défaut, le CSS sert à personaliser le style de chaque élément.

CSS

Anatomie d'un élément (box model) :

3 façons de définir un style :

// dans l'élément
<element style="...">
// dans un bloc style
<style type="text/css">
// dans une stylesheet
<link rel="stylesheet" href="main.css">

4 types de sélécteurs :

p {...} /* sélécteur d'élement */

.class {...} /* sélécteur de classe */

#id {...} /*  sélécteur d'identifiant */

[attr] {...} /* sélécteur d'attribut */

Exemples de sélécteurs d'attributs :

div * {...}
div p a {...}
div.maClasse {...}
div a#monId {...}
ul > li {...} // all li directly children of ul
div[class=”maClasse”] {...} // all div that only have this class
div + span {...} // span that is adjacent to div
a[class~=”plop”] {...} // all div that have at least this class

Pseudo-classes

a:link {...}
a:visited {...}
a:hover {...}
div:only-child {...}
div:first-child {...}
div:last-child {...}
div:nth-child(an+b) {...}
div:nth-last-child(an+b) {...}
...

Pseudo-éléments

p::first-line // first line of the paragraph even in responsive mode
p::first-letter // first letter: usefull for typography of the first letter
p::before // add content inside the p before p's content
p::after // add content inside the p after p's content

display

Les éléments avec display: block forcent les éléménts suivant à aller à la ligne suivante. On peut choisir leur width et height

Les éléments avec display: inline subissent le flux du texte (et vont à la ligne quand il n'y a plus de place sur la ligne actuelle)

Les éléments avec display: inline-block agissent comme des inline à l'extérieur et block à l'intérieur

float et postion

les unités de positionnement

Arborescence d'un projet web :

site/
	css/
		main.css
		myTheme.css
	fonts/
	js/
	img/
	index.html

Responsive web design

Responsive web design

Dans tous les cas :

<meta name="viewport" content="width=device-width, initial-scale=1.0">

puis des media-queries :

@media only screen and (min-width: 480px) {...}

Pour aller plus loin :

Javascript

Rendre le web dynamique

Javascript

Javascript est le langage de programmation des pages web.

  • Inconvénient : legacy
  • Avantage : google, mozilla, facebook etc l'optimisent sans relâche

Types

Comparaison de valeur

  • Toujours utiliser === et !==
  • == "presque égal"
  • === "strictement égal"

Number

Un seul type de nombre (pas de distinction int/float/double)

parseInt("123", 10); // 123

parseInt("010");  //  8

Number.isNaN(NaN); // true

1 / 0; // Infinity

Math.sin(3.5);

var aire = Math.PI * r * r;

String

"bonjour".length; // 7

"bonjour".charAt(0); // "b"

"coucou monde".replace("coucou", "bonjour"); // "bonjour monde"

"bonjour".toUpperCase(); // "BONJOUR"

Boolean

false, 0, la chaîne vide (""), NaN, null et undefined deviennent toutes false

Boolean(""); // false

Boolean(234); // true

Comparaisons

123 == "123"; // true
1 == true;    // true

123 === "123"; //false
true === true; // true

if

var nom = "des chatons";
if (nom == "des chiots") {
  nom += " !";
} else if (nom == "des chatons") {
  nom += " !!";
} else {
  nom = " !" + nom;
}

les opérateurs logiques :

if (nom === "toto" && prenom === "alex")
if (nom === "toto" || prenom === "alex")
var permis = (age > 18) ? "oui" : "non";

switch

switch(action) {
    case 'dessiner':
        dessine();
        break;
    case 'manger':
        mange();
        break;
    default:
        neRienFaire();
}

sans break l'execution se poursuit au block suivant.

for

for (var i = 0; i < 5; i++) {
  // Sera exécutée cinq fois
}

array

var a = new Array();
a[0] = "chien";
a[1] = "chat";
a[2] = "poule";
a.length; // 3

var a = ["chien", "chat", "poule"];
a.push("vache");

a.join(", "); // "chien, chat, poule"
a.slice(1, 3); // ["chat", "poule"]
a.pop(); // "poule"

map / foreach

["a", "b", "c"].forEach(function(element){
	console.log(element)
});

var numbers = ["1", "2", "3"].map(function(element){
	return parseInt(element, 10)
});

Object

Les objets javascript sont similaires au dictionnaires en python et plus généralement aux hashmap

var obj = new Object();
var obj = {};
obj["prenom"] = "Simon";
obj["nom"] = "Dupont";
println(obj["nom"])

Object

Les objets peuvent avoir plusieurs niveaux:

var obj = {
    nom: "Dupont",
    prenom: "Simon",
    associes: ["A", "B"]
    preferences: {
        couleur: "orange",
        chiffre: 8
    }
}

on accède aux champs par enchainement :

obj.preferences.couleur; // orange
obj["preferences"]["chiffre"]; // 8

JSON

Les objets peuvent être serialisés en json :

var objectString = JSON.stringify(object);

var object = JSON.parse(objectString);

function

function ajoute(x, y) {
    var total = x + y;
    return total;
}

DOM (Document Object Model)

Le DOM est le graph dont les noeuds sont les balises html consituant le document.

javascript permet de manipuler le DOM dynamiquement.

Manipuler le DOM

Lorsqu'une page html est lue, window et document

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <script>
    "use strict";
    document.addEventListener('DOMContentLoaded', function() {
        var heading = document.createElement("h1");
        heading.textContent = "gros titre!";
        document.body.appendChild(heading);
    })
    </script>
  </head>
  <body></body>
</html>

Manipuler le DOM

Lorsqu'une page html est lue, window et document sont initialisées et on peut manipuler le DOM avec :

document.getElementById(id)
element.getElementsByTagName(name)
document.createElement(name)
parentNode.appendChild(node)
element.innerHTML
element.style.left
element.setAttribute
element.getAttribute
element.addEventListener
window.content
window.onload
window.dump
window.scrollTo

Les Evènements DOM

  • click
  • mouseUp
  • mouseDown
  • mouseMove
  • mouseEnter
  • mouseLeave
  • ...
<div onclick="changeFont();"></div> // don't do this

myDiv.addEventListener('click', function(){ // after myDiv = document.getElementById();
	doSomething();
});

Asynchronicité

Le problème du code synchrone

var f = readfile(file); // 10s
var g = readfile(file2); // 12s
var h = readfile(file3); // 15s

combine(f, g, h); // runs after 10 + 12 + 15 = 37s

Les promesses

var fP = readfile(file);
var gP = readfile(file2);
var hP = readfile(file3);

fP.then(function(contentF){
	console.log('Done', contentF);
});

Promise.all([fP, gP, hP])
    .then(function(results){ // runs after max(10, 12, 15) = 15s
        var f = results[0];
        var g = results[1];
        var h = results[2];
        return combine(f, g, h);
    })
    .catch(errorHandler);

Javascript côté serveur

API Serveur

  • File system

Modules

// export
module.exports = 9.81; // dans gravite.js
module.exports = function(masse){ // dans appliquerG.js 
	return 9.81 * masse; 
};

// import
var gravite = require('./gravite.js'); // my own stuff
var appliquerGravite = require('./appliquerG.js');

var moment = require('moment'); // npm package

Exporter plusieurs variables

// export
module.exports = { // dans math.js
	sum: function (a, b){ a + b },
	substract: function (a, b) { a - b }
}

// import
var additioner = require('./math.js').sum;
var soustraire = require('./math.js').substract;
// ou
var math = require('./math.js');

math.sum(3, 4);
math.substract(31, 22);

Node Package Manager

La plus grosse bibliothèque de modules pour Node

npm install npm --save -g // upgrades npm
npm init // initialize an npm project

package.json

{
  "name": "ToilettesBordeaux",
  "version": "0.0.0",
  "description": "## Données",
  "main": "index.js",
  "scripts": {
    "build": "browserify js/main.js -o app.js -d",
    "start": "devserver",
    "test-server": "devserver -p 9184",
    "test": "casperjs test test/casper",
    "watch": "watchify js/main.js -o app.js -d -v",
    "serve": "devserver",
    "lint": "eslint js/"
  },
  "repository": {
    "type": "git",
    "url": "git://github.com/anthill/ToilettesBordeaux.git"
  },
  "author": "",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/anthill/ToilettesBordeaux/issues"
  },
  "dependencies": {
    "browserify": "~6.1.0",
    "leaflet": "~0.7.3",
    "react": "~0.11.1",
    "react-tabs": "^0.1.2"
  },
  "devDependencies": {
    "watchify": "~2.0.0",
    "grunt": "~0.4.5",
    "grunt-devserver": "~0.6.0",
    "eslint": "~0.9.2",
    "casperjs": "~1.1.0-beta3",
    "tree-kill": "0.0.6"
  }
}

Il décrit le projet, ses scripts et ses dépendances

node_modules

Dossier contenant l'arbre de dépendances

Ne jamais commit !

projet_Node/
	js/
	node_modules/
		<!-- dependencies: always installed-->
		browserify/
		<!-- devDependencies: not installed when subdependency-->
		watchify/
		grunt/
			node_modules/ <!-- here only dependencies-->
				async/
				coffee-script/
				...
		grunt-devserver/
	package.json

On peut lister les dépendances avec

npm ls

Scripts

  • install
  • publish
  • test
  • start
  • stop
  • pre / post
  • scripts maison
npm run makeCoffee
// postmakeCoffee is run
npm start

Aller plus loin

GOGOGO

Indispensable pour utiliser Node dans le navigateur

  • Résout l'arbre de dépendances
  • Adapte le code serveur au contexte navigateur
  • Emballe le tout dans un seul fichier
browserify js/main.js -o browserify-bundle.js -d

Puis importer le bundle dans le HTML

<script defer src="browserify-bundle.js"></script>

watchify, l'équivalent temps réel

React

Building User Interfaces in JS

React

Créé par Facebook en 2013

Utilisé par

  • Facebook
  • Instagram
  • Netflix
  • Airbnb
  • ...

Existe en web et en natif

Avantages

  • Architecture par composants
  • Flux de données unidirectionnel
  • Statelessness
  • Virtual DOM

Inconvénients

Virtual DOM

  • copie virtuelle du DOM en cache
  • compare quand les données changent
  • modifie seulement le nécessaire

=> Rapidité

Composants

JSX vs JS

Construire un composant

Data flow

Les données "descendent", les évènement "montent"

Props et State

  • Objets JS
  • Contiennent la donnée
  • Déterministes
  • Déclenchent render()

Props

  • Immutable
  • Est hérité des parents
  • A utiliser dans la majorité des cas

State

  • Mutable: this.setState()
  • Doit être initialisé
  • Local au composant

Il faut limiter les composants stateful

Exemple

Aller plus loin

Data-Science

tour d'horizon

Data-Science

  • statistiques avancées (classification, régression...)
  • réseaux de neurones, deeplearning
  • théorie des graphes
  • optimisation (algorithmes génétiques, recuits, TSP ...)
  • computer vision
  • traitement du signal

Objectif:

Trouver le bon algorithme pour la bonne tâche.

Peu de maths...

Apprentissage supervisé

régression classification

Apprentissage non-supervisé

clustering page-rank réseaux de Kohonen ...

Pandas

Manipulation des données tabulaires en python

Doc

Pandas

Avantages :

  • importation des données
  • typage
  • gestion des NaN
  • gestion des dates et intervalles
  • intégration avec Numpy et Scikit
  • intégration avec spark

Import dans ipython

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

Series

s = pd.Series([7, 'Einstein', 3.14, -1789710578, 'Dumas'])

# adding index
s = pd.Series([7, 'Einstein', 3.14, -1789710578, 'Dumas'],
              index=['A', 'Z', 'C', 'Y', 'E'])

#from a dictionnary
d = {'Chicago': 1000, 'New York': 1300, 'Portland': 900, 'San Francisco': 1100,
     'Austin': 450, 'Boston': None}
cities = pd.Series(d)

Series: séléction

cities['Chicago']
cities[['Chicago', 'Portland', 'San Francisco']]
cities[cities < 1000]

# changing value
cities['Chicago'] = 1400

# applying function
np.sqrt(cities)

Series: opérations

# changing value
cities['Chicago'] = 1400

# applying function
np.sqrt(cities)

cities.notnull()

Séries temporelles

rng = pd.date_range('1/1/2012', periods=100, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(rng)), index=rng)
ts.resample('5Min', how='sum')

Dataframe:

data = {'year': [2010, 2011, 2012, 2011, 2012, 2010, 2011, 2012],
        'team': ['Bears', 'Bears', 'Bears', 'Packers', 'Packers', 'Lions', 'Lions', 'Lions'],
        'wins': [11, 8, 10, 15, 11, 6, 10, 4],
        'losses': [5, 8, 6, 1, 5, 10, 6, 12]}
football = pd.DataFrame(data, columns=['year', 'team', 'wins', 'losses'])

Dataframe: input/output

# read
pd.read_csv('file.csv', sep=',')
pd.read_json('test.json')
pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
data = pd.read_sql_table('data', conn)
# write
df.to_hdf('foo.h5','df')
                         names=cols)

Scikit-learn

Machine Learning library

Doc

Scikit-learn

Avantages :

  • mise en place
  • combine bien avec l'écosystème python
  • beacoup d'exemples
  • API quasi-unique pour tous les algos
  • la plus grande communauté

Scikit API

from sklearn import datasets, linear_model

# Create linear regression object
regr = linear_model.LinearRegression()

# Train the model using the training sets
regr.fit(diabetes_X_train, diabetes_y_train)

# Make predictions
regr.predict(diabetes_X_test)

Classification

  • Comparaisons des méthodes
  • Evaluer une classification
  • Classer des spam

Classification: naive bayse

Idée: on suppose "naïvement" que toutes les features sont statistiquement indépendantes.

Théorème de Bayes (explication):

\[ P(y\mid x_1, x_2, ..., x_n) = \frac{P(y)P(x_1, x_2, ..., x_n\mid y)}{P(x_1, x_2, ..., x_n)} \]

Classification: naive bayse

Avec l'indépendance des features:

\[ P(y\mid x_1, x_2, ..., x_n) = \frac{P(y)\prod_{i=1}^{n}P(x_i\mid y)}{P(x_1, x_2, ..., x_n)} \]

ce qui permet de calculer la classe la plus probable, après avoir choisis une distribution pour \( P(x_i\mid y) \)

Classification: naive bayse

Exemple avec une gaussienne:

\[ P(x_i\mid y) = \frac{1}{\sqrt{2\pi \sigma_y^2}}exp\left(-\frac{(x_i-\mu_y)^2}{2\sigma_y^2} \right) \]

Classification: naive bayse

Avantages :

Classification: naive bayse

Exemple avec Iris:
from sklearn import datasets
iris = datasets.load_iris()
from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB()
y_pred = gnb.fit(iris.data, iris.target).predict(iris.data)
print("Number of mislabeled points out of a total %d points : %d" % (iris.data.shape[0],(iris.target != y_pred).sum()))
Seuls 6 des points sur 150 sont mal labélisés.

Classification: régression logistique

Classification: régression logistique

\[ y = \frac{1}{1+e^{-z}} \] \[ z = \alpha_0 + \sum_{i=0}^{N} \alpha_i x_i \] où la fonction logit permet de faire entre les résulats d'un modèle linéaire dans l'intervalle [0,1]

Classification: régression logistique

Advantages :

  • régularisation contre overfitting
  • features correllées ou pas
  • stream

Classification: régression de Poisson

\[ y = Poisson(\lambda) \] \[ \lambda = exp(\alpha_0 + \sum_{i=0}^{N} \alpha_i x_i) \] pour modéliser des nombres entiers positifs croissants (nombre de visites sur un site etc)

Classification: svm

Maximise la distance geometrique entre la "decision boundary" et les samples.

Classification: svm

Classification: svm

Avantages :

  • précision
  • quelques résulats théorique pour se protéger de l'overfitting
  • un bon choix de noyau permet de spérer des données complexes

Problèmes :

  • gourmand en mémoire
  • difficile à interpréter
  • difficile à tuner

Classification: decision tree

\[ (x_1, y_1), (x_2, y_2), ...., (x_n, y_n) \]

Classification: decision tree

Premier split:

Classification: decision tree

Second split:

Classification: decision tree

Jusqu'à une condition d'arrêt :

Classification: decision tree

Avantages

  • facile à interpréter
  • feature hétérogènes (categorical, continuous)
  • modèle exportable
  • données manquantes
  • gère bien les features correllées

Problèmes :

  • pas de stream
  • overfitting

random forests gagnent souvent sur tout le monde, rapide et sclalable, sans paramètres.

Résumé

Evaluer une classification

Accuracy: à quel point la réponse est proche de la solution. Pensez à la cible avec des flêches et qu'on fait le décompte. Combien de prédictions sont de bonnes prédictions ?

Précision: à quel point cette réponse est reproductible. Penser au tireur et non à la cible. Est-ce que le modèle est fiable ?

Matrice de confusion

Le dataset sur le cancer du sein permet d'illustrer la gravité de l'évaluation d'un modèle.

  • 286 femmes qui ont subi un cancer du sein, 9 features
  • 201 n'ont pas eu de récurrence
  • 85 en ont eu

Matrice de confusion

Positif (réel) Négatif (réel) Positif (prédit) vrai positif faux positif Négatif (prédit) faux negatif vrai négatif

Matrice de confusion

Pour un modèle "jamais de récurrence" : Positif (réel) Négatif (réel) Positif (prédit) 0 0 Négatif (prédit) 85 201

Matrice de confusion

Pour un modèle "toujours une récurrence" : Positif (réel) Négatif (réel) Positif (prédit) 85 201 Négatif (prédit) 0 0

Matrice de confusion

Pour un modèle plus évolué genre decision tree : Positif (réel) Négatif (réel) Positif (prédit) 10 13 Négatif (prédit) 75 188

Précision

La robustesse du modèle (et c'est ça qui est important) se calcul par :

\[\frac{nb\ vrais\ positifs}{nb\ vrais\ positifs + nb\ faux\ positifs} \]
  • Precision "jamais de récurrence": 0/(0+0) = 0 (NaN)
  • Precision "toujours récurrence": 85/(85+201) = 0.30
  • Precision de l'arbre: 10/(10+13) = 0.43

Sensibilité (recall)

La complétude du modèle :

\[\frac{nb\ vrais\ positifs}{nb\ vrais\ positifs + nb\ faux\ négatifs} \]
  • Precision "jamais de récurrence": 0/(0+85) = 0
  • Precision "toujours récurrence": 85/(85+0) = 1
  • Precision de l'arbre: 10/(10+75) = 0.12

F1-score

Equilibre entre précision et sensibilité :

\[ 2\frac{precision \times recall}{precision+recall} \]
  • Precision "jamais de récurrence": 0
  • Precision "toujours récurrence": 0.46
  • Precision de l'arbre: 10/(10+75) = 0.19

Cas d'usage: iris

from sklearn.datasets import load_iris
from sklearn import tree
iris = load_iris()
clf = tree.DecisionTreeClassifier()
clf = clf.fit(iris.data, iris.target)
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(iris.target, clf.predict(iris.data))

# exercice
from treeExport import makeJsonTree
makeJsonTree(clf, iris.feature_names)

Cas d'usage: iris

Régressions

  • Comparaisons des méthodes
  • Evaluer une régression
  • Regression tree
  • Prédire le prix d'une maison

Régression linaire

Avec l'hypothèse \( h(x) = \theta_0 + \theta_1 x \) et la fonction de coût:

\[ J(\theta_0, \theta_1) = \frac{1}{2m}\sum_{i=1}^{m}\left(h_\theta(x^{(i)})-y^{(i)}\right)^2 \]

il suffit d'utiliser la méthode du gradient.

Régression: regression tree

Même principe que pour la classification :

Bagging

Consiste à diviser le learning set en plusieurs sous-ensembles et crée un modèle par sous ensemble. Le résultat est obtenu par moyenne pour la régression et par vote pour la classification.

  • scalable
  • réduit le risque d'overfitting
  • augmente quasi-systématiquement la stabilité

Exemple: random forest: beaucoup d'arbres overfittés

Boosting

Consiste à mettre en série des modèles qui apprennent de l'erreur résiduelle des précédents.

  • pas scalable
  • super-précis pour des dynamiques complexes
  • risque d'overfitting

Exemple: adaboost: beaucoup d'arbres underfittés

Evaluer une régression

\[ RMSE = \sqrt{\frac{\sum_i^n (p_i-x_i)^2}{n}} \] \[ RSE = \frac{\sum_i^n (p_i-x_i)^2}{\sum_i^n (\bar x-x_i)^2} \]

Evaluer une régression

\[ MAE = \frac{\sum_i^n |p_i-x_i|}{n} \] \[ RAE = \frac{\sum_i^n |p_i-x_i|}{\sum_i^n |\bar x-x_i|} \]

Evaluer une régression

\[ pearson = \frac{\sum_i^n (x_i-\bar x)(p_i-\bar p)}{\sqrt{\sum_i^n (x_i-\bar x)^2} \sqrt{\sum_i^n (p_i-\bar p)^2}} \]

Pearson

Overfitting

Diagnostiquer son problème.

Cas d'usage: prédire le prix d'une maison

import numpy as np
import matplotlib.pyplot as plt


from sklearn.cross_validation import train_test_split
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.ensemble.partial_dependence import partial_dependence
from sklearn.datasets.california_housing import fetch_california_housing

cal_housing = fetch_california_housing()
# if pb 
# https://raw.githubusercontent.com/scikit-learn/scikit-learn/3daab8a99862674514735a3caadd45cc542b43c1/sklearn/datasets/california_housing.py

# separation 80/20 train-test
X_train, X_test, y_train, y_test = train_test_split(cal_housing.data,
                                                    cal_housing.target,
                                                    test_size=0.2,
                                                    random_state=1)
names = cal_housing.feature_names

Cas d'usage: prédire le prix d'une maison

import pandas as pd
X_df = pd.DataFrame(data=X_train, columns=names)
X_df['LogMedHouseVal'] = y_train
X_df.hist(column=['Latitude', 'Longitude', 'MedInc', 'LogMedHouseVal'])
plt.show()

Cas d'usage: prédire le prix d'une maison

Cas d'usage: prédire le prix d'une maison

clf = GradientBoostingRegressor(n_estimators=300, max_depth=6,
                                learning_rate=0.04, loss='huber',
                                random_state=1)
clf.fit(X_train, y_train)

from sklearn.metrics import mean_absolute_error
from scipy.stats import pearsonr

y_pred = clf.predict(X_test)
mae = mean_absolute_error(y_test, y_pred)
print('MAE: %.4f' % mae)
pea = pearsonr(y_test, y_pred)
print('PEA: %.4f' % pea[])

Cas d'usage: prédire le prix d'une maison

# importances des features
indices = np.argsort(clf.feature_importances_)

plt.barh(np.arange(len(names)), clf.feature_importances_[indices])
plt.yticks(np.arange(len(names)) + 0.25, np.array(names)[indices])
plt.xlabel('Relative importance')
plt.show()

Réduction de dimensionalité (PCA)

Il s'agit de trouver une nouvelle base de vecteurs propres qui élimine les corrélations.

  • visualisation
  • simplification du dataset
  • moins facile à interpréter

Excellent lien.

Détéction d'anomalies

Lorsqu'une prédiction d'un modèle diffère significativement de la réalité, il y une anomalie.

Détection d'anomalies chez twitter.

Clustering

Il s'agit de regrouper des points par des règles de proximité géométriques dans un espace à N dimensions.

Excellent post décrivant la prédicition via k-means clustering.

Ressources

API

Structurer les services

API

Une Application Programmtion Interface est un ensemble de contraintes sur les entrées/sorties d'un programme pour que tout le monde puisse se parler.

API REST

  • Interface uniforme
  • Stateless
  • Cacheable
  • Client-Server: separation of concerns
  • Layered-System

API REST

Les representations des objets sont des URI:

http://api.example.com/client/123

API REST

Avec le protocole HTTP:

  • GET
  • POST
  • PUT
  • DELETE

Github API

curl https://api.github.com/users/vallettea
{
  "login": "vallettea",
  "id": 371303,
  "avatar_url": "https://avatars.githubusercontent.com/u/371303?v=3",
  "gravatar_id": "",
  "url": "https://api.github.com/users/vallettea",
  "html_url": "https://github.com/vallettea",
  "followers_url": "https://api.github.com/users/vallettea/followers",
  "following_url": "https://api.github.com/users/vallettea/following{/other_user}",
  "gists_url": "https://api.github.com/users/vallettea/gists{/gist_id}",
  "starred_url": "https://api.github.com/users/vallettea/starred{/owner}{/repo}",
  "subscriptions_url": "https://api.github.com/users/vallettea/subscriptions",
  "organizations_url": "https://api.github.com/users/vallettea/orgs",
  "repos_url": "https://api.github.com/users/vallettea/repos",
  "events_url": "https://api.github.com/users/vallettea/events{/privacy}",
  "received_events_url": "https://api.github.com/users/vallettea/received_events",
  "type": "User",
  "site_admin": false,
  "name": "Alexandre Vallette",
  "company": null,
  "blog": null,
  "location": null,
  "email": null,
  "hireable": null,
  "bio": null,
  "public_repos": 50,
  "public_gists": 61,
  "followers": 32,
  "following": 3,
  "created_at": "2010-08-20T21:09:06Z",
  "updated_at": "2016-02-26T23:22:07Z"
}

API nodejs

Avec express.js:

app.get('/user/:name', function(req, res){
    var user = req.params.user;
    console.log('requesting sensor user', user);

    // result of the call to a db
    var data = {
        name: "toto",
        age: 12
    };

    res.status(200).send(data);

});

API python

Avec flask:

from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

@app.route('/user/<username>')
def show_user_profile(username):
    list = [
        {'param': 'foo', 'val': 2},
        {'param': 'bar', 'val': 10}
    ]
    return jsonify(result=list)

if __name__ == "__main__":
    app.run()
						</username>

API temps réél

Webhooks:

var githubhook = require('githubhook');
// configure listener for github changes
var github = githubhook({/* options */
	   host: "0.0.0.0",
   port: 8082,
   path: "/pushchanges",
   secret: "123456"  
  });

// listen to push on github on branch master
github.on('push', function (repo, ref, data) {
	  var branchName = _s.strRightBack(ref, "/");
	  var fullNameRepository = data.repository.full_name;
	  var removedFilesArray = data["head_commit"]["removed"];
	  var addedFilesArray = data["head_commit"]["added"];
	  var modifiedFilesArray = data["head_commit"]["modified"];
});

// listen to github push
github.listen();

API temps réél

Avec socket.io:

var io = require('socket.io')(80);
var cfg = require('./config.json');
var tw = require('node-tweet-stream')(cfg);
tw.track('socket.io');
tw.track('javascript');
tw.on('tweet', function(tweet){
  io.emit('tweet', tweet);
});

Scrapping

Prendre sa data

Scrapping

Toute information visible sur internet peut être récupérée.

  • API: methode officielle
  • html: exemple BeautifulSoup
  • js: casperjs

Scrapping

Exemple: scrapper la météo avec python

soup = BeautifulSoup(urllib2.urlopen("http://www....").read())

a = soup('table', {'width': '100%', "border":"1", "cellpadding":"1" ,"cellspacing":"0", "bordercolor":"#C0C8FE" ,"bgcolor":"#EBFAF7"})[0]

b = a.findAll("tr")

Scrapping

Exemple: scrapper la qualité de l'eau

casper.start("http://...", function() {
    this.selectOptionByValue('select[name="departement"]', "033") 
});

casper.then( function() {
    this.selectOptionByValue('select[name="communeDepartement"]', "063") 
});

casper.then(function(){
    this.waitUntilVisible('input[value="Rechercher"]', function() {
        this.click('input[value="Rechercher"]');
    });
})

Orchestration

Penser en service

Ansible

Déployer et maintenir

Ansible

Ansible permet de déployer automatiquement une infrastructure complexe sur plusieurs machines.

Ansible

Avantages :

  • léger: tout fonctionne par ssh
  • communauté: de nombreux modules