De nombreux développeurs et développeuses logiciels se forment à la data science pour analyser les données de leurs clients. De plus en plus réalisent qu’ils peuvent appliquer ces mêmes techniques à leurs propres questions, par exemple :
- Quand ce projet sera-t-il prêt à être livré ?
- Quels composants de notre application doivent être testés en priorité ?
- Qui devrait corriger ce bug ?
- Quelles parties de mon API les utilisateurs trouvent-elles les plus difficiles à utiliser ?
Au cours des 15 dernières années, la recherche empirique en génie logiciel a explosé pour explorer ces questions, portée en partie par la disponibilité de données issues de sites comme GitHub et Stack Overflow. Cet article présente quelques résultats représentatifs, puis détaille les méthodes derrière trois d’entre eux.
Si vous souhaitez en savoir plus sur la façon d’utiliser la data science pour obtenir ce type d’enseignements sur vos propres projets, faites-le moi savoir.
Data science et ingénierie logicielle : exemples
Commençons par une découverte qui concerne toute personne faisant de la data science à grande échelle : la mise en évidence par Yuan et al. que des tests simples peuvent éviter la plupart des pannes critiques dans les systèmes distribués intensifs en données. Ils ont étudié des défaillances sur Cassandra, Hadoop MapReduce et des systèmes similaires, et ont constaté que :
- Presque toutes les défaillances nécessitaient 3 nœuds de calcul ou moins pour être reproduites. Autrement dit, on n’a généralement pas besoin d’un cluster pour déboguer un cluster.
- Les journaux d’erreurs contenaient le plus souvent suffisamment d’informations pour permettre la reproduction.
- La majorité des pannes catastrophiques auraient pu être facilement évitées en testant simplement le code de gestion des erreurs.
Le dernier point est le plus inattendu. Les professionnels testent généralement que leur code d’analyse fonctionne quand tout se passe bien, mais testent rarement qu’il fait la bonne chose quand quelque chose tourne mal. Ajouter quelques tests ciblant ces cas pendant le développement éviterait bien des douleurs en aval.
Un autre résultat à grande échelle provient des travaux d’Altadmri et Brown, qui ont analysé 37 millions de tentatives de compilation de programmes par des lycéens au Royaume-Uni. Ils ont ensuite interrogé des enseignants sur les erreurs les plus fréquentes de leurs élèves et ont découvert que :
- Les enseignants n’étaient pas d’accord entre eux sur les erreurs les plus probables.
- Plus important encore, les prédictions des enseignants ne corrélaient que faiblement avec ce que les élèves se trompaient réellement.
Bien sûr, l’exploration de données n’est pas la seule façon de produire des insights probants en programmation. En 2013, l’équipe d’Andreas Stefik a publié la deuxième étude d’une série visant à savoir si certaines langues sont plus faciles à apprendre que d’autres. Comme référence, ils ont inclus un langage inventé dont les mots-clés étaient générés aléatoirement.
À leur surprise, les langages à accolades comme Java et Perl étaient tout aussi difficiles à reconnaître pour des novices qu’un langage généré aléatoirement. Python et Ruby étaient significativement plus faciles à apprendre, et Quorum, qui teste en A/B la syntaxe de chaque nouvelle fonctionnalité avant de l’ajouter, l’était encore davantage. Andreas revient sur ces résultats, et sur les raisons pour lesquelles les concepteurs de langages prêtent si peu attention à l’ergonomie, dans ce podcast réjouissant.
Identifier les signalements de failles de sécurité
Pour illustrer comment ces études sont menées, Fayola Peters au LERO a utilisé des modèles de prédiction basés sur le texte pour repérer les signalements de failles de sécurité dans les bug trackers de grands systèmes, afin d’en prioriser le traitement. Dans une étude, elle a utilisé des données issues des projets Chromium, Wicket, Ambari, Camel et Derby : au total 45 940 signalements de bugs, dont seulement 0,8 % concernaient la sécurité.
Certains bugs de sécurité sont étiquetés manuellement, et ces cas peuvent servir à entraîner des classifieurs pour détecter ceux qui ne le sont pas. Des techniques comme Naïve Bayes et les Random Forests constituent un point de départ, mais l’efficacité de modèles génériques peut souvent être améliorée par un filtrage sur des mots-clés spécifiques. Le test le plus important consiste à vérifier dans quelle mesure des modèles construits à partir de projets avec des failles étiquetées peuvent repérer des bugs similaires dans d’autres projets. Les résultats étaient encourageants : Peters a constaté que ses classifieurs fonctionnaient suffisamment bien pour être utiles en pratique.
Mon correctif sera-t-il accepté ?
Deuxième exemple : les entreprises veulent que leurs modifications soient intégrées aux projets pour éviter d’avoir à maintenir le code elles-mêmes, et les bénévoles veulent aussi savoir si leur correctif a des chances d’être retenu. Comme il s’écoule souvent un long délai entre la soumission et l’acceptation d’un patch, Bram Adams et son équipe à Polytechnique Montréal ont construit des modèles pour prédire ceux qui seront acceptés.
Comme beaucoup de projets de data science, celui-ci commence par la collecte et le nettoyage de données provenant de plusieurs sources, notamment des dépôts Git et des revues de code Gerrit. Cependant, pour les projets qui utilisent des revues par e-mail, comme le noyau Linux, rassembler les données suppose d’aspirer les archives de listes de diffusion et d’utiliser des heuristiques comme les sommes de contrôle des patches ou l’intersection ensembliste des lignes modifiées pour faire correspondre les patches aux discussions. Même avec des outils comme GrimoireLab, il restera toujours des cas où plusieurs versions d’un patch ont été évaluées, ou des patches scindés en plusieurs parties et revus séparément. Comme en data science en général, il revient à l’analyste de construire un modèle, et les hypothèses qu’il contient auront un impact majeur sur les conclusions finales.
La deuxième étape consiste à choisir quelles variables examiner et quelles métriques utiliser pour chacune, par exemple :
- la qualité du patch
- l’expérience de l’auteur du patch
- le processus de revue (par exemple, commentaires et nombre de réviseurs)
- la qualité de la revue (par exemple, niveau de détail des retours)
- le délai de revue
- les interactions entre l’auteur du patch et les réviseurs (par exemple, ton cordial vs. agressif)
Rien que pour ces six éléments, on peut mobiliser aussi bien des statistiques de survie que de l’analyse de sentiment. Une fois les mesures définies, vous pouvez appliquer les outils de data science enseignés dans les cours de DataCamp. Puisque l’objectif réel est de prédire l’acceptation de patches futurs, la régression logistique s’impose comme approche directe, mais il en existe bien d’autres.
Enfin, on peut mesurer l’importance des variables pour évaluer l’impact de chacune sur l’acceptation d’un patch. Cette étape sera nécessairement en partie qualitative, car l’objectif est d’identifier ce que les développeurs peuvent faire pour augmenter leurs chances de voir leur travail intégré. Comme toujours, attention à ne pas confondre corrélation et causalité, mais même quelques recommandations simples (comme « N’ÉCRIVEZ PAS VOS MESSAGES DE COMMIT EN MAJUSCULES ») peuvent faire une vraie différence.
Trouver de l’aide
Le plus grand changement dans la façon de travailler des programmeurs au cours des 20 dernières années ne tient pas aux langages utilisés, mais à la dépendance quasi universelle à Stack Overflow pour poser des questions et obtenir des réponses. Christoph Treude à l’Université d’Adélaïde et ses collaborateurs développent des méthodes pour rendre ces sites encore plus utiles.
Leur point de départ est le jeu de données Stack Overflow. Après quelques statistiques exploratoires sur le nombre de mots et de phrases, les mots les plus fréquents, la mesure TF-IDF, etc., l’étape suivante consiste à voir quels mots dans les fils Stack Overflow coïncident avec des votes plus élevés, des taux d’acceptation supérieurs et davantage de vues.
Comme la documentation logicielle contient beaucoup de phrases incomplètes et d’éléments de code, les bibliothèques de traitement automatique du langage naturel prêtes à l’emploi se trompent souvent. La documentation rédigée dans d’autres langues que l’anglais est encore plus difficile à analyser, car elle conserve généralement l’anglais pour la terminologie technique. Autrement dit, elle mélange deux langues naturelles et des éléments de code. Des heuristiques ad hoc et des techniques de modélisation plus avancées doivent être combinées pour traiter ces cas.
Assembler ces briques permet de construire un outil qui prend le nom d’un module Python en entrée et produit des phrases pertinentes à son sujet à partir des fils Stack Overflow. Plus loin encore, Treude et ses collaborateurs ont exploité les dépendances grammaticales entre les mots pour trouver automatiquement de la documentation logicielle expliquant comment réaliser une tâche, puis identifier automatiquement des extraits de code capables d’accomplir cette tâche.
Conclusion
Trop souvent, les « vérités » largement partagées sur le développement logiciel reposent sur des opinions tranchées et des voix fortes plutôt que sur des preuves. Comme indiqué en introduction, cela change à mesure que des centaines d’études de qualité paraissent chaque année pour étayer certaines croyances, comme « la revue de code est vraiment le meilleur moyen de trouver des bugs », et en bousculer d’autres, comme « le développement piloté par les tests n’est pas aussi efficace que certains le pensent, et les instructions goto ne sont pas vraiment nuisibles ».
On a défini l’« ingénierie » comme « l’application de la méthode scientifique pour créer des choses utiles ». Si cela est vrai, alors grâce à la data science, le développement logiciel est peut-être enfin en passe de devenir une véritable discipline d’ingénierie. Si vous souhaitez voir des cours montrant comment appliquer la data science au développement logiciel, dites-le nous.
Pour aller plus loin
Chaque année, des conférences comme Mining Software Repositories présentent des dizaines de nouveaux résultats dans ce domaine. Certaines de ces publications restent derrière des barrières payantes académiques, mais un nombre croissant de chercheur·e·s mettent des prépublications à disposition.
Pour une vue d’ensemble, l’ouvrage de 2010 Making Software proposait une sélection des résultats les plus marquants de l’époque. Une trilogie plus récente, Perspectives on Data Science for Software Engineering, The Art and Science of Analyzing Software Data et Sharing Data and Models in Software Engineering, couvre ces sujets de façon plus large et plus actuelle. Par ailleurs, Derek Jones travaille sur un nouvel ouvrage intitulé Empirical Software Engineering Using R.