XD blog

blog page

2013-09


2013-09-29 Zoomer sur graphe XY avec d3.js

d3.js est un framework écrit en javascript qui permet de visualiser des données. Il est conçu pour des sites web et permet de créer des graphes animés. Le résultat est assez esthétique à en juger par les différentes galleries :

Tout d'abord, je dois dire que ça prend du temps de concevoir un graphe. Mon objectif était de créer un graphe XY et de pouvoir zoomer horizontalemen sur une partie. Quand on découvre l'outil et les spécifités de javascript, il est préférable de partir d'une exemple qui fonctionne déjà sans trop chercher à aggréger des bouts de codes venant de plusieurs graphes. L'exemple que j'ai trouvé pour le zoom vient d'ici : js fiddle. Appliqué à mes données, cela donne :

Les premiers pas sont tout de même assez longs, les erreurs ne sont pas faciles à comprendre, surtout quand on est novice. On espère que ce graphe qu'on est en train de constuire pourra resservir. Cela dit voici, quelques astuces.


more...

2013-09-28 Utiliser l'API Linkedin

J'ai utilisé l'API Linkedin pour voir s'il était possible de récupérer mes contacts et de les mettre dans un fichier Excel. Tout d'abord il faut récupérer une clé d'identification en suivant les instructions décrites REST. Cette clé vous donne la possibilité de consulter votre profil, d'effectuer des recherches, de récupérer la liste des contacts, de faire tout ce que votre compte vous permet de faire excepté que vous pouvez le faire jusqu'à un certain point. Par exemple, je peux récupérer l'intégralité de mes contacts, mais je ne peux effectuer qu'une dizaine de recherches et récupérer pour chacune d'entre elles les 110 premiers résultats. La limite de 110 dépend de votre compte (le mien est un compte gratuit), le nombre de résultats de recherche dépend de votre compte développeur (throttle limits). Il est possible d'étendre cette limite mais il faut devenir Partner (Request for Partnering with LinkedIn) mais je ne suis pas allé jusque là. Cela dit, les compteurs sont remis à zéro tous les jours.

Après avoir effectué quelques essais, on s'aperçoit qu'il est impossible d'accaparer des données auxquels votre compte ne vous donne pas accès. D'un point de vue utilisateur, c'est l'assurance qu'un programmeur n'aura pas accès à d'autres informations que celles dévoilées par votre profil public. Elles le seront simplement sous une autre forme (un second site web, uune feuille Excel...)

La clé que j'ai requise est une clé développeur. Elle permet de développer (un site web par exemple) mais ne permet pas de passer à l'échelle. Pour d'autres usages, il faut regarder le site Linkedin Developers.

Le code que j'ai utilisé est écrit en Python et accessible ici, documentation. Pour des pages, il est préférable d'utiliser les outils javascripts développés par Linkedin.

2013-09-27 Format de compression BZ2

Il existe beaucoup de formats de compression. Le plus connu est dans doute le format zip. Il serait impossible de tous les citer (voir compression). Un des logiciels les plus utilisés sous Windows est 7z. Il permet de compresser / décompresser les formats les plus utilisés pour la compression du texte. Et le format 7-zip est le plus souvent le plus efficace.

Alors pourquoi aurait-on besoin d'autre format de compression ? Ce qui marche pour le texte ne marche pas forcément très bien sur la musique, les images ou la vidéo. Pour le texte, on cherche toujours une compression sans erreur. On accepterait mal qu'un document se retrouve altéré durant les étapes de compression / décompression. Pour les images, on recherche principalement des compressions avec un peu de perte : une déterioration de la qualité de l'image qui soit presque invisible pour l'oeil humain. Le format MP3 est aussi une compression de la musique avec perte. Pour la vidéo qui est très gourmande, on utilise le fait que les images changent peu d'une seconde à l'autre comme le décor en fond d'écran. On ne va donc pas compresser les images directement mais la différence entre une image et sa précédente.

Pour en revenir aux données qu'on compresse sans perte, pourquoi utiliser un autre format de compression si 7-zip est meilleur ? En fait, il est meilleur la plupart du temps mais pour certains usages précis, d'autres formats sont plus adaptés, plus simples ou plus performants. Le format Bzip2 ou Bz2. Pour citer Wikipedia, les avantages de ce format sont : une faible utilisation mémoire à la compression, la robustesse des archives à la corruption et la parallélisation possible sur de nombreux threads.

Pour compresser du texte en Python au format bz2, on utilise le programme suivant :

import bz2

# les lignes de texte à décompresser
lines = ["line1", "line2 é"]

# on ouvre un fichier classique en mode binaire
with open(file,"wb") as f :
    comp = bz2.BZ2Compressor()
    for line in lines :
        tof = line + "\n"  # on ajoute une fin de ligne
                           # puis on encode en utf8 avant de compresser
        c = comp.compress ( tof.encode("utf8")  )
        f.write( c )
    c = comp.flush()   # il ne faut pas oublier car le 
    f.write( c )       # BZ2Compressor fonctionne comme un buffer

Pour le relire :

import bz2
lines = [ ]
with bz2.BZ2File(file, "r") as f :
    for line in f :
        s = str(line, encoding = "utf8")
        lines.append (s)
Avec ses deux exemples, il n'est pas besoin de conserver une version décompressée du fichier. On écrit et lit directement les données au format compressé.

2013-09-26 Busy areas in Paris

During summer, one pleasure is to go to work by bike. Simple option is to take a Velib but most of the time, the closest Velib station is empty. The same thing happens when you leave your work to go back home. No bike is available.

I thought maybe this could be used to draw a map of Paris showing areas where people work. I thought about looking at the distribution of the number of available bikes over a day. I already mentioned that the Velib data was available (see Les stations Vélib à Paris un jeudi soir). Next figure shows it for a couple of stations and one of them is clearly a working station: bikes arrive in the morning and disappear at the end of the working day (it was taken a couple of weeks ago during a week day).

The number of available bikes was measured every five minutes. Knowing that every station does not have the same number of spots, I normalized the previous curve by the sum. I then considered the sum between 10am and 4pm. So for each station, I built the following indicator:

 I(s) =  \frac{\sum_{t=10am}^{4pm} X(s,t) }              { \sum_{t=0am}^{11:59pm} X(s,t) }

I used the information to draw a map of Paris with the Velib stations. If I(s) > 0.25 , I used a red flag and a green otherwise.

Basically, companies offices are located in the center of Paris (districts with one digit) and around the Seine, people live around (districts with two digits). It also shows there are some business areas just outside Paris like Issy-Les-Moulineaux (where I work). You can play with the final result below. It uses OpenStreetMap and OpenLayers.


more...

2013-09-21 Le profile online d'un développeur

Beaucoup de sociétés recherchent de bons développeurs et les dernières années ont changé les façons de les trouver. Il y a d'abord les réseaux sociaux Linkedin, Viadeo, Facebook. Mais ce n'est pas tout, les bons développeurs ont souvent partagé leur code ou contribué à des projets open source. On retrouve leurs traces sur GitHub. Certains ont aussi tenté de résoudre certains des problèmes proposés par kaggle. Ajoutons, un site web, un petit blog pour commenter tous les défis techniques auquel un développeur s'attaque.

Il y a dix ans, le CV et la lettre de motivation était la façon de se vendre. Le CV est aujourd'hui sur Linkedin ou Viadeo, la motivation dans le nombre de commit sur GitHub.

2013-09-15 Python extensions to do machine learning

I started to compare the functionalities of some Python extensions (the list is not exhaustive) :

The first one (scikit-learn) covers many features and its documentation is quite clear. When a model is missing, you can look into PyBrain for Reinforcement Learning, in Gensim for Dirichlet Application (Latent, Hierarchical) and in NLTK for any text processing (tokenization for example). For those who do not want to code, Orange would be a good option. The module Theano does gradient optimization using GPU.

A couple of forums, kind of FAQ for machine learning:

It would be difficult to do machine learning without using visualization tools. matplotlib and ggplot would be a good way to start. We also manipulate tables: numpy and pandas. For a command line: ipython or bpython are two common options.

If you are looking for data UC Irvine Machine Learning Repository. If you work with Windows, many of the presented modules can be downloaded from Unofficial Windows Binaries for Python Extension Packages. It also gives a clear view of what package is available on which Python's version.


more...

2013-09-14 Quelques astuces avec pandas python

Ce n'est pas toujours évident d'apprendre à manipuler un nouveau module. On commence toujours par des trucs simples qu'on peine toujours à faire même après quelques requêtes sur un moteur de recherche. Bref, voici quelques raccourcis (on suppose que df est un DataFrame). Je recommande un rapide coup d'oeil à 10 Minutes to Pandas (et celle-ci aussi : Essential Basic Functionality).

Parcourir tous les éléments (version lente) :

self.header = ['index'] + [ _ for _ in df.columns ]
self.values = []
for i in range(len(df) :
    row = [ df.index[i] ] + [ df.ix[i,j] for j in range(len(self.header)) ]
    self.values.append(row)

Parcourir tous les éléments (version plus rapide) :

self.header = ['index'] + [ _ for _ in df.columns ]
self.values = []
for i,row in enumerate(df.values) :
    row = [ df.index[i] ] + [ x for x in row ]
    self.values.append(row)

Créer un DataFrame à partir d'une matrice (liste de listes) :

df = pandas.DataFrame(liste_de_listes, columns = list_nom_colonnes)


more...

2013-09-13 Burger bio et espérence de vie en bonne santé

Le bio a le vent en poupe, voici un fast food bio : BioBurger. Cela donne envie d'essayer. Et puis après avoir écouté cette émission de radio : Nocifs , les additifs ?, notre espérance de vie augmente chaque année mais l'espérence de vie en bonne santé diminue chaque année aussi (Rupture de tendance : l'espérance de vie en bonne santé diminue pour la première fois. Dans quel état vivons-nous la grande vieillesse ?, Espérance de vie en bonne santé : dernières tendances). Bref, on avale plus de cochonneries qu'il y a trente ans (comme l'aspartame) et la probabilité d'avoir un cancer à la fin de la vie augmente. Bio donc.

2013-09-08 Convertir un tableau Excel au format HTML

Le code suivant convertit un tableau Excel au format HTML puis stocke le résultat dans le presse-papier (il suffit donc de faire CTRC+V pour le coller où on veut). La macro convertit la zone sélectionnée au format HTML. Voici ce qu'elle donne :

objectifPythonVBA
test if / elseif .. Then / else / end if
bouclefor .. in ..for .. = .. to .. / next
fonctiondeffonction / end function

Le code de la fonction doit être copié/collé dans un module (ALT+F11 pour voir le code VBA associé à la feuille). Je n'ai pas implémenté beaucoup de styles mais la fonction est facilement modifiable.

' code à copier dans la feuille Excel
Function ColorToHtml(ByVal value As String) As String
    Dim scolor As String
    scolor = Trim(Hex(value))
    While Len(scolor) < 6
        scolor = "0" + scolor
    Wend
    scolor = Mid(scolor, 3, 4) + Mid(scolor, 1, 2)
    ColorToHtml = "#" + scolor
End Function

Sub range_html_to_cliboard()
    Set rge = Selection
    Dim res, line, ce As String
    res = "<table>" + Chr(10)
    
    For i = 1 To rge.Rows.Count
        line = "<tr>"
        For j = 1 To rge.Columns.Count
            ce = "<td style="""
            If rge(i, j).Interior.color Then
                ce = ce + "background-color:" + ColorToHtml(rge(i, j).Interior.color) + ";"
            End If
            If rge(i, j).Font.color Then
                ce = ce + "color:" + ColorToHtml(rge(i, j).Font.color) + ";"
            End If
            If rge(i, j).Font.Bold Then
                ce = ce + "font-weight:bold;"
            End If
            ce = ce + """>"
            ce = ce + rge(i, j).Text + "</td>"
            line = line + ce
        Next
        line = line + "</tr>"
        res = res + line + Chr(10)
    Next
    
    res = res + "</table>" + Chr(10)
    
    ClipBoard_SetData (res)
End Sub

La fonction ne marche pas tel quel sur les tableaux créés avec des styles, ni même avec une liste filtrée. Pour cela, il faut copier la zone désirée puis faire deux collages spéciaux, le formatting et les valeurs, au même endroit. On sélectionne ensuite la zone collée puis on appelle la macro décrite ci-dessus.


more...

2013-09-07 Quelques restaurants encore

Quelques restaurants encore qui figureront sur une carte un jour si j'arrive à écrire le programme qui me permettra de récupérer leurs adresses depuis leur site web et de les afficher sur une carte.


Xavier Dupré