lundi 23 novembre 2020

Jupyter pour le deep learning

 A l'occasion de la sortie en Français du livre de François Chollet: 



J'ai préparé mon environnement pour utiliser Keras et Tensorflow dans un notebook Jupyter.

Le prérequis est d'avoir les notebook Jupyter installés.

Création d'un environnement Python spécifique à Keras et Tensorflow.

Utiliser le module Python natif venv  pour créer un espace propre à vos programmes et  librairies Python.

python -m venv --system-site-packages <env_a_creer>

Activer l'environnement virtuel par la commande suivante exécutée depuis le répertoire crée: 

source bin/activate

Installer dans cet environnement Keras et Tensorflow avec la commande 'pip'

(suivre les instruction du site Tensorflow)

Vérifier la bonne installation par une tentative d'import de keras depuis l'invite python (exemple)

from keras.models import Sequential


Vérifier le fichier de configuration keras.json situé sous le répertoire '.keras' du répertoire de l'utilisateur.

Ce fichier renseigne sur le backend à utiliser : ici tensorflow.

Installer un nouveau noyau  (kernel) à Jupyter.

Toujours depuis votre répertoire <venv>, lancer la commande:

python -m ipykernel install --user --name=<venv> --display-name 'keras'

 Pour vérifier les kernels installés :

jupyter kernelspec list

Le kernel ajouté doit figurer dans la liste.

Pour le supprimer: 

jupyter kernelspec remove <venv>

Pour tester:

Lancer Jupyter et vérifier la presence d'un kernel supplémentaire (ici keras)

Puis tester l'import des librairies Keras




 Accéder à distance à l'instance Jupyter.

option utile  comme dans mon cas où Jupyter est installé sur un ultramini-portable  

Lancer Jupyter sur le mini-portable: 

 jupyter notebook --ip=0.0.0.0 --NotebookApp.token=''

L'option 'ip' permet de demander à Jupyter d'écouter sur toutes les interfaces réseaux.

La dernière option évite d'avoir à rentrer un token à rallonge dans le navigateur distant.

Il suffit alors de faire pointer son navigateur distant sur http://192.168.1.xx:8888/





Mon ultramini-portable Chuwi: grand comme ma main mais très puissant. 

En bonus: changer l'aspect de Jupyter

Dans le répertoire  .jupyter de l'utilisateur 

Créer l'arborescence suivante: 

/home/<user>/.jupyter/custom

Puis éditer un nouveau fichier custom.css

Le mien contient les lignes suivantes:

egerman@egerman-MiniBook:~/.jupyter/custom$ cat custom.css
#ipython_notebook::before{
 content:"Jupyter sur Chuwi"
}
#ipython_notebook img{
 display:none;
}
body > #header {
    background: #78abd2;
}
div.cell {
    transition: all 0.25s;
    border: none;
    position: relative;
    top: 0;
}
div.cell.selected, div.cell.selected.jupyter-soft-selected {
    border: none;
    background: transparent;
    box-shadow: 0 6px 18px #aaa;
    z-index: 10;
    top: -10px;
}

Avec comme résultat: 
  • Un titre personnalisé
  • Un mise en avant de la cellule active

jeudi 15 octobre 2020

Régression linéaire en Python : 3 méthodes

 La régression linéaire est un des piliers du machine learning.

Je vais présenter 3 méthodes pour trouver l'équation de la droite qui résume au plus près un nuage de point..

Le chargement des données. 

Les données sont issues d'un jeu de donnée des valeurs foncières en opendata (disponible sur github) . 

Les données seront chargées dans un dataframe de Pandas.

import pandas as pd
data = pd.read_csv('parcelles_ext.csv', sep=';')
import numpy as np

data.replace('None',np.nan , inplace = True )
data2 = data[['valeur_fonciere','surface_reelle_bati','adresse_code_voie', 'nombre_pieces_principales']]
data2 = data2.dropna()
y= data2['valeur_fonciere'].to_numpy()
X=data2['surface_reelle_bati'].to_numpy()
X = np.reshape(X,(-1,1))
y = np.reshape(y,(-1,1))


Seules deux colonnes seront utilisées.

Méthode par un batch de descente en gradient.


Deux fonctions sont nécessaires: une qui calcule le 'coût' (l'erreur)  et une autre qui va répéter autant de fois que necessaire le calcul de cout puis le gradient et va se rapprocher petit à petit du minimum de la fonction de coût.

def  cost_function(theta,X,y):   
    m = len(y)
    predictions = X.dot(theta)
    cost = (1/2*m) * np.sum(np.square(predictions-y))
    return cost

Le batch
def gradient_descent(X,y,theta, alpha=0.01,iterations=100):
    m = len(y)
    cost_history = np.zeros(iterations)
    theta_history = np.zeros((iterations,2))
    for it in range(iterations):   
        prediction = np.dot(X,theta)
        theta = theta -(1/m)*alpha*( X.T.dot(prediction - y))
        theta_history[it,:] =theta.T
        cost_history[it]  = cost_function(theta,X,y)     
    return theta, cost_history, theta_history
Pour maintenant activer le batch , on a besoin d'ajouter une colonne  'biais' aux données en entrée.
Et de choisir un taux d'apprentissage et un nombre d'itération.


lr =0.0001
n_iter = 100000*8
theta = np.random.randn(2,1)
initial_theta = theta
X_b = np.c_[np.ones((len(X),1)),X]
Le 'alpha' (learn rate) est ici très bas et le nombre d'itération très élevés.
La raison principale est l'ordre de grandeur des données: 

 [  1. 113.]
 [  1.  91.]
 [  1.  61.]
 [  1. 150.]]
113 , 150 etc , les données ne sont pas à l'echelle (voir la suite) mais on arrive à un résultat.


Méthode par une fonction de recherche de minimum.


au lieu de devoir faire un batch à la main, il est possible d'utiliser une fonction intégrée qui va se charger de trouver le minimum d'une fonction en optimisant les itérations par l'emploi de transformation. 
On va individualiser la fonction gradient:

def gradient(theta,X,y):
    #print(X.shape)
    #print(theta.shape)
    prediction = np.dot(X,theta)
    t_gradient = 1/len(y)*(X.T.dot(prediction-y))
    return t_gradient

Et appeler la fonction de recherche de minimum (fmin_tnc de scipy) en lui passant le nom des fonctions de cout et de gradient.



Les deux méthodes arrivent à des résultats comparables.

Méthode par l'équation  normale.


Il est possible de trouver directement l'équation de la droite normale mais avec un niveau de complexité qui explose avec le nombre de donnée.


 
A retenir : toujours normaliser ou mettre à l'echelle les données. 

On peut utiliser des méthodes intégrées:

ou le faire à la main:

L'avantage est d'avoir en retour les valeurs de mu et sigma pour l'appliquer aux prévisions.
Le learn rate et le  nombre d'itération  seront moins extrêmes.


Le code est sous forme de notebook pour jupyter à retrouver sur mon github.


jeudi 13 août 2020

Régression logistique en Python : cours du professeur ng Andrew

Dans l'article précédent  (lien ici), je traduisais en Python le premier TP de la formation Machine learning de ng Andrew. Le TP introduisait les problèmes de régression linéaire. 
La deuxième semaine avait comme  objectif de présenter la régression logistique.
Cette notion est un prolongement de la régression linéaire. Le résultat est une probabilité qui permet de dresser une ligne de démarcation (deux clusters) entre 2 régions : oui ou non. Le jeu de données propose les notes d'examen pour  2 épreuves et le résultat de l'admission finale.
Il est demandé de tracer une droite qui partage au mieux les étudiants reçus et les recalés. 


Le gros point bleu en haut à droite est la visualisation de la probabilité estimée pour un cas de test.



x1_test =45
x2_test = 85
plt.scatter(x1_test, x2_test, c = 'lightblue', s = 400 )
plt.pause(40)
plt.show(block=False)
propa = thc[0] + thc[1] * 45 + thc[2] * 85
#print(propa)
print('estimation probabilite recu 45 ep1 et 85 ep2:',sigmoid(propa))

On utilise les principes de la régression linéaire pour ensuite appliquer une fonction (sigmoïde) qui ventile les résultats entre la valeur 0 et 1.

Autant pour le TP1 il était possible d'effectuer la descente en gradient par itération en étant sur de converger vers un résultat, dans ce cas de figure,  il  est nécessaire de faire appel à une fonction de calcul de minima.  

Avec octave ça donne ceci:

%  Run fminunc to obtain the optimal theta
%  This function will return theta and the cost 
[theta, cost] = ...
fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);


Avec Python , j'utilise  la fonction fmin_tnc de scipy


from scipy.optimize import fmin_tnc
Cette fonction à la signature suivante:
scipy.optimize.fmin_tnc(funcx0fprime=Noneargs=()approx_grad=0bounds=Noneepsilon=1e-08scale=Noneoffset=Nonemessages=15maxCGit=- 1maxfun=Noneeta=- 1stepmx=0accuracy=0fmin=0ftol=- 1xtol=- 1pgtol=- 1rescale=- 1disp=Nonecallback=None)

Minimize a function with variables subject to bounds, using gradient information in a truncated Newton algorithm. This method wraps a C implementation of the algorithm.


D'une manière  simple, il faut lui fournir la fonction de coût à minimiser, la fonction de gradient, les jeux de données et les résultats attendus.

essai = fmin_tnc(func = costFunction2, x0 = initial_theta.flatten(), fprime = None , args = (XX , yy.flatten() ) )
J'ai ajouté le calcul de la matrice de confusion importé de la librairie sklearn:

from sklearn.metrics import confusion_matrix
confusion
= confusion_matrix(pr,cible,[0,1])
print('matrice de confusion',confusion)
total = np.sum(confusion)
prec = (confusion[0][0] + confusion[1][1]) / total
effic = confusion[1][1]/np.sum(confusion, axis = 0)[1]
print('precision',prec)
print('pertinence', effic)

;
Le code n'est pas fameux en raison des contraintes sur le format des paramètres en entrée. C'est cette partie qu'il faudra améliorer.

dimanche 7 juin 2020

Machine learning : d'Octave à Python

  • Dans son cours en ligne ‘Machine Learning’   (Stanford), le professeur NG Andrew  utilise les langages Octave et Matlab pour les travaux pratiques. J’ai refait le premier TP en Python  (Pandas et Numpy) et cet article est à prendre comme un retour d’expérience.

Le TP numero 1 se divise en deux parties :

Les problèmes de régression linéaire par la descente de gradient 

·       A une seule variable

·       A plusieurs variables

Avec une comparaison par rapport à une résolution par l’équation normale.

Partie 1

Le problème est de trouver les coefficients de la droite qui s’ajuste le mieux à ce nuage de point :



Pour cela on utilisa le méthode de la descende de gradient  qui consiste trouver par petites touches le point le plus base de cette figure : Elle représente la courbe du ‘coût’ (fonction d’erreur)

 

Le résultat est le point situé au coordonnées : 1.1664 (<->)   et   -3.630 (|)

Utilisation de Python

Les librairies utilisées sont :

import numpy as  np

import pandas as pd

import matplotlib.pyplot as plt

from matplotlib import cm

from mpl_toolkits.mplot3d import Axes3D 

 

Axe3D permettra de réaliser la courbe 3D de la fonction coût.


La difficulté du codage réside dans le partage de rôle entre pandas et numpy. Les calculs de matrices sont à faire avec numpy mais pandas propose aussi ses propres fonctions de calcul.

Je n’ai pas chercher à refactoriser mon code qui demeure très laid.

L’effort portera sur la 2eme partie de l’exercice.


Ci-dessous la comparaison entre Python et Octave.


samedi 22 décembre 2018

Quand la loi d'ATWOOD se vérifie une nouvelle fois: Javascript

La loi d'Atwood se formule de la manière suivante: toute application qui peut être écrite en JavaScript, sera finalement écrite en JavaScript
ici un lien vers un article précédent sur le sujet.

Cette loi est a nouveau vérifiée aujourd'hui et d'une façon forte.

En effet , Martin Fowler a sorti la deuxième edition de son livre incontournable :

Refactoring

Improving the Design of Existing Code

Dans la première édition ,les exemples de ce livre étaient en Java.

The book is written using Java as its principle language, but the ideas are applicable to any OO language.

Dans la nouvelle édition; les exemples sont en ..Javascript.



Now, Fowler has thoroughly updated his book to reflect modern programming techniques.


Tous les développeurs se doivent d'avoir ce livre en bonne place sur leur bureau.

refectoring, testing, refactoring, testing, GOTO début.

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” 
—M. Fowler (1999)



dimanche 17 septembre 2017

Liens utiles sur la blockchain

Je donne ici des liens utiles pour suivre l'actualité de la blockchain.

Blockchain daily news : site en francais.

Blockchain france.

Le top 250 des entreprises de l'ecosystème blockchain.

A partir de cette liste et des mots clé j'ai généré l'image suivante:

Bitcoin : graphique sur les volumes d'échange: bitcoincharts

Visualisation de block : blockcypher

dimanche 10 septembre 2017

La blockchain: quelle révolution ?

Le concept de blockchain est présenté comme une révolution d'Internet. Son utilisation dans le domaine financier a été largement mis en avant par le développement des cryto-monnaies comme le Bitcoin ou l'Etherium.
Je prépare une présentation de 40 minutes sur le thème de la blockchain.  Le  fil conducteur la  sera construit sur les éléments de réponse à cette question: la blockchain est elle une révolution ?

Pour m'aider dans cette tache, j'ai depuis quelques mois assemblé une carte de connaissance.
Le source  de la carte (réalisée avec freeplane) est disponible sur github a cette adresse:
lemon-labs blockchain .
Merci pour votre aider à la compléter.


Ici le lien de l'illustration à télécharger pour zoomer.