Site de domotique

Rencontrés aujourd’hui, au Maker Faire de Paris: des bloggueurs inspirés par la domotique qui ont développé le « Smart Board Sensors » : une interface à base de Arduino permettant d’interfacer facilement une foultitude de capteurs et d’y accéder via HTTP et JSON.

Sur le stand, il y avait notamment une démo avec des électrovannes et des hygromètres. ça m’a rappelé quelque chose…  http://www.domotique-info.fr/

Un drapeau français en ligne de commande

Suites aux événement du vendredi 13 novembre 2015 à Paris (où j’habite), j’ai envie de partager cette petite ligne de code à lancer dans un shell (en tout cas ça fonctionne en bash).

 t=$(($(tput cols)/3));for FR in $(seq $(tput lines));do printf "e[44m%${t}se[47m%${t}se[41m%${t}se[0mn";done # French Flag

Le résultat devrait être quelque chose qui ressemble à l’image suivante:

CLI French flag

Merci à Command Line Magic (@climagic) pour cette belle trouvaille.

Gamme pythagoricienne

Lors des derniers posts, on s’est quitté sur des considérations d’encodage de caractère, de détection de langue et d’API REST. Comme on dit en Papouasie-Nouvelle-Guinée: « Time flies » !

Pendant cet épisode silencieux, une événement s’est produit: j’ai découvert la guitare (un instrument de musique généralement à six cordes). Le silence était donc tout à fait relatif, le reste de la maison peut en témoigner… Bon, bref, l’objectif ici n’est pas de m’épancher sur ma nouvelle vie de rock star (auprès des mes chats, ça fonctionne bien) mais de partager ce que j’ai découvert en essayant de comprendre tout ce qui m’apparaissait arbitraire derrière les concepts de gamme, de ton, de demi-ton. Et pourquoi 12 demis tons (pourquoi pas 10 ou 16). Et puis, entre mi et fa, pourquoi ce hiatus impromptu? Comme on dit aux Malouines: « First things first« , alors commençons par le commencement.

Pour tout individu ayant été un tant soit peu en contact avec la musique occidentale, il y a 7 notes, soit Do, , Mi, Fa, Sol, La et Si en suivant la nomination de Guido , ou C, D, E, F, G, A et B selon la notation anglo-saxonne.  Après on recommence. Mais en plus aiguë. On repart de Do mais une octave au-dessus. D’autres systèmes existent mais ce n’est pas l’objet de cet article.

Tout de suite, on se dit hé, ben ouais, 7 notes, comme les 7 jours de la semaine, les 7 péchés capitaux, les 7 plaies d’Égypte, les 7 nains de Blanche-Neige, les 7 doigts de la mains, les 7 commandements, les 77 dalmatiens, etc. Je m’emporte. C’est un peu vrai. N’empêche que les trucs un peu cool et mystérieux viennent souvent en bande de 7 (comme les Tortues Ninja, les mousquetaires, les saisons , les 7 tomes d’Harry Potter, le 7e ciel, les atomes de carbone dans l’heptane et le Supplique pour être enterré à la plage de Sète).

Donc, on se dit « héhé, 7 c’est cool, c’est un nombre premier sûr, c’est un peu mystiquifianisant, etc. c’est pour ça qu’il y a sept notes dans notre gamme ». Comme aurait dit Ovide: « Que nenni! » En fait l’explication est ailleurs.

Bien qu’il y ait plusieurs sortes de gammes, il y a un principe généralement admis: quand on double la fréquence d’une note, on retombe sur la même note en plus aiguë (augmentée d’une octave). Corollaire: en divisant par deux la fréquence d’une note, on reste sur la même note mais une octave plus basse.

Par exemple, si on part du La à 440 Hertz on trouve:

\(440 Hz \times 2 = 880 Hz\) fréquence du La suivant. Aussi \(\frac{440 Hz}{2} = 220 Hz\): fréquence du La plus grave.

Description
Illustration de la plage de fréquence d’une octave

Donc, entre deux notes identiques séparées d’une octave on a un intervalle de fréquence. Intervalle à diviser (couper en rondelles) pour obtenir des notes intermédiaire. On pourrait tous diviser cet intervalle en \(2, 3, 7, 12, 17, 32\) ou n’importe quel nombre et inventer son système musical personnel. C’est un peu ce qu’a fait notre ami Pythagore.

Après avoir savamment observé son monocorde favori, il s’aperçut que les notes étaient rarement pures. Une note pure est produite par une onde sinusoïdale  unique, qui oscille à une fréquence audible, ce qui pour l’humain correspond grosso modo à la plage \(20 Hz-20 kHz\). En fait, de façon naturelle, un corps vibrant génère des harmoniques, c’est à dire des notes secondaires particulières. Sans doute parce qu’elles sont naturelles et qu’on les retrouve un peu partout un peu tout le temps, l’oreille humaine y trouve un certain réconfort. Une certaine harmonie.

Harmoniques

Les harmoniques sont des multiples entier d’une fréquence de base. Si notre fréquence de base est <e\(f\), les harmoniques seront \(0 f, 1f, 2f, 3f, 4f, 5f\), etc. Chacun des harmoniques (si si, harmonique est masculin). Par exemple, un son à \(0 Hertz\) produira respectivement les harmoniques de fréquences suivantes: \(0 Hz, 0 Hz, 0 Hz, 0 Hz\), etc. En d’autre mots: s’il n’y a pas de source sonore ,il n’y a pas d’harmoniques. C’est plutôt rassurant et corrobore plusieurs lois physiques, notamment en rapport avec la conservation de l’énergie.

Comme les premiers harmoniques ont tendances à être de plus forte amplitude que ceux plus loin dans le spectre, on se concentre généralement sur ces derniers.

