Thématiques principales

lundi 24 septembre 2018

Python : Manipulation des données

Nous voila dans une petite digression. Je n'avais pas pensé faire un article sur les préceptes de base de la manipulation des listes, des tuples, des tableaux ou encore des dictionnaires en python mais au vue des quelques derniers articles sur l'IA [1-4] et aussi des futurs articles qui auront pour base les frameworks numpy [6], pandas [7] et scikit-learn [8], il nous faut explorer un peu comment nous pouvons manipuler les données, c'est a dire ici les charger, et effectuer des calculs.

Alors nous irons dans la compréhension des structures de données rencontrées de façon récurrente dans l'IA et le machine learning mais nous n'entrerons pas ici dans la visualisation ou l’interprétation des données. Nous nous attarderons sur ces aspects lorsque l'on traitera de la visualisation et de l'analyse statistique des données dans la limite du compréhensible.

Commençons par les bases, ce que python nous permet de base déjà

Les listes

Bon nous ne cherchons pas spécialement a faire un cours sur python donc voyons l'essentielle sur les listes et les manipulations de base. La liste en python est un ensemble de données de taille dynamique et modifiable.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# liste
maListe=[1, 2, 3, 4]
print(maListe)
maListe.append(5)
print(maListe)
print(maListe[:3])#on prend les paramtres avant l'index 3 exclu
print(maListe[3:])# on prend les paramtres apres l'index 3 inclu
malisteN2=[[1, 2, 3, 4],[5,6,7,8],[9,10, 11, 12],[13, 14, 15, 16]]
print(malisteN2)

[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3]
[4, 5]
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]


mercredi 19 septembre 2018

BigData: Théorème de CAP

Il y a quelques temps, l'un de mes collègues me posa cette question:

Saurais tu me rappeler le principe des trois lois des systèmes distribués ? Il y a la cohérence mais je ne sais plus quels sont les autres....
Et la je dois avouer que si ça me disait bien quelque chose, j'ai été incapable de l'aider. J'ai bien pensé aux 3V du Big Data (Vitesse,Volume, Variété) [1] mais ce n’était pas ça et finalement ça s'est fini en blague autour des trois lois de la robotique [2]. (Nous reviendrons sur ces deux concepts)

Du coup je n'ai pas pu beaucoup aidé mon collègue qui finalement a trouvé tout seul (comme un grand)! C’était le théorème de CAP (ou de Brewer [3])! Ça me disait bien quelques chose mais quoi? Regardons cela ensemble.

Pour parler du théorème de CAP, il faut d’abord garder en tête deux concepts : ACID que nous avions vu dans les propriétés des bases de données Relationnelle [4] et BASE que nous venons de voir dans l’article précédent [5] dans les bases NoSql.

Ces deux concepts sont un peu comme les deux faces d’une même pièce: la gestion des données. D’un côté, on prône l'intégrité, de l’autre, la performance. Le théorème de CAP est la justement pour formaliser cette dualité au travers de trois concepts clefs:

  • Consistency: la cohérence des données dans la base
  • Availability: la disponibilité des données
  • Partitioning : les requêtes sur la base doivent aboutir quel que soit le partitionnement sur le réseau. 

Ainsi à partir de ces 3 concepts, le théorème de CAP énonce qu’il n’est pas possible pour un système de base de données de garantir à la fois les 3 concepts en même temps et ne peut en garantir qu’au mieux 2 [6].

Ainsi 3 configurations émergent de ce schéma mettant en évidence des types de base de données bien spécifiques:

  • CA: Coherence et disponibilité nous mène à l’ensemble des base de données les plus classique, les SGBD-R et nous ramène aux propriétés ACID
  • CP: Coherence et Partitioning nous mène à des base de données où les performances sont moindre mais où la sécurité de l'intégrité des données est primordiale. On trouvera certains SGBD-R (en cluster) et type de base NoSql configuré en conséquence.
  • AP: Disponibilité et partitioning nous conduit ici à la performance avant tout. Les bases ne sont pas forcément cohérente dans le temps mais la multiplicité des bases sur le réseau permet de garantir une réponse quoiqu’il arrive. La majeur partie des base NoSql se trouveront dans cette configuration en nous ramenant aux propriétés BASE.

Alors en fait le monde réel n’est pas si cloisonné et le théorème de CAP ne doit pas être interprété aussi strictement. En réalité chacun de ces concepts peut se représenter selon différents degrés d'équilibre variant dans le temps selon l’architecture choisi et les cycles de vie des données élaborées. Ainsi, même s’il n’est possible de garantir que deux propriétés à un instant données, rien n'empêche de chercher à les garantir à tour de rôle.

Sans entrer dans les détails (que vous trouverez ici [7]), cela reste une démarche complexe mais possible selon le besoin, il restera alors à composer avec le coût de la mise en oeuvre….

Références

[1] https://www.axess.fr/definition-big-data-3v/
[2] https://fr.wikipedia.org/wiki/Trois_lois_de_la_robotique
[3] https://fr.wikipedia.org/wiki/Th%C3%A9or%C3%A8me_CAP
[4] http://un-est-tout-et-tout-est-un.blogspot.com/2018/02/sgbd-r-introduction.html
[5] À publier
[6] https://openclassrooms.com/fr/courses/4462426-maitrisez-les-bases-de-donnees-nosql/4462471-maitrisez-le-theoreme-de-cap
[7] https://www.infoq.com/fr/articles/cap-twelve-years-later-how-the-rules-have-changed

lundi 17 septembre 2018

BigData: BASE

Nous voici sur un nouveau sujet: les bases de données NoSql. Pour introduire doucement ce sujet, nous allons nous intéresser au pourquoi ce type de base en nous intéressant aux propriétés de celles-ci: les propriété BASE.

Les propriétés BASE sont pour les bases de données NoSql, ce qu’est ACID pour les bases de données relationnelles. Nous avions vu les propriétés ACID dans l’article [1]. Celle ci énonce qu’une base de données doit respecter les propriétés d’atomicité, de cohérence, d’isolation et de durabilité.

Ces propriétés sont propres au SGBD-R et imposent des contraintes fortes de fonctionnement que justement les bases de données NoSql cherchent à affranchir.

Pourquoi vous allez dire? Et bien c’est simple: le Big Data.

Alors le but n’est pas de digresser sur le Big Data, nous reviendrons sur ce thème dans un autre article pour comprendre le Big Data, cependant, il faut juste avoir conscience aujourd’hui, les systèmes d’informations sont confronté une problématique de traitement de données massives et fortement distribuées et malheureusement, cette problématique ne se résout plus avec des bases de données relationnelle classique car justement les propriétés ACID deviennent contre productive (nous verrons cela aussi pourquoi précisément dans un article prochain).

C’est la que le NoSql, en opposition avec les SGBD-R, va tenter de fournir une solution en proposant de s’appuyer sur les propriétés BASE à la place d’ACID.

Mais alors qu’est ce que BASE? BASE est l’acronyme de:
  • Basically Available : le service doit garantir la disponibilité des données
  • Soft-State : la base supporte des accès concurrent pouvant rendre les données incohérentes
  • Eventually Consistent : la base garanti que celle-ci trouvera des états où les données seront cohérentes
On voit ici que nous sommes bien loin des propriétés ACID même plutôt à l’opposé mais il faut garder en tête que l’objectif ici est la performance plutôt que la cohérence.

Référence

[1] http://un-est-tout-et-tout-est-un.blogspot.com/2018/02/sgbd-r-introduction.html

CSRF

Je ne suis pas coutumier d'article sur des sujets concernant le FrontEnd car honnêtement, les technologies web ne me passionnent pas vraiment étant plus familiarisé avec celle du BackEnd.

Cependant, ça serait une erreur de ne pas s’intéresser a tout, surtout que l'on trouve dans les concepts du front des choses plutôt intéressantes et des préoccupations propres a elle qui ne peuvent qu'enrichir la compréhension du fonctionnement des applications d'entreprises actuelles.

Ainsi aujourd'hui on va s’intéresser à un concept propre au front et à la sécurité: le CSRF.

Le CSRF ou Cross Security Request Forgery [1] est une faille de sécurité visant à faire réaliser une action malveillante et non souhaité à un utilisateur.

Explications [2]

Cette faille part du principe que vous, être malveillant, connaissiez des urls spécifiques d’un site permettant la réalisation d’action d’administration via des GET ou des POST. Vous n’avez pas les droits adéquats pour réaliser ces actions, mais vous savez qui peut les faire. L’exploitation de la faille consiste, par un quelconque moyen (un mail avec des chatons par exemple), à inciter cette personne à cliquer sur ces urls pré-paramétrés pour réaliser ces actions à son insu.

Pour éviter cela, il existe une solution: le jeton (ou token). L’idée est d’associer (au moment de la réponse à un GET initial) à chaque éléments réalisant une requête une valeur auto-générée et aléatoire qui sera repoussée au serveur afin d'être authentifiée et validée.

Ce faisant, il est alors impossible de réaliser une requête quelconque sans ce token, ceci permettant alors de s’assurer que pour que l’action soit valide, il faut que l’utilisateur l’ait réalisé en ayant eut le jeton préalablement, invalidant alors la possibilité d’utiliser la faille CSRF.

Alors si ca vous a paru compliqué, ne vous inquiétez pas, la plupart des frameworks actuels tels que Spring avec Thymeleaf [3], [4] implémentent déjà des tokens pour se parer à la faille CSRF. Ceci existe même aussi directement dans les serveurs d’applications, comme avec Welogic [5].

Références

[1] https://fr.wikipedia.org/wiki/Cross-site_request_forgery
[2] https://openclassrooms.com/fr/courses/2091901-protegez-vous-efficacement-contre-les-failles-web/2863569-la-csrf
[3] https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html
[4] https://www.baeldung.com/spring-security-csrf
[5] http://weblogic-wonders.com/weblogic/2016/04/29/prevent-csrf-attack/

samedi 15 septembre 2018

IA: Equation normale

Il y a quelques jours, j'avais parlé de l’équation normale dans la régression linéaire [1]. Nous n'avions pas traité de son utilisation dans la régression linéaire parque:
  • c'est la solution analytique et que du coup c'est la solution simple
  • elle ne s'applique qui si les jeux de données sont limitées
  • c'est pas fun car on voulait utiliser la descente de gradient.
Du coup nous l'avions laissé de coté, la pauvre....

Aujourd'hui on va rendre a l’équation normale ce qui appartient à l’équation normale, c'est a dire la régression linéaire.

Dans le principe, l’équation normale [2] est la résolution analytique parfaite des coefficients du modèle linéaire:



Avec Theta, le vecteur des coefficients du modèle, X le vecteur des données d'entrée et Y le vecteur des données de sortie attendues.

Pour illustrer cela, prenons un exemple en python:


1
2
3
4
5
6
7
import numpy as np
 
MAX=1000
    
X=  np.arange( 0, MAX )
T= 4+3*X  
Y= T + (np.random.rand(1,MAX)-0.5)[0]*3000 

Dans cet exemple, nous allons construire une série de valeur de 0 a 3000, on en calcule la série T équivalente selon une droite dont on va bruité les données: la série Y.

Représentons ces données:

1
2
3
4
5
import matplotlib.pyplot as plt
fig = plt.figure(1,figsize=(8,8))
plt.plot(X,T,"b-")# model lineaire
plt.plot(X,Y,"r.")# model lineaire bruité
plt.show(



Donc on a bien déployer nos données autour de la droite T. Avant de chercher des paramètres, en première approche, nous pourrions nous demander si l’équation normale est capable de nous retrouver les paramètres initiaux de la droite avant que celle ci ne soit bruitée.

Appliquons l'equation normale a (X,T) afin de voir si le Theta resultant est bien le couple (4,3):


1
2
3
4
5
Xmat=np.c_[np.ones((len(X),1)),np.mat(X).T]
Ymat=np.mat(T).T

Verif=np.linalg.inv(Xmat.T.dot(Xmat)).dot(Xmat.T).dot(T)
print(Verif)

De résultat:

[[4.]
 [3.]]

Cool! Au moins on sait que l'on sait retrouver nos paramètres! A noter la préparation des données avec la fonction c_ (concatenate) et ones qui permet de construire une matrice unitaire (rempli de 1). L'objectif de cette préparation est de permettre de produire une paire de valeur.

Maintenant reprenons nos données buitées et calculons nos paramètres, au passage calculons les valeurs résultants du modèle sur l'ensemble des valeurs d'entrées:

1
2
3
4
Xmat=np.c_[np.ones((len(X),1)),np.mat(X).T]
Ymat=np.mat(Y).T
TheTa=np.linalg.inv(Xmat.T.dot(Xmat)).dot(Xmat.T).dot(Ymat)
print(TheTa)

donnant:

[[-165.91134982]
 [   3.24312348]]

OK cela ne correspond pas a nos paramètres initiaux. Mais peut etre que cela donne une bonne approximation de nos données. Superposons les graphes:


1
2
3
4
5
6
ThetaD=np.array(TheTa[0])+np.array(TheTa[1])*X
fig = plt.figure(1,figsize=(8,8))
plt.plot(X,Y,"r.")# model lineaire bruité
plt.plot(X,T,"b-")# model lineaire
plt.plot(X,ThetaD.T,"y-") # taux erreur de base deux precedents
plt.show()

Effectivement nos deux droites ne sont pas les mêmes, cependant, au vue de la dispersion, celle estimé est une assez bonne approximation de la première. Bien sur c'est lorsque l'on sortira du périmètre de l'ensemble [0-1000] que les encarts se feront les plus important. Il faudra donc en tenir compte lors de l'utilisation du modèle résultant de façon a minimiser les erreurs.

Voila, en fournissant une solution analytique, l’équation normale fourni une approche assez immédiate pour la détermination des paramètres de notre modèle. Apres il reste comme tout autre approche limité par l'ensemble des données du jeu d’apprentissage dont la taille peut rendre celle ci rédhibitoire.

Références

[1] https://un-est-tout-et-tout-est-un.blogspot.com/2018/09/started-ia-neuromimetique-la-regression.html
[2] http://gilles.dubois10.free.fr/geometrie_affine/eucliequanorm.html

100 : un peu d'autobio

Ça y est, ça fait presque un an que j'ai commencé ce blog et cet article en est le 100 ième!

Dans mon premier article, je ne m’étais pas forcement étalé sur le pourquoi de ce blog, sa signification, etc. J'avais parler surtout de changement, de l'importance de maintenir le changement et que souvent lorsqu'il n'y a plus de changement c'est qu'il y a probablement régression.

Aujourd'hui il peut être bien pour ce 100ième de faire un petit bilan du passé, de se poser quelques questions (et pourquoi pas y répondre) et de se fixer de nouveaux objectifs pour les mois qui vont maintenant venir.

Commençons par le bilan de tout ça. En soit l’écriture d'un blog donne l'occasion de pousser un peu plus loin l'acquisition de connaissances. En effet, comme on le dit, ce qui se comprend bien s’énonce clairement et le corollaire de cela est que si l'on ne parvient pas bien a expliquer quelques chose, c'est que probablement il y a des choses qui n'ont pas été parfaitement comprise. Avec ce blog j'ai voulu aller jusqu'au bout de cette idée.

Alors bien sur, les sujets traités dans ce blog ne sont pas des nouveautés pour moi mais en allant jusqu’à l’écriture de ces articles, je voulais en quelques sorte me rassurer sur mes compétences mais aussi ma capacité a acquérir de nouvelles connaissances tout comme ma capacité à en transmettre.

Étrange démarche direz vous et j'admet que ça soulève des questions surtout la question pourquoi?

Pour y répondre, il importe de revenir un peu plus en arrière que sur cette dernière année. En fait un peu plus... un peu plus, disons jusqu’à l’époque ou j'ai passé mon doctorat, même un peu avant. Mince ça commence a faire loin tout ça et je ne pensais pas partir dans des souvenirs et dans des discourt aussi personnel, surtout dans un blog d'informatique! Mais bon maintenant que je suis lancé!

En gros, et pour aller au plus vite : une enfance classique, des études et un niveau moyen mais un certain intérêt pour la mécanique, découlant sur un bac avec une mention assez bien et une classe prepa qui a été un calvaire, une perte de temps et un gâchis au vue de ce qu'il y avait a y apprendre.

Ainsi en toute logique j'ai pris la première école d’ingénieur qui a bien voulu de moi, clairement par défaut, il faut l'avouer mais ce fut alors le début probablement de la plus belle décennie de ma vie (après la prepa, ça n’était pas de refus).

En école d’ingénieur, je ne peux pas dire que j'ai vraiment tout de suite trouvé mes marques, peut être a cause des événements qui s’étaient déroulé en prepa. Cependant en école, j'ai rencontré vraiment des gens bien (je ne dirais pas de nom mais si un jour il tombe sur cet article, ils se reconnaîtront) et si a la base je pensais faire de la mécanique, j'ai finalement dérivé dans l'informatique en passant a coté de la formation de l'automaticien (que, j'avoue, j'aurais du suivre avec plus d'attention)

Ce fut alors a l'issu d'un redoublement (la deuxième année d’école) que je repris les choses en main et ou je m'investi vraiment dans ce qui serait le fondement de ma carrière dans l'informatique et surtout toute la partie conceptuelle de celle-ci qui fit de ce domaine quelque chose de passionnant a mes yeux.

On peut ainsi presque dire que débuta alors vraiment un age d'or (personnellement comme professionnellement). J'obtins donc mon diplôme d'ingénieur en informatique et réseau et fit le choix de tenter a sa suite un Master Recherche pour pouvoir creuser les concepts plus intime de l'informatique et de l’étude des systèmes : le  concept objet, le MDE, la théorie du contrôle par supervision, les processus de développement, la neuromimétique etc...

Cette année fut réellement passionnante et probablement que ça s'est vu puisque l'on me proposa de poursuivre le travail démarré pendant le stage de master avec une thèse financé par une bourse ministérielle. Bien sur j'ai accepté et eut l'opportunité de faire en plus de l'enseignement, une expérience des plus enrichissante.

J'ai pu apprécier sur tweeter ou autre réseau social de ci delà que de nombreux doctorants vivaient mal leur thèse. Il est vrai que le doctorant est un peu la matière premier de la recherche et que de nombreuses dérives existes surtout dans les relations entre le thésard et son directeur de thèse! Moi j'en ai eut trois et il ont probablement été les meilleurs que l'on puisse avoir. Laurent, le plus jeune d'entre eux était probablement le plus dynamique et le plus enclin a amener de la matière a réfléchir. Jean-marc pour sa part préparait son HDR et a été inestimable dans la technicité de ses conseils, et enfin Bernard, que j'ai considéré et considère toujours comme un maître a penser me donna beaucoup d'inspiration et de rigueur. Leur apport a été et est encore aujourd'hui dans mon travail inestimable.

Je ne rentre pas dans le détail de la thèse, nous y reviendrons dans d'autres articles mais on s'en doutera le jour de la soutenance fut en quelque sorte le point culminant de cet age d'or qui se termina alors lorsqu'il fallu faire le choix de tenter de poursuivre dans le recherche ou partir dans l'industrie.

Mon choix fut l'industrie et après 10 ans en Alsace, je revins dans le Nord (en 2011) pour travailler pour Sopra puis un an plus Thales. Je n'entrerai pas dans le détail de mon travail pour ces entreprises puisque sujet au "secret". J'exprimerai juste mon ressenti sur ces expériences en y incluant aussi une composante importante de la vie, la composante personnelle.

En effet, autant si ma vie personnelle sur Mulhouse a été indéniablement un terreau fertile pour construire ma thèse, je dois avouer que ma vie personnelle a mon retour dans le nord s'est gravement compliqué. Cela ne m'a pas empêché de réussir les differentes missions qui m'ont été données a l’époque chez Sopra, la preuve en est que j'ai fini par être embauché par le client qu’était Thales. Cependant, je n'avais pas forcement mesuré ce qu’était vraiment la vie en entreprise surtout en ayant une vie personnelle complexe a gérer.

J'ai donc fais ce que je pense tout le monde fait dans ces moment la, s'appuyer sur ses acquis et se concentrer sur les problèmes importants (et la je ne pense pas que l'on me contredira si je met le personnel en premier). Ainsi le temps a passé, les années se sont écoulées et les problèmes personnels ont finis pas se terminer. C’était en 2014 et 2015.

C'est la que l'on peut reprendre un concept vieux comme le monde dans le domaine de l'informatique: l'effet tunnel ou l'on avance sans visibilité ni recul mais on arrive a une échéance, et la c'est le choc! En effet, avec la fin des problèmes, j'ai aussi pu retrouvé un environnement sain pour travailler et surtout me remettre en question (Merci Emilie!!). S'en est donc suivi d'une grosse période de doute et de flottement ou j'ai vu ces quelques dernières années comme des années ou finalement je n'avais pas progressé, voir l'inverse!

Bien sur j'avais eut l'occasion de pouvoir réaliser des choses professionnellement il n'y avait rien a me reprocher, j'avais même eut l'opportunité d'avoir d'autres responsabilités mais cela ne me convenait pas et au fil du temps, je ne parvenais plus a m’évaluer, savoir ce que je valais et si tout bêtement ce que je faisais chez Thalès était ce que je voulais vraiment.

J'ai donc encore mis deux années pour tenter d’évoluer, passer architecte, s'essayé au rôle de Scrum Master, etc... cependant il y avait bien quand même UNE chose qui manquait, c’était la découverte.

Ainsi courant 2017, j'ai pris conscience que je n'avais pas fait de la recherche pour rien et que j'occultais même complètement mon doctorat lors de mes échanges personnels comme professionnels comme si c’était un honte, une chose inutile, un péché inavouable.

J'avoue même qu'encore aujourd'hui, je n’évoque pas cela naturellement, je ne veux pas donner l'impression que je me pose "la". Au fond de moi peut être que je regrette de ne pas avoir su poursuivre dans le monde académique et que j'ai cédé a la facilité de travailler dans le privé.

Face a ce refus d'assumer mon titre et ce constat de ne plus savoir ce que je valais, je me suis alors dit, aujourd'hui j'ai que 36 ans (en juin), j'ai eut un doctorat, peut être que c’était il y a 6 ans,  mais je dois pas être si con et rien n'est impossible: allez je me relance dans ce qui a été pour moi, l'activité qui m'a le plus porté, ce qui a fait ma force, le métier qui me passionnait: la recherche.

Alors la vous allez vous dire, ba parfait t'es retourné en labo quoi pas la peine d'en faire un foin! Ba non car c'est loin d’être aussi simple. j'en avais parlé dans cet article, et j'avoue que la tache est rude pour revenir dans le monde académique. Pourtant, je me suis dit mais qu'est ce qui m’empêche de publier quand même? rien, nous en venons donc au blog ici présent.

Alors OK ce blog est loin d’être un recueil de recherche et s'assimile plus a un ensemble de plein de choses connues : en gros un état de l'art... et oui un état de l'art. Un peu comme lorsque l'on prépare une thèse.... mais c'est logique car on ne peut élaborer des propositions si l'on ne dispose pas des connaissances permettant de les étayer... et je me suis rendu compte qu'il fallait regagner de la confiance en soit, de la capacité a reformuler les choses, et que apprendre aussi c'est quand même super cool!

Du coup voila, on en est la en septembre dernier, j'ai décidé de commencer ce blog pour m'en servir comme d'un gros bloc note et en prenant le parti que "ce qui se comprend bien s’énonce clairement", j'ai pris le plis de tenter de vulgariser soit ce qui était déjà acquis depuis longtemps (genre les techno java ou la normalisation de bases de données), soit des choses qui méritait d’être apprise (genre Liquibase).

Au passage, c'est un exercice qui aide a la synthétisation et a la prise de recul sur des technos qui parfois sont foisonnantes et peuvent être mentalement un peu fouillis.

Dans le même temps, j'ai également pris conscience que pendant ces quelques années, je m’étais trop reposé sur l'entreprise dans laquelle j’étais pour avancer. C'est une erreur! Il ne faut jamais attendre quoique ce soit pour avancer et progresser! Et la j'ai compris que j'avais fait le tour de ce que j'avais a apprendre a mon poste chez Thales. En toute logique, j'ai donc décidé de partir.

S'en est suivi logiquement les entretiens... et les baffes. Oui des baffes car de chaque entretien j'ai appris de choses:

  • que je ne m’étais pas assez tenu a jour et que l'idée du blog arrivée a temps pour m'auto challenger sur des nouveaux sujets
  • que je ne m’étais pas assez intéressé aux différents secteurs d'activités et marché dans lesquels je pouvais donner de la logique a mes connaissances
  • que des entretiens, sont des entrevues ou il existe de nombreux biais qui peuvent nous faire échouer: notre propre arrogance mais aussi celle de l'interlocuteur, un peu trop de confiance en soit ou l'inverse le manque de confiance en soit, ou tout bêtement les attentes des uns et autres qui ne convergent pas.

Pour ma part, je sais que les entretiens que j'ai le plus apprécié sont ceux ayant eut lieu avec des interlocuteurs qui m'ont fait avancé, et m'ont poussé a me poser les bonnes questions (je remercie au passages mes interlocuteurs de chez Sfeir et Zenika de l’époque).

Certains ont été des catastrophes mais j'en avais déjà parlé dans un article sur le polymorphisme et honnêtement, même avec presque un an de recul, ma position reste la même, dans ce cas, il y avait un vrai problème dans le processus d'entretien, j’espère que leur approche a évolué depuis...

Enfin voila, j'ai fini par faire un choix pour Capgemini, parce que:

  • les contacts que j'ai eut lors des entretiens ont été vrai géniaux, autant des RH que des techniques, il y a un vrai respect de l'individu et aucun jugement, c'est un peu le slogan "venez comme vous etes".
  • et une ESN est une bonne façon de se confronter a différents contextes de travail et de continuer a se bousculer au quotidien.

Donc voila, depuis mars dernier je suis chez "Cap" et c'est aussi pour ça que le rythme des articles à baissé car mine de rien l'activité que j'y mène consomme beaucoup d’énergie mais je pense que j'ai quand même trouvé un bon rythme de croisière avec entre 4 et 8 articles par mois, c'est plutôt pas mal surtout que les articles ont pris plus de dimension, surtout ceux sur l'IA qui ont ete assez long.

Du coup j'en viens maintenant a l'avenir de ce blog. Je vais essayer de tenir le même rythme: entre 4 et 8 articles par mois selon leur taille. Mon objectif pour l'année qui arrive sera de tenter parler un peu plus de modélisation, de poursuivre dans l'IA et de prendre une dimension un peu plus formelle en introduisant un aspect un peu plus mathématique aux articles.

L'idée finale est bien de continuer sur l'idée d'un état de l'art mais aussi de commencer a reconstituer un spectre et une direction cohérente dans mes recherches avec pourquoi pas un véritable article scientifique a l'issu de tout ça dans un journal.

Voila, je crois que j'ai tout dit.  On se dit donc en septembre prochain pour un prochain point et voir ou m'aura mener la direction prise aujourd'hui! A bientôt.



dimanche 9 septembre 2018

IA : Neuromimétique, la régression linéaire

Nous revoilà sur un sujet un peu plus sympa pour ce début septembre, la régression linéaire.

Cet article aurait du être publié en août mais le temps a manqué, et j'ai voulu profiter du précédent article sur les Streams [1] pour essayer une approche un peu différente de ce tour d'horizon de ce que l'on peut faire avec un neurone!

Du coup aujourd'hui, il s'agit de présenter la régression linéaire en s'appuyant sur les Streams Java. Comme nous l'avions vu dans les articles précédents sur l'IA [2], nous allons créer un jeu de données d'apprentissage et un jeu de donnée de test sur deux cas d'utilisations (en fait 3 nous verrons pourquoi):
  • l'un sur l'identification de paramètres : nous allons donc demander a notre neurone de nous donner les paramètres (a,b) d'une droite tel que y=a.x+b
  • l'un sur la construction d'un modèle prédictif partant d'une droite bruité artificiellement (nous traiterons ici de plusieurs cas différents afin de considérer les situations qui marchent bien de celles, moins pertinentes)
Pour cela, nous n’utiliserons qu'un seul modèle de fonction d’activation : le linéaire [3]. Nous pourrions utiliser le sigmoïde mais ça risque de faire vraiment long... peut être que dans un autre article nous nous intéresserons a cette dernière.

Enfin concernant le mode d'apprentissage, nous utiliserons un apprentissage supervisé. Nous n'avions pas beaucoup parlé de ce point dans nos précédents articles sur la classification [2] [4], ou nous avions élaboré un modèle basé sur une correction simple du vecteur des paramétrés portés par les dendrites du neurone. Ici ça sera l'occasion de découvrir la descente de gradient [5] et par la même occasion quelques fonctions de coût nous permettant d’évaluer l'efficacité de notre modèle.

Pour bien comprendre cet article, je vais d'abord en donner les lignes directrices:

  1. Tout d'abord, comme nous n'utilisons pas encore de frameworks spécifiques pour le machine learning (comme scikit-learn [6]) ou de framework de réseau de neurone comme Tensor-Flow [7] ou Keras [8]), il nous faut d'abord construire un  neurone, lui donner une implémentation pour la fonction d'activation, et lui donner une fonction d'apprentissage.
  2. Ensuite, nous tacherons de monitorer le neurone lors de son fonctionnement afin de nous permettre d'observer comment vont évoluer ses paramètres lors de l'apprentissage, et comment va évoluer son  efficacité en fonction de ses paramètres.
  3. Enfin, nous ferons une petite séance de visualisation de données sous python afin d'avoir des schémas explicatifs des données monitorées.

Voila, ça va être dense!

Le neurone

Nous en avions déjà fait un en python pour la classification. Ici on va aller a l'essentiel:

  • Un tableau de paramètre représentant les poids des dendrites (biais inclus).
  • Une fonction linearInfer permettant le calcul de la sortie du neurone (produit matricielle du vecteur d'entrée avec le vecteur des poids) inféré sur la fonction d'activation linéaire).
  • Une fonction d'apprentissage learnStep permettant la correction des poids selon des données étiquetés fourni par la classe Data
  • Quelques méthodes utilitaires comme la méthode reset permettant d'initialiser les données des poids de façon aléatoire.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Neurone {

    public Double[] dendrites;

    public Neurone(int inSize)
    {
        this.reset(inSize);
        System.out.println(this);
    }

    public void setParameter(Double v,Double b)
    {
        this.dendrites[0]=v;
        this.dendrites[1]=b;
    }

    public void reset(int inSize)
    {
        this.dendrites= Stream.generate(() -> Math.random()/1000).limit(inSize+1).toArray(Double[]::new);
    }

    public Double linearInfer(Double[] stepInputs)
    {
        ...      
    }

    public void learnStep(Set<Data> datasSet)
    {
        ...
    }

}


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class Data {

    public Double[] input;
    public Double output;


    public Data(Double[] input,Double output)
    {
        this.input=input;
        this.output=output;

    }
}

Nous voila donc une ébauche de neurone et une structure de données pour gérer les données d'apprentissage.