C # ou Java? TypeScript ou JavaScript? La classification des langages de programmation basée sur l'apprentissage automatique

GitHub possède plus de 300 langages de programmation, allant des langages bien connus tels que Python, Java et Javascript aux langages ésotériques tels que Befunge , connus uniquement de petits groupes de personnes.

Top 10 des langages de programmation hébergés par GitHub par nombre de référentiels

L'un des problèmes auxquels GitHub est confronté est la reconnaissance de différents langages de programmation. Lorsqu'un code est placé dans le référentiel, la reconnaissance de son type est très importante. Cela est nécessaire pour des raisons de recherche, d'alertes de vulnérabilité, de mise en évidence de la syntaxe, ainsi que de représentation structurelle du contenu du référentiel pour les utilisateurs.

À première vue, la reconnaissance de la langue est une tâche simple, mais ce n'est pas le cas. Linguist est l'outil que nous utilisons actuellement pour définir un langage de programmation sur GitHub. Linguist est une application Ruby qui utilise une variété de stratégies de reconnaissance de langue, y compris des informations de nom et des extensions de fichier. De plus, il prend en compte les modèles Vim ou Emacs, ainsi que le contenu en haut du fichier (shebang). Le linguiste traite de manière heuristique l'ambiguïté linguistique et, si cela ne fonctionne pas, utilise alors un classificateur bayésien naïf formé sur un petit échantillon de données.

Bien que Linguist prédit assez bien au niveau des fichiers (84% de précision), tout se casse lorsque les fichiers sont nommés de manière étrange, et encore plus lorsque les fichiers n'ont pas d'extensions. Cela rend Linguist inutile pour le contenu tel que GitHub Gists ou les extraits de code dans README, les erreurs et les demandes d'extraction.

Afin de rendre la définition du langage plus claire à long terme, nous avons développé un classificateur d'apprentissage automatique appelé OctoLingua. Il est basé sur l'architecture Artificial Neural Network (ANN), qui peut gérer la prédiction du langage dans des scénarios non triviaux. La version actuelle du modèle peut faire des prédictions pour les 50 principaux langages de programmation sur GitHub et dépasse Linguist en termes de précision.

Plus de détails sur OctoLingua


OctoLingua a été écrit à partir de zéro à Python, Keras avec le backend TensorFlow - il a été créé pour être précis, fiable et facile à entretenir. Dans cette partie, nous parlerons de nos sources de données, de l'architecture du modèle et des tests de performances d'OctoLingua. Nous parlerons également du processus d'ajout de la capacité de reconnaître une nouvelle langue.

Sources de données


La version actuelle d'OctoLingua a été formée sur les fichiers obtenus à partir de Rosetta Code et d'un ensemble de référentiels crowdsource internes. Nous avons limité notre ensemble de langues aux 50 plus populaires sur GitHub.

Rosetta Code était un excellent ensemble de données de départ car il contenait du code source écrit pour effectuer la même tâche, mais dans différents langages de programmation. Par exemple, le code pour générer des nombres de Fibonacci a été présenté en C, C ++, CoffeeScript, D, Java, Julia et autres. Cependant, la couverture des langages était hétérogène: pour certains langages de programmation, il n'y avait que quelques fichiers avec du code, pour d'autres, les fichiers contenaient tout simplement trop peu de code. Par conséquent, il était nécessaire de compléter notre ensemble de données de formation avec quelques sources supplémentaires et ainsi d'améliorer considérablement la couverture des langues et l'efficacité du modèle final.

Notre processus d'ajout d'une nouvelle langue n'est pas entièrement automatisé. Nous compilons par programme le code source à partir de référentiels publics sur GitHub. Nous sélectionnons uniquement les référentiels qui répondent aux critères de qualification minimum, tels que le nombre minimum de fourches couvrant la langue cible et couvrant des extensions de fichier spécifiques. À ce stade de la collecte des données, nous définissons la langue principale du référentiel en utilisant la classification de Linguist.

Symptômes: basé sur des connaissances antérieures


Traditionnellement, des architectures basées sur la mémoire telles que les réseaux de neurones récurrents (RNN) et les réseaux de mémoire à court terme (LSTM) sont utilisées pour résoudre les problèmes de classification de texte à l'aide de réseaux de neurones. Cependant, des différences dans les langages de programmation dans le vocabulaire, les extensions de fichiers, la structure, le style d'importation des bibliothèques et d'autres détails nous ont obligés à trouver une approche différente qui utilise toutes ces informations, en extrayant certains signes sous forme de tableau pour former notre classificateur. Les attributs sont récupérés comme suit:

  1. 5 premiers caractères spéciaux dans un fichier
  2. Les 20 premiers caractères d'un fichier
  3. Extension de fichier
  4. La présence de caractères spéciaux spécifiques utilisés dans le code source des fichiers, tels que les deux-points, les accolades, les points-virgules

Réseau de neurones artificiels modèles (ANN)


Nous utilisons les facteurs ci-dessus comme entrée pour un réseau neuronal à deux couches construit en utilisant Keras avec un backend Tensorflow.

Le diagramme ci-dessous montre que l'étape d'extraction d'entités crée une entrée de table à n dimensions pour notre classificateur. Au fur et à mesure que les informations se déplacent à travers les couches de notre réseau, elles sont ordonnées par suppression, et le résultat est une sortie en 51 dimensions, ce qui représente la probabilité que ce code soit écrit dans chacune des 50 premières langues sur GitHub. Il montre également la probabilité que le code ne soit écrit dans aucune des 50 langues.


Structure ANN du modèle source (50 langues + 1 pour «autre»)

Nous avons utilisé 90% de notre base de données source pour la formation. De plus, à l'étape de formation du modèle, une partie des extensions de fichier a été supprimée afin que le modèle puisse apprendre exactement du vocabulaire des fichiers, et non de leurs extensions, qui prédisent si bien le langage de programmation.

Test de performance


OctoLingua vs Linguist


Dans le tableau ci-dessous, nous montrons le score F1 (moyenne harmonique entre précision et exhaustivité) pour OctoLingua et Linguist calculé sur le même ensemble de tests (10% du volume de notre source de données d'origine).

Trois tests sont présentés ici. Lors du premier test, l'ensemble de données n'a pas été touché du tout; dans le second, les extensions de fichiers ont été supprimées; dans le troisième, les extensions de fichier ont été mélangées afin de confondre le classificateur (par exemple, un fichier Java pourrait avoir l'extension ".txt", et un fichier Python pourrait avoir l'extension ".java".

L'intuition derrière le brassage ou la suppression d'extensions de fichiers dans notre suite de tests est d'évaluer la fiabilité d'OctoLingua dans la classification des fichiers lorsqu'une balise clé est supprimée ou trompeuse. Un classificateur qui ne dépend pas beaucoup de l'extension serait extrêmement utile pour classer les journaux et les extraits de code, car dans ces cas, les gens ne fournissent généralement pas d'informations précises sur l'extension (par exemple, de nombreux journaux liés au code ont l'extension txt.)

Le tableau ci-dessous montre comment OctoLingua a de bonnes performances dans diverses conditions, lorsque nous avons supposé que le modèle apprenait principalement du vocabulaire du code, et non des méta-informations (par exemple, l'extension de fichier). Dans le même temps, Linguist détermine la langue par erreur, dès que des informations sur l'extension de fichier correcte sont manquantes.

OctoLingua vs performances Linguist sur la même suite de tests

L'effet de la suppression des extensions de fichier lors de la formation d'un modèle


Comme mentionné précédemment, lors de la formation, nous avons supprimé un certain pourcentage d'extensions de fichier des données pour que le modèle apprenne du vocabulaire des fichiers. Le tableau ci-dessous montre les performances de notre modèle avec différentes proportions d'extensions de fichiers supprimées pendant la formation.


Performances OctoLingua avec un pourcentage différent d'extensions de fichiers supprimées

Veuillez noter qu'un modèle formé sur les fichiers avec des extensions est beaucoup moins efficace sur les fichiers de test sans extensions ou avec des extensions mixtes que sur les données de test régulières. En revanche, lorsqu'un modèle est formé sur un ensemble de données dans lequel une partie des extensions de fichier est supprimée, les performances du modèle ne diminuent pas beaucoup sur l'ensemble de test modifié. Cela confirme que la suppression d'extensions d'une partie des fichiers pendant la formation incite notre classificateur à en apprendre davantage sur le vocabulaire du code. Il montre également que l'extension de fichier a tendance à dominer et à empêcher la pondération du contenu présenté.

Prise en charge d'une nouvelle langue


L'ajout d'une nouvelle langue à OctoLingua est un processus assez simple. Cela commence par des recherches et l'obtention d'un grand nombre de fichiers dans une nouvelle langue (nous pouvons le faire par programmation, comme décrit dans la section «Sources de données»). Ces fichiers sont divisés en suites de formation et de test, puis passent par notre préprocesseur et notre extracteur de fonctionnalités. Un nouvel ensemble de données est ajouté au pool existant. Le kit de test nous permet de nous assurer que la précision de notre modèle reste acceptable.


Ajout d'une nouvelle langue à OctoLingua

Nos plans


OctoLingua est actuellement à une «étape de prototypage avancé». Notre mécanisme de classification des langages est déjà fiable, mais ne prend pas encore en charge tous les langages de programmation disponibles sur GitHub. En plus d'étendre la prise en charge des langues, ce qui n'est pas si difficile, nous nous efforçons de fournir une détection de la langue avec différents niveaux de détails de code. Notre implémentation actuelle nous permet déjà, avec une légère modification de notre mécanisme d'apprentissage automatique, de classer les fragments de code. En outre, il ne semble pas difficile d'amener le modèle au stade où il peut détecter et classer de manière fiable les langages intégrés.

Nous envisageons également de publier le code source de notre modèle, mais nous avons besoin d'une demande de la communauté.

Conclusion


Notre objectif dans le développement d'OctoLingua est de créer un service qui fournit une définition fiable de la langue par le code source à différents niveaux de détail: du niveau des fichiers ou des fragments de code à la définition et à la classification potentielles de la langue au niveau de la ligne. Tous nos travaux sur ce service visent à accompagner les développeurs dans leur travail de développement quotidien, ainsi qu'à créer les conditions pour écrire du code de haute qualité.

Si vous souhaitez contribuer à notre travail, n'hésitez pas à nous contacter sur Twitter @github !

Source: https://habr.com/ru/post/fr459104/


All Articles