Si on se concentre sur les premiers entiers naturels, on a 0, 1, 2, 3, 4, 5.

  • \(0 f\), c’est un peu intérêt et on ne peut pas en faire grand chose.
  • \(1 f\) s’appelle fondamentale puisque c’est la fréquence de base. Le fondement. On se rappelle que 1 est l’élément neutre de la multiplication, ce qui veut dire que \(1 \times f = f\). C’est d’ailleurs aussi vrai pour quelques autres valeurs tel que le rappelle le tableau ci-dessous.
Tableau de la multiplication par 1 de nombres célèbres
Une fois Nombre Résultat
1 X 0 0
1 X +∞ +∞
1 X -∞ -∞
1 X NaN NaN
  • \(2 f\), on l’a déjà rencontré, c’est la même note mais à l’octave. Comme c’est la même note, ce n’est d’aucune utilité pour construire une gamme.
  • \(3 f\) est le premier harmonique intéressant. Comme c’est le 3e, on l’appelle quinte. (En fait, il y a une autre raison qu’on verra plus loin). C’est le premier et le plus simple. C’est avec lui qu’on va construire notre gamme.
  • \(4 f\) est le double de 2f, donc l’octave de l’octave. Si on était parti du La à \(440 Hz\), on serait maintenant sur le La \( \left(2 \times 440 Hz \right) \times 2\), soit un La de \(1760 Hz\). Comme on reste encore sur la même note, ce n’est toujours pas utile pour notre gamme.
  • \(5 f\) est le second harmonique à produire une nouvelle note. Comme c’est le 5e harmonique, on l’a naturellement nommé tierce. D’ailleurs, en plus de faire des gammes, Pythagore faisait des accords (avec des orchestres de monocordes?) et ce qu’on appelle accord parfait est justement composé de la fondamentale, de la tierce et de la quinte.
Nomenclature des premiers harmoniques
0f 1f 2f 3f 4f 5f
rien  la fondamentale l’octave la quinte l’octave de l’octave (2X2f) la tierce

 

Une fois tout ça en place, on va se concentrer sur la quinte: le troisième harmonique, soit le premier harmonique à produire une nouvelle note.

Cette note de fréquence \(3 f\) est supérieure à \(2 f\). (on se souviendra que \(3 \gt 2\) et que \( f\) est strictement positif). Elle est donc en dehors de l’intervalle \(\left[f, 2f \right]\) sur lequel on veut construire une gamme. Heureusement, grâce à une propriété énoncée plus haut, on sait que cette note existe aussi sur une octave plus basse (plus grave). Pour descendre d’une octave on divise par 2 la fréquence, par conséquent \(3 f\) et \(\frac{3}{2}f\) sont une seule et même note (à l’octave près). Bien sûr, \(\frac{3}{2}f\) = \(1.5 f\); ce qui tombe bien sur une fréquence comprise entre \(f\)et \(2 f\). On a enfin généré une première nouvelle note pour notre gamme. Si la note de départ était un Do, 3/2f tombera sur le Sol. Do, , Mi, Fa, Sol: Il y a 5 notes entre Do et Sol, on appelle donc ça une pinte quinte. En fait, il n’y a que trois notes entre Do et Sol. Mais bon, pour aller de Do à Sol, il faut bien dire Do, , Mi, Fa, Sol, ce qui nécessite 5 notes. C’est comme ça qu’on en arrive à nommer le produit du 3e harmonique «quinte».

Grayé de cet algorithme, on peut réitérer de façon récursive le processus. On prend la quinte de notre quinte. Partant de Sol = \( \frac{3}{2}f \), on trouve \( 3\times \left( \frac32 \right) f = \frac92 f \). Pour revenir dans l’intervalle \(\left[f, 2f \right]\) on peut diviser par deux autant de fois que l’on veut, en l’occurrence ici on le fera deux fois pour s’arrêter à  \(\frac98f = 1,125f\). On a donc une série de multiplications par 3 des fréquences et de divisions par 2 pour ramener la note dans l’intervalle de l’octave. Dit autrement, la fréquence de chaque note dans notre gamme basées sur les quintes successives a la forme
$$\left(\frac{3^n}{2^m}\right)f$$

Illustration de la position des notes en fonction de leur fréquence
Répartition des notes sur une octave

 

p.s.: cet article est resté à l’état de brouillon depuis longtemps,  trop longtemps. Le choix éditorial du jour est donc de le publier en l’état. Sans toutes le conclusions sur les gammes tempérées ou non, sur la quinte du loup et sans les tables où l’on peut voir la correspondance entre Hertz et note. Ces dernières tergiversations pourront toujours venir en complément.

 

Retour sur le dongle WI-FI Edimax nano

L’adaptateur Wi-Fi Edimax EW-7811Un n’aime pas le chaud.

On se souviendra que dans les articles précédent, j’ai présenté le dongle Wi-Fi Edimax EW-7811Un. Il est tout beau. Il est tout petit. Il est reconnu par la Raspbian et sur Lego Mindstorm. En plus il coûte moins de 10€. Bref, il a tout ce qu’il faut.

Enfin presque. Dès qu’il a chaud il boude. Le dongle est donc très bien pour une utilisation occasionnelle dans une maison par exemple. Dans mon cas, il doit assurer la liaison 24/24 depuis le cabanon du jardin (là où il y la le contrôle des électrovannes et tout et tout). Ledit cabanon étant ce qu’il est, c’est à dire ni plus ni mois que bonne vieille shed des familles, sans isolation aucune, la température monte l’été largement au-dessus des specs présumées. Enfin, c’est la conclusion à laquelle je suis parvenu. Ayant passé une gros câble RJ-45 de la maison au jardin pour fin d’investigation, j’ai pu m’assurer que le Raspberry Pi était toujours alerte même lorsque le dongle tait mort. En ces occasions, seul un reboot physique permettant de récupérer le dongle. Il faut couper l’alimentation du système. Un soft reboot n’arrive pas à relancer le Edimax EW-7811Un.

J’avais commandé deux dongle identiques et j’ai eu le même comportement avec les deux dongles. Ma conclusion est non scientifique mais relativement étayée par les faits sur un échantillon de 2 observations. J’ai d’autres aspirations que de valider ma théorie par des tests de Student ce qui me demanderaient d’agrandir mon échantillon au-delà de ce que je suis prêt à pourvoir en ressources pour ce problème. D’un point vue plus pratique, j’ai acheté deux autres dongles Ouiphi. Je les ai testés. J’en ai gardé un pour sa facilité de configuration. Le premier (j’ai perdu la référence mais je pourrais la retrouver en fouillant dans mon historique de commandes auprès d’un plus grand fournisseur de tout et n’importe quoi en-ligne) ne voulait pas se configurer facilement sur ma Raspbian. Le second, dont la référence m’échappe au moment d’écrire ces lignes (mais qui pourrait être retrouvée si telle était ma volonté) s’est installé comme un charme, et n’a plus jamais décroché.

Conclusion:
Le dongle WI-FI Edimax EW-7811Un est mignon, il est tout petit, mais il craint la chaleur. Ou du moins, il craint d’être online trop longtemps (la chaleur comme source du problème étant une hypothèse probable mais pas entièrement démontrée). Je le conseille donc plutôt pour une utilisation occasionnelle. Si l’objectif est d’avoir du 24/7 (ce qui approche la valeur de 3,428571428571429 mais vous aviez compris que je ne parlais pas de ça), alors mieux vaut chercher un dongle un peu plus gros, mais un peu plus robuste.

Unicode, UTF-8 et autres considérations

Unicode, UTF-8 et autres considérations

Comme mentionné précédemment, manipuler du texte en différentes langues nécessite  de s’intéresser au codage des caractères. Il y a beaucoup de choses  à dire sur l’ASCII (version originale à 7 bits, puis étendue à 8 bits), sur l’Unicode et les différentes façon de représenter les caractères. Mais Internet est là pour ça et beaucoup l’ont expliqué mieux que je ne saurais le faire.

Concentrons nous donc sur le problème concret de la création d’histogramme de n-gram à partir de caractères UTF-8. Selon votre langage de programmation favori, un caractère peut avoir différentes significations.  En C et comme dans beaucoup de ses dérivés, un « char » est une suite de 8 bits. C’est donc simplement un nombre entier compris entre [-127, 128] ou [0, 255] selon qu’on le considère signé ou non-signé. C’est tout. Fin de l’histoire. Il n’y a aucune notion de représentation derrière, un caractère est un entier défini sur un domaine restreint de 256 valeurs.  Ça tombait plutôt pas mal, le standard ASCII, après une mise à jour, associait une lettre, un élément de ponctuation, un chiffre, un caractère à chacune de ces 256 valeurs possibles. La plupart des langues basées sur l’alphabet latin peuvent être couvertes avec 256 symboles (sachant qu’il faut aussi garder de la place pour le chiffres, la ponctuation, des signes essentiels comme $, £, &, @, % et autres #. En y ajoutant quelques symboles qu’on ne voit pas mais qui sont nécessaires (comme le changement de ligne (0x0D), le son de cloche (0x07) ou le 0x15  NAK « negative acknowledge », on remplit rapidement l’espace disponible. Notons que l’euro (€) n’existait pas à l’époque, donc le symbole n’est pas inclut dans l’ASCII. On le retrouve grâce à l’Unicode.

256, c’est joli mais c’est petit

En fait, toutes les langues utilisant un alphabet latin ne peuvent pas s’écrire avec 256 symboles (moins les trucs bizarres comme le NAK). Si on met les ğ et Ş turcs, il n’y a plus de place pour les Ð, Þ ou æ islandais par exemple. Et puis vous savez quoi ? Il y a une multitude de langues qui n’utilisent pas l’alphabet latin ! Déjà que l’ascii ne couvrait pas toutes les déclinaisons de cet alphabet, on peut imaginer le problème des alphabets inuitcyrillyquehindî, grec, arabe ou hébreux et plus encore des idéogrammes asiatiques tels les sinogrammes ou les hiraganas.

On veut des bits

Naturellement on se dit qu’il n’y a qu’à rajouter des bits. En effet, en passant à seize (16) bits par caractères, on atteint un potentiel de 65536 symboles différents. En passant à 32 bits, on ouvre les mode des possibles à plus de 4 milliards de lettres/symboles/idéogrammes/smileys.

Bref, tout ça pour dire que l’UTF-8 peut représenter l’ensemble des caractères des langues naturelles en utilisant un nombre variable d’octets. Pour les 128 symboles de l’ASCII de base (2 7 bits = 128 possibilités) tout se passe comme il faut, un seul octet est nécessaire. Ça couvre l’anglais, la ponctuation et quelques autres caractères fondamentaux comme l’inénarrable barre verticale « | » (0x7C).

Mais me direz-vous, octet, octant, octogone, octopode ça me rappelle vaguement le nombre huit. Et bien oui, le huitième bit de l’octet UTF-8 sert à signaler qu’on est dans un cas spécial et qu’il faut combiner les bits déjà lus avec ceux de l’octet suivant pour retrouver notre caractère qui est donc en dehors du domaine des 128 codes de base. Le second octet ayant évidemment lui-même un bit signalant la possibilité d’aller voir chez l’octet suivant et ainsi de suite jusqu’à… 4. Donc un caractère codé en UTF-8 est une suite de 1, 2, 3 ou 4 octets.

L’UTF-8 a beaucoup d’avantages et est largement répandu sur Internet. Je fais donc le Postulat numéro 1 (ou serait-ce un axiome?) que les données d’entrées seront codées de cette façon. Si ce n’est pas le cas, la pléthore d’outils permettant la conversion d’autres systèmes vers UTF-8 permettra, via un pré-traitement des données, de s’assurer de la validité dudit postulat.

Mais alors, c’est quoi un caractère ?

Ça peut être beaucoup de chose. Twitter s’est d’ailleurs posé la question puisque leur mission est de les compter jusqu’à hauteur de 140 (un nombre abondant). Leur définition semble satisfaisante pour les besoins de création de n-gram. Grosso-modo, un unigramme est un « code point« , c’est à dire un ensemble de 1, 2, 3 ou 4 octets représentant une lettre, un idéogramme, un symbole.

Ce n’est pas parfait parce que l’Unicode permet la composition. Par exemple, pour faire ê, il y a plusieurs chemins. La lettre e peut être accentuée, c’est dire qu’une séquence comprenant 2 code points peut être utilisée (un « e » suivi d’un « ^ » ou vice versa, j’en sais trop rien) ou bien on peut aussi coder directement le symbole ê. C’est un exemple de non-orthogonalité flagrante selon une de ses définitions en informatique (2 façons d’arriver au même résultat). L’autre définition portant sur les effets collatéraux d’un appel de fonction sur un appel précédent. C’est dans le même esprit mais je m’égare…

Idéalement, tous les diacritiques devraient être normalisés pour être codés sous la même forme. Mais le postulat numéro 2 dit que ce n’est pas nécessaire. D’ailleurs, l’intérêt est de voir si ça marche avec n’importe qu’elle entrée ayant été le moins pré-traitée possible. Si ça ne fonctionne pas, on remettra en cause le Postulat numéro 2. Pour l’instant, on considère que le système sera assez robuste pour être efficace malgré le biais induit par les différents codages d’un même glyphe. Si ça se passe mal, on rétrogradera le postulat en hypothèse qu’on infirmera. Pour l’instant allons de l’avant.

La ponctuation ?

Les points, point d’interrogation, virgules sont de bons indicateurs de fin ou de début de mot. Ils sont donc utiles puisque selon les différentes langues, les lettres n’ont pas la même fréquence en début ou en fin de mot. L’espace (un nom féminin dans ce contexte !) joue donc aussi un rôle important et doit être considéré comme un caractère à part entière. Cependant, selon l’origine du texte, on peut se retrouver avec des suites de 2, 3 voire 10 espaces consécutives. Le trigramme  »    » (3 espaces à la queue-leu-leu) est même le plus fréquent avec les données Wikipedia pour le français et l’anglais sur mes premiers tests. C’est un facteur qu’il faudra prendre en compte.

Et concrètement ?

Tout ça pour dire que j’ai trouvé une façon simple de regrouper des unigrammes, des bigrammes et des trigrammes malgré le fait que chacun des code point soit en fait une une chaîne  de caractères. Merci à cette librairie qui permet d’itérer sur les code points tout en gardant l’accès aux positions des octets sous-jacents.  De cette façon, on peut avancer de un, deux ou trois caractères pour former les n-grammes et construire une std::string à partir des positions des octets. L’histogramme se bâtit en incrémentant les valeurs d’une std::map où la clef est une std::string et la valeur un compteur (int, long long, etc.)


#include <fstream>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>

#include "utf8/utf8.h" //http://www.codeproject.com/Articles/38242/Reading-UTF-with-C-streams

typedef std::map<std::string, int> histotype;
typedef std::pair<std::string, int> histonodetype;

void PrintGrams(const histotype& gram)
{
    std::vector<histonodetype> vectgram;

    std::copy(gram.begin(), gram.end(), std::back_inserter(vectgram));
    std::sort(vectgram.begin(), vectgram.end(), [](const histonodetype& left, const histonodetype& right){return left.second < right.second;});

    for(auto elem : vectgram )
    {
        std::cout << elem.first << " " << elem.second << std::endl;
    }
}

int main(int argc, char** argv)
{
    std::ifstream in(argv[1]);
    std::string line;

    histotype unigram;
    histotype bigram;
    histotype trigram;
    while( std::getline(in, line))
    {
        typedef  decltype(line.begin()) ittype;
        utf8::iterator<ittype> it(line.begin(), line.begin(), line.end());
        utf8::iterator<ittype> endit (line.begin() + line.size(),
                line.begin(), line.begin() + line.size());

        if(it==endit) // check for end of line
            continue;

        auto unibeg = it;
        auto bibeg = it;
        auto tribeg = it;

        it++;

        unigram[std::string(unibeg.base(), it.base())]++;
        it++; unibeg++;
        if(it==endit) // check for end of line
            continue;

        unigram[std::string(unibeg.base(), it.base())]++;
        bigram[std::string(bibeg.base(), it.base())]++;
        it++; unibeg++; bibeg++;
        if(it==endit) // check for end of line
            continue;

        for(;it != endit; it++, unibeg++, bibeg++, tribeg++)
        {
            unigram [ std::string(unibeg.base(), it.base())]++;
            bigram  [ std::string(bibeg.base(), it.base())  ]++;
            trigram [ std::string(tribeg.base(), it.base()) ]++;
        }
    }

    PrintGrams(unigram);
    PrintGrams(bigram);
    PrintGrams(trigram);

    return 0;
}
Programme de création de n-grammes

Ce code compile avec une version récente de gcc (il y a quelques éléments de syntaxe du c++0x11). C’est une preuve de concept, pas du code de production, mais si vous voulez expérimenter la génération de n-grammes, c’est un bon point de départ.

Pour ma part j’ai testé quelques 100 000 lignes en français et en anglais venant de Wikipedia (avec et sans les tags XML) et malgré les biais induits par les nombreuses suites d’espaces et les séquences spéciales pour mettre en forme le texte sur Wikipedia (les [[[,  »’, et autre), on voit déjà poindre les « de  » et « ng  » en pôle position pour respectivement les trigrammes français et anglais.

Le choix et le pré-traitement des corpus d’apprentissage sera un dossier en soi, mais d’ici là, je compte travailler sur le stockage des résultats (peut-être avec SQLite) et leur mise à jour (peut-être via une API REST.

 

Identification de la langue d’un texte

 Identification de la langue d’un texte

Récemment, un article m’a rappelé qu’il était serait amusant de faire un système pour détecter de manière automatique la langue dans laquelle un texte est écrit. L’article en question parlait de complètement autre chose et ne faisait que reprendre les résultats d’un blog anglophone. Cependant, en présentant d’une certaine façon les distributions d’occurrence des lettres au sein de quelques langues européennes, je me suis souvenu que ces distributions donnaient une signature qu’on pouvait utiliser pour reconnaitre la langue d’un texte. Ce peut aussi d’ailleurs être utilisé pour briser les codes simples comme le chiffre de César tel que Simon Singh nous l’expliquait dans son excellent livre sur l’histoire des codes secrets.

Pour créer les signatures, on peut analyser la fréquence d’occurrence des lettres individuelles, mais aussi des séquences de deux lettres consécutives. Par exemple en français, la séquence « ch » est plus fréquente que « sh » ou « cz ». D’autres langues présenteront d’autres proportions pour ces même suites. Et pourquoi s’arrêter à deux ? On peut aussi répertorier les séquences de trois, quatre ou N lettres consécutives. C’est ce qui s’appelle des  n-grams. Ça ne se résume pas qu’aux lettres et ça ne sert pas qu’à détecter une langue, mais c’est le contexte dans lequel le présent projet va les utiliser.

Sommairement, il s’agit donc de :

  • Créer des signatures basées sur les n-grams pour différentes langues
  • Extraire la signature d’un texte inconnu dont on veut identifier la langue
  • Comparer sa signature avec celles des langues « apprises »
  • En déduire l’idiome du texte

La signature n’étant que l’histogramme des fréquences d’occurrence des différents n-grams.

Heu… mais pour quoi faire ?

Clarifions tout de suite un point : je n’en ai personnellement aucune utilité. Ce n’est ni lié à des sujets professionnels, ni à un quelconque outil qui pourrait me servir. La recherche sur le sujet est bien avancée et je ne cherche pas à l’approfondir. Tous les jours on peut d’ailleurs voir à l’œuvre des sites qui ont de très bons résultats dans le domaine. Cependant, la (relative) simplicité de mise en œuvre d’une solution à un problème qui peut sembler aussi complexe est fascinante.  C’est donc en pur dilettante que j’ai envie de jouer un peu avec ce problème.

D’un autre côté, bien que la solution soit conceptuellement simple, quelques détails pratiques font qu’il y a tout de même quelques petits défis à relever et questions à répondre. Comment trouver des données d’apprentissage ? Comment gérer les caractères internationaux, l’Unicode et les codages à nombre variable d’octets (par exemple l’UTF-8) ? Que faire de la ponctuation, des espaces, ou même des tags HTML dans le cas où les données viendraient de source web ? Quelle technique choisir pour mesurer la similarité des signatures (vecteurs de cardinalité et de dimensions différentes) ? Comment présenter les résultats ? Bref, suffisamment d’interrogations pour rendre le projet intéressant.

 Étapes du projet

Avant de me lancer, j’ai détaillé sommairement les grands blocs ou thèmes sur lesquels il faut travailler. Je les présente ci-dessous, sachant que cela n’a rien de formel. Ce découpage est relativement orthogonal, ce qui permet de travailler indépendamment sur un sujet ou un autre.

    • Création des bases de données
      1. Obtenir des sources de texte
      2. Analyse des langues
      3. Stockage des résultats
    • Reconnaissance de la langue
      1. Analyse et création des signatures
      2. Comparaison avec les signatures en base de données
      3. Calcul des estimations de probabilité pour chaque langue
    • Interface et interaction
      1. Soumission des données à analyser
      2. Mise à jour de la base de données
      3. Affichage des résultats

 État des lieux

Corpus d’apprentissage

J’ai quelques pistes pour les corpus d’apprentissage. J’ai expérimenté un peu avec Wikipedia qui permet de télécharger l’intégralité de son contenu à un instant t. C’est trié par langue et de nombreuses langues sont disponibles. Pour récupérer le contenu de Wikipedia, c’est mieux que :

quirysse@beluga:~$ wget --random-wait -r -p -e robots=off -U mozilla http://en.wikipedia.org/wiki/Main_Page

Le problème c’est que c’est gros. Très gros.

wilhelm@beluga:~/WikiCrawl$ ll -h *xml
-rw-r--r-- 1 wilhelm woodself 46G Jul  9 00:58 enwiki-latest-pages-articles.xml
-rw-r--r-- 1 wilhelm woodself 12G Jul 16 21:00 frwiki-latest-pages-articles.xml
wilhelm@beluga:~/WikiCrawl$
Espace occupé par deux langues sur Wikipedia

 

De plus, les fichiers sont codés en XML dans le langage de Wikipedia, ce qui après quelques tests, même après avoir enlevé les tags XML, on trouve beaucoup d’occurrences de  » [[ »  et autres balises du genre. Ça reste quand même une option mais un peu de préparation de la base de données s’avèrera nécessaire. Il y a une piste avec European Parliament Proceedings Parallel Corpus 1996-2011. C’est d’ailleurs ce qui a été utilisé dans l’article cité plus haut.

Analyse

La génération d’histogrammes d’unigrammes, de bigrammes et de trigrammes n’est pas un souci en soi. Cependant, il faut penser au codage Unicode et comme l’UTF-8 semble tout indiqué, il faut gérer le fait qu’un caractère puisse être composé d’un nombre variable d’octets. Un article complet sur le sujet est en préparation, puisque grâce à cette bibliothèque on peut arriver rapidement  à une solution.

Stockage

Les histogrammes, on en fait quoi ? Ils peuvent être longs à générer. On peut vouloir les mettre à jour en utilisant de nouveaux corpus et de nouvelles langues. Alors SQL, fichier maison ? A voir.

Détection de la langue

De façon naturelle on pense au cosinus, mais ça cause certaines difficultés. Je pense plutôt à une erreur RMS ou une distance euclidienne sur les dimensions présentes dans le vecteur d’entrée. Et puis qu’est-ce qu’on fait des hapax et des n-grams très rares. On les garde ou on nettoie le vecteur d’entrée ? Rien n’est fixé mais on en reparlera.

Interface

Évidemment, tout commence toujours pas une série de petits scripts bash et 2 ou 3 mini programmes en C++. Mais au final, une API REST pour obtenir les probabilités des différentes langues sachant une signature pour un texte en entrée, ça serait sympa, non ? Et une page web où l’on verrait les probabilité évoluer en même temps qu’on entre du texte dans un champ, ça serait encore mieux ! C’est un dossier qui est encore un peu loin, mais il y a du potentiel pour faire un système agréable. Pour l’instant, on va en rester au bash…

Conclusion

Donc, voilà où on en est. L’UTF-8 est à peu près réglé (article à suivre). Reste à faire le reste. C’est à dire, à peu près tout…

Framboise en boîte 5/N

Préambule

Bon, il fait beau, il fait chaud, on a tous le soleil dans les yeux et le sourire aux lèvres… Surtout, mes plants de tomates ont 5 pieds de haut, il est grand temps de terminer ce post préparé au mois de mai (déjà, mais qu’est-ce que le temps passe). Donc voilà, on conclut sur l’installation de l’arrosage et on passe à autre chose. En fait, il restera la partie où notre amie la Framboise Magique se connecte à Internet pour déterminer toute seule le moment idoine

C’est en creusant qu’on devient creuseron (du verbe creuserer)

Après avoir validé les différents sous-systèmes, il est temps de mettre en place l’arrosage proprement dit. C’est à dire qu’il y a un moment où le geek intérieur doit laisser la place aux pulsions du cerveau reptilien et que, tel le mammouth creusant son nid, le jardinier numérique doit prendre sa pelle et sa pioche afin de libérer l’espace nécessaire au creux de notre bonne vielle Terre afin d’y installer des vannes et des tuyaux.

 Galerie de quelques étapes creusatoires

J’y vais un peu dans le désordre. En gros, pour enterrer des tuyaux, il faut faire des trous. Je laisse le soin à chacun de trouver sa façon de faire. Tous les goûts étant dans la nature, ce n’est pas un terrain sur lequel j’ai envie de m’avancer. On déplace de la terre, on la remplace par des tuyaux et on rebouche, le tout avec le modus operandi choisi.

Et les électrovannes ?

Qu’est-ce qu’on fait avec les électrovannes ? On les enterre comme un vulgaire tuyau de polychlorure de vinyle ?   Que nenni ! On les protège, les chouchoute, on leur creuse un nid. Donc, on fait un gros trou, rond ou carré. Ça dépend du nid choisi. Le nid en question s’appelle un regard pour électrovanne. C’est un caisson fait pour accueillir des choses enterrées avec divers trous permettant le passage des tuyaux et des gaines électriques. L’astuce c’est qu’une fois ledit caisson mis en terre, on garde un accès à son précieux trésor via une trappe, un regard. Tout est dans tout. Le regard pour électrovanne accueille des fils électrique (électro), des tuyaux (vanne) tout en préservant un accès depuis le monde  des vivants (le regard).

Comme souvent quand on met les doigts dans la flotte, on pense au drainage. En l’occurrence, un grosse poche de gros cailloux à moins de 10€ pour 25 kg fera l’affaire (Les gens biens appellent ça gravillon, c’est joli et ça rime avec papillon. Ça n’en reste pas moins qu’un tas de cailloux).

Donc les cailloux vont au fond du trou. Ensuite on met les vannes, on passe les câbles électriques (contrôlés via les relais et le Raspberry Pi mais on l’a vu dans les chapitres précédents). Il y a même de l’information en-ligne sur la mise en place des ces fameux regards.

Les dangers du monoxyde de dihydrogène

C’est au moment de brancher les câbles électriques sur les électrovannes qu’on réalise que, malgré le drain caillouteux, la pérennité du système semble mitigée.  On pourrait se dire : il fait beau, mon trou est rempli d’air sec, un domino et puis basta. Mais que se passera-t-il lorsque la bise sera venue et amènera avec elle des litres d’eau à en saturer ma terre nourricière ? Eh ben c’est simple, le monoxyde de dihydrogène (rempli de sels ionisés et donc conducteur) fera en sorte que l’installation s’autodétruira, en créant au passage un tremblement de terre,  des famines, des électrocutions massives et toutes sortes d’autre horreurs dont l’honnête citoyen que j’essaie d’être ne peut porter la responsabilité sur ses frêles épaules. Il possible que ce soit moins dramatique mais ce n’est pas certain. Le principe de précaution m’a donc amené à trouver une solution simple: le connecteur étanche. Il s’agit d’une mini-éprouvette remplie de gras dans lequel on vient planter une marette. Le gras n’étant hydrosoluble (à moins que ce ne soit l’eau qui soit lipophobe), une fois les conducteurs engoncés dans le gras, ils sont à l’abri des assauts de l’eau.

Varia

Pour les tomates, j’ai installé un tuyau poreux enterré qui répand l’eau directement sous les racines des plants. Comme ça, on minimise l’évaporation et les risques de différents champignons qui peuvent se former sur le feuilles des tomates trop humides.

J’en ai profité pour installer sur le réseau hydraulique un peu de tuyau goutte-à-goutte. Tant qu’à faire, aussi bien rassasier les géraniums en même temps que le reste…

Le rythme de tomates  n’étant pas nécessairement celui de la pelouse, j’ai installé quelques tuyères sur un second circuit pour cette dernière. Donc 2 relais, 2 électrovannes et 2 programmes d’arrosage.

Et maintenant ?

Maintenant, les plants de tomate sont grands mais pas encore leurs fruits. La pelouse n’a jamais été aussi verte. Ça marche. Cependant, le contrôle se fait encore avec un bon vieux crontab des familles. Je suis donc arrivé au même point du point de vue fonctionnel que si j’avais acheté un programmateur d’arrosage sur le marché. C’est tout de même un peu différent puisque personne à part moi ne peut faire le ssh qui va bien via la tablette numérique et commander l’arrosage. C’est une lourde responsabilité. Par contre,  lors de nos barbecues mondains, l’effet est tout à fait réjouissant. En effet, faire jaillir l’eau sur la pelouse depuis sa tablette et lui commander de retourner d’où elle vient du bout des doigts permet d’avoir une petite minute de gloire entre deux merguez.

Donc la suite sera sans doute de faire une interface web pour contrôler plus facilement facilement l’installation. Mais surtout, de surveiller le web pour connaître la météo et de décider automatiquement s’il faut arroser ou non. Là, on aura un système vraiment intéressant.

Ce sera la prochaine étape du projet arrosage (pour ceux qui ont suivi, N sera donc supérieur ou égal à 6). Mais d’ici là, je pense que je vais commencer un autre truc qui me démange… Mais il est tard, on en parlera une autre fois.

 

<– Précédent –|

Un peu de selfies en 3D

Ça y est, Google IO est en route et les annonces sont faites. Permettez-moi donc de publier mon selfie fait avec le prototype de Google Tango. La couleur matérialisant ici la carte des profondeurs (des distances). En arrière plan, on voit l’image capturée par la caméra RGB.

Selfie avec un Google Tango
Selfie avec un Google Tango

Rien de grandiose d’un point de vue artistique (quoiqu’ une certaine inspiration Pop Art puisse en ressortir) mais l’effet est plaisant.

Puisqu’on est dans les selfies et que j’avais  un Trimble TX8 ce week-end à la maison, j’en ai profité pour réaliser cette petite photo de famille devant le parasol du jardin.

Selfie 3D dans le jardin avec un Trimble TX8

Pour terminer, comme il y a toujours un chat qui traîne dans le coin, j’ai aujourd’hui retrouvé Diderot dans mes données scannées…

Framboise en boîte 4/N

Le futur

Dans cet article, nous aborderons les technologies futuristiques (à ne pas confondre avec futuristes) des drivers FTDI qui permettent à notre sympathique framboise de communiquer avec ses relais (là, le s s’avère nécessaire réforme ou pas1 ).

Retour sur l’Arros-o-tron

La dernière fois, nous avons testé l’ensemble de contrôle des relais avec de la vraie eau, tout à fait vraiment vraie (et humide). Malencontreusement, quelques digressions annexes nous ont fait perdre le focus (qui a la fâcheuse propriété d’être évanescent) et la conclusion s’en est allée. Cette conclusion, je vous la donne donc directement en introduction du l’article N+1 (N est ici tout à fait déterminé, il s’agit du nombre 3.  À ne pas confondre avec N, le nombre total d’articles sur le sujet qui nous occupe, qui lui n’est pas encore déterminé. Ou peut-être que si, dans l’hypothèse où vous liriez cet article dans le futur par rapport à maintenant. Peut-être  n’avons-nous pas le même maintenant. Nous verrons d’ailleurs plus loin comment FTDI  a répondu à cet opaque problème. Mais enfin, je m’égare).

Donc oui, ça marche. On contrôle très bien l’électrovanne à partir de l’alimentation 12V et du relai. L’eau jaillit et se tarit à souhait à partir de simples commandes (connexion ssh sur le Rapsbperry Pi et quelques commandes UNIX).

Ce ne sera pas la configuration finale, mais pour ce premier test arrosatoire, j’ai utilisé une électrovanne 24 VAC. Je l’ai commandée à partir de mon alimentation 12 VDC (voir article premier). Pas très orthodoxe, mais je suis parti de l’hypothèse que les tensions nominales sur n’avait pas à être franchement respectées. Selon notre ami Maxwell (rien à voir avec le café), s’il y a du courant dans la bobine, on pourra faire bouger un truc en utilisant la force du champ magnétique induit par le passage des électrons enivrés par les enroulements de notre conducteur. Jamais dans ses équations est dit qu’on doive respecter les tensions nominales de notre fournisseur de solénoïdes. Je fais sans doute quelques raccourcis, mais toujours est-il que ça marche (d’ailleurs pour ce test, j’ai bien appliqué 12 volts en courant continu alors que nominalement on requérait du courant alternatif, na!)

Contrôleur du travail

Les électrovannes en tant que telles pourront d’ailleurs être l’objet d’un article ultérieur tant il y a à dire sur cet objet contrôlant le travail. En effet, en autorisant ou interdisant le déplacement de masses d’eau, la vanne contrôle le travail (on se souviendra qu’il y a vaguement un lien entre la force (qui peut elle-même être liée à la masse) et le déplacement). Les joyeux jaillissements de l’eau à travers mon tuyau sont donc du travail. Et comme toute peine mérite salaire, Veolia ne manque pas de se faire rétribuer à chacune de mes saillies.

 Le contrôle de la carte à relais

Nous avons déjà dit que la carte USB-X440 était munie d’un connecteur USB (et de cinq trous de quatre millimètres, mais ce dernier constat n’intervient que très peu, ou pas du tout, sur le sujet précis qui nous occupe dans cette section). En fait, la carte USB-X440 communique en série. Oui, oui, ce bon vieux port série, le RS-232, les stop bit et start bit, la parité, le baud, et tout et tout. A priori, rien de très sexy. C’est là que la technologie du future entre en jeu.

FTDI produit des chips qui permettent d’émuler une communication de type RS-232 à travers un support USB.

Petit mot sur le futur

On se souviendra que dans les années 1990, et même avant, plusieurs entreprises ajoutaient le suffixe 2000 à leur raison sociale ou à leurs produits. Du système d’exploitation au plombier du coin, tous étaient résolument tournés vers l’avenir et la modernité. Tout le monde voulait son 2000. C’était dans l’air du temps, et si l’on a moins de 20 ans, on ne s’en souvient guère. Cette bohème ne pouvait pas durer éternellement parce qu’elle avait un défaut intrinsèque: le temps passe, les années changent, et le futur d’hier devient le passé d’aujourd’hui. Si Windows 2000 n’est plus qu’un (plus ou moins bon) souvenir, tous les chauffagistes 2000, les menuisiers 2000 et autres assureurs 2000 qui ont survécus sont passés de visionnaires à passéistes, tournés à jamais vers une époque de plus en plus lointaine.

FTDI a trouvé la solution. Bien qu’issue des années 1990, cette entreprise est à jamais tournée vers l’avenir, puisque son point de fuite n’est pas une année déterminée, mais bien le futur en personne. Ce futur qui dès maintenant et pour toujours sera invariablement devant. FTDI est en effet l’acronyme de Future Technology Devices International ce qui se traduit (assez librement) par: « Bidules internationaux basés sur la technologie du futur ». Le problème de la relativité temporelle est donc résolu. Peu importe le point de vu, FTDI sera toujours devant.

Le port série automagique

Quoi qu’on en dise, les circuits FTDI on plusieurs atouts :

  1. Ils permettent une communication simple à travers une connectique standard (USB était encore répandu au moment d’écrire ces lignes, bien que cela paraisse incongru au lecteur d’un certain futur)
  2. Les spécifications sont ouvertes et il est donc aisé d’écrire les pilotes idoines
  3. Ils sont supportés nativement par tous les bons noyaux près de chez vous

Ce troisième point est particulièrement intéressant. C’est la pierre d’achoppement du l’automagicité. En effet, il suffit de relier la carte munie du chip FTDI  à son ordinateur (en l’occurrence, un Raspberry Pi faisant tourner une distribution Raspbian) pour n’avoir rien à faire… En fait le pilote papote avec le chip. Chacun fait sa tambouille de son côté. On finit par s’entendre sur un truc du genre 9600 8N1. Et hop, on se retrouve avec un device dans /dev/ttyUSB0

pi@nsa ~ $ ls /dev/ttyUSB0
/dev/ttyUSB0
pi@nsa ~ $

On a donc une émulation de port série, installée en quelques millisecondes, sans aucune configuration. C’est à ce demander à quoi sert de faire un blog pour en parler tellement l’opération est sans douleur.

Du coup, de façon tout à fait classique, pour envoyer une commande à la carte, on écrit dans /dev/ttyUSB0 et, symétriquement, on lit dans /dev/ttyUSB0 pour recevoir des messages (le zéro (0) pouvant bien entendu être incrémenté si plus d’un port USB émulé est présent).

D’après la documentation, la relais se commandent ainsi:

Sxb

S veut dire relai (switch?)

x, le numéro du relai

b, une valeur booléenne (0 ou 1) pour changer l’état du relai.

Il suffit donc d’écrire dans sa commande dans le tty pour pour commander une action, en utilisant echo par exemple.

Cela donne donc, comme on l’a vu précédemment:

Relai #1 au repos:

pi@nsa ~ $ echo S10 &gt; /dev/ttyUSB0

Relai #1 actif:

pi@nsa ~ $ echo S11 &gt; /dev/ttyUSB0

Pour écouter ce que nous dit la carte, on utilisera cat :

pi@nsa ~ $ cat /dev/ttyUSB0

La suite

On se rendra donc bien entendu à N 5 puisque nous n’avons pas encore abordé l’installation du circuit hydraulique, le creusage dans le jardin ni la plantation de tomates.

<– Précédent   Suivant –>

Framboise en boîte 3/N

Reality-check: la confirmation de tous nos espoirs

Pour résumer les épisodes précédents, on a :

  • Un objectif, celui de contrôler l’arrosage du jardin via une carte Raspberry Pi
  • Une installation au fond de ma cabane en Île-de-France avec un boîtier électrique hébergeant un Raspberry Pi et une carte avec 4 relais (et cinq trous de quatre millimètres), le tout connecté au reste du monde via l’isthme d’un µ-dongle WI-FI.

Après avoir eu la confirmation que l’installation pouvait contrôler une lumière alimentée sur 230 VAC, on voudra maintenant voir ce qu’on peut faire avec une électrovanne et de la vraie eau. Cet élément étant généralement plutôt humide, sa maîtrise via un circuit électrique asservi à une commande bash semble, sinon improbable, à tout le moins incongrue.

(intermède dédouanement lexico-sémantique)

On se souviendra qu’avant Mendeleïev, le tableau périodique des éléments n’en contenait que 4 ou 5, soit :

Symbole de l'eau Symbole de feu Symbole de la terre Symbole de l'air Bonus
Eau Feu Terre Air Quintessence (éther)

donc l’eau peut belle et bien être qualifiée d’élément humide, tout n’est qu’une question d’époque. On signalera au passage qu’il fut un temps où les cours de chimie étaient plus simples qu’aujourd’hui.

Validation aqueuse

Validons donc ce qui reste à valider: la mise en mouvement de moles de molécules d’eau grâce à l’installation Raspberry Pi + carte relais

(dédouanement second, c’est le temps)

Relais ou relai ? C’est compliqué et simple. Pour toutes sortes de raisons, l’Académie fait du lobbying pour la forme relai au singulier (comme balai) depuis un bon moment (réforme orthographique de 1990). La même année, Pixies sortait Bossanova et Jane’s Addiction disait Stop! (chacun son truc). C’est dire si ça fait longtemps qu’on peut écrire relai sans s. Comme c’est encore difficile à avaler pour nombre de nos contemporains, on a le droit d’écrire les deux formes. On fait ce qu’on veut. C’est la fête du slip, comme aurait dit Confucius.  Cependant, ce qui un peu plus moins permis, c’est de faire comme l’auteur de ces lignes, à savoir de papillonner d’une forme à l’autre…

Suite

Au rythme où ça va, affirmons tout de suite que N 4…

<– Précédent —  Suivant  –>

Site sur le bricolage, la bidouille et l'informatique