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.



mardi 13 juin 2017

Recherche de performance d'un programme python

Il est toujours intéressant de comprendre comment se décompose le temps d'exécution d'un programme. Cette démarche peut s'inscrire dans le cadre d'une recherche de la performance mais aussi dans le but d'utiliser au mieux des bonnes pratiques.

Avant tout, il est nécessaire d'avoir une mesure du temps d'exécution d'un programme. Le moyen le plus simple est d'utiliser la commande 'time'.  J'emploie cette commande avec l'option '-p' qui permet un affichage en seconde.

exemple:


time -p  python   programm1.py






Pour avoir le détail sur les fonctions qui consomment le plus en terme de temps d'exécution, il faut réaliser une opératoin de 'profilage'.  Le module cProfile est mon préféré car il s'utilise de manière externe sans modification du source et il est déjà installé. 

La commande pour l'activer est la suivante: 
python -m cProfile  -o eg.prof programme1.py 

L'option '-o'   est suivie du nom de fichier où seront stocké les statistiques.  L'option -s vient en exclusion avec l'option -oo , l'option 's' comme 'sort'  affecte un critere de tri  : exemple -s cumtime pour trier sur le temps cumulé.

 Exemple de sortie: 

       28917791 function calls (28917181 primitive calls) in 376.750 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       66    0.000    0.000    0.000    0.000 :102(release)
       59    0.000    0.000    0.000    0.000 :142(__init__)
       59    0.000    0.000    0.002    0.000 :146(__enter__)
       59    0.000    0.000    0.001    0.000 :153(__exit__)
       66    0.001    0.000    0.001    0.000 :159(_get_module_lock)


Cette sortie n'est pas toujours facile à lire aussi j'utilise une interface graphique Kcachegrind (ou qcachegring sur MacoSX) 

L'installation de qcachefrind se fait par: 
brew install qcqchegrind
Puis
brew install graphviz

Il reste à convertir un fichier cProfile au format callgrind avec la commande:
pyprof2calltree -i eg.prof -o ant2.grind

(avec -i pour le fichier en entrée, l'option -o pour le fichier en sortie )


Le travail d'optimisation peut commencer en tenant compte de deux axes: 
Le temps d exécution d'une méthode (en seconde ou en %) et le nombre d'appel à cette fonction




Dans cet exemple la fonction recherche_conditionC3 est appelée 26524 fois et représente un coût de 85%.

La fonction avant optimisation est comme ceci :

def recherche_conditionC3(self, cle,date):
    resultat = 'KO'
    ligne=[]
    for item in self.tableC3:
       if item[0] == cle:
        if date >= item[1]:
            ligne = item
            resultat = 'OK'
       if item[0] > cle:
         break
    return(resultat,ligne)

Il est possible de remplacer une recherche systématique par un pattern de memoization: c'est à dire un type de cache.
....
  clecache = cle + date.strftime('%m-%d-%Y')
    if clecache in C3taux.dictC3taux:
      #pdb.set_trace()
      return('OK',C3taux.dictC3taux[clecache])
sinon : continuer dans la méthode.


Avec comme résultat: un cout de moins de 1% 




Après une série d'optimisation,  de 260 secondes on tombe à 80 secondes. 

Ces techniques n'empêchent pas d'avoir une réflexion préalable sur une conception capable d'encaisser des montées en charge.

L'outil qcachegrind propose des vues  sur les arbres d'appel des méthodes


dimanche 27 novembre 2016

Pour bien commencer avec un Raspberry

Pour quelques dizaines d'euros, il est possible d'avoir à sa disposition un veritable ordinateur.
Cette ordinateur autorise la réalisation de projets divers.


Voici quelques conseils:

Choisir  pour commencer un kit complet

Ces kits sont livrés avec un SD carte déjà configurée. Elles sont proposées avec plusieurs systèmes d'exploitation (carte noob) .


Ces kits sont mis en route en quelques minutes.

Le wifi intégré: comment configurer une clé WEP sur la RASBIAN .

Les réseaux wifi sont sécurisés avec des mécanismes  de robustesse  différents. 
Les anciens réseau sont sécurisés avec le protocole WEP, les nouveaux réseaux utilisent WPA qui est plus robuste.
La distribution RASBIAN dérivée de la DEBIAN propose un outil de configuration di wifi qui ne reconnait pas le protocole WEP.  Pour contourner cette limitation, il sera nécessaire de modifier le fichier /etc/network/interfaces en complétant les parametres: 
 wireless-essid mybox
 wireless-key XXXX

Installation de docker. 

le système de conteneur docker a été porté sur Raspberry : 
Pour cela suivre les indications du site Hypriot.com.
Exemple ci-dessus du lancement d' HelloWorld sous docker dans une console (en fond le bureau du Raspberry)
 $docker run  hypriot/armhf-hello-world:latest


Utilisation d'une console USB/SERIAL


On trouve sur Internet des cables USB/SERIAL qui permettent de prendre en main le raspberry via son ordinateur. Cela permet de pouvoir configurer son raspberry sans écran ou clavier.

Après installation du driver COM  sur MacosX et branchement du cordon , il suffit de lancer la commande  dans le terminal :  screen /dev/cu.usbserial 115200 


Installation d'un serveur FTP

Le serveur pure-ftp fonctionne parfaitement sur mon raspberry. 

Installation de nodeJS

Un simple apt-get install nodejs , installera tout le necessaire pour exécuter du javascript en mode serveur.
pi@raspberrypi:~ $ nodejs -v
v0.10.29


Pour terminer : la rasbian est livré avec 2 versions de python installées: python 2.7  et python 3.4

De quoi passer des bons moments.