C # o Java? ¿TypeScript o JavaScript? La clasificación de los lenguajes de programación basados ​​en el aprendizaje automático.

GitHub tiene más de 300 lenguajes de programación, que van desde lenguajes conocidos como Python, Java y Javascript hasta lenguajes esotéricos como Befunge , conocidos solo por pequeños grupos de personas.

Los 10 principales lenguajes de programación alojados en GitHub por número de repositorios

Uno de los problemas que enfrenta GitHub es el reconocimiento de diferentes lenguajes de programación. Cuando se coloca algún código en el repositorio, el reconocimiento de su tipo es muy importante. Esto es necesario por motivos de búsqueda, alertas de vulnerabilidad, resaltado de sintaxis, así como la representación estructural del contenido del repositorio para los usuarios.

A primera vista, el reconocimiento de idioma es una tarea simple, pero no lo es. Linguist es la herramienta que estamos utilizando actualmente para definir un lenguaje de programación en GitHub. Linguist es una aplicación de Ruby que utiliza una variedad de estrategias de reconocimiento de idiomas, que incluyen información de nombres y extensiones de archivos. Además, tiene en cuenta los modelos Vim o Emacs, así como los contenidos en la parte superior del archivo (shebang). Linguist procesa la ambigüedad lingüística heurísticamente y, si esto no funciona, utiliza un clasificador bayesiano ingenuo entrenado en una pequeña muestra de datos.

Aunque Linguist predice bastante bien a nivel de archivo (84% de precisión), todo se rompe cuando los archivos tienen nombres extraños, y más aún cuando los archivos no tienen extensiones. Esto hace que Linguist sea inútil para contenido como GitHub Gists o fragmentos de código en README, errores y solicitudes de extracción.

Con el fin de aclarar la definición del lenguaje a largo plazo, hemos desarrollado un clasificador de aprendizaje automático llamado OctoLingua. Se basa en la arquitectura de la red neuronal artificial (ANN), que puede manejar la predicción del lenguaje en escenarios no triviales. La versión actual del modelo puede hacer predicciones para los 50 principales lenguajes de programación en GitHub y supera a Linguist en precisión.

Más detalles sobre OctoLingua


OctoLingua fue escrito desde cero en Python, Keras con el backend TensorFlow, fue creado para ser preciso, confiable y fácil de mantener. En esta parte, hablaremos sobre nuestras fuentes de datos, arquitectura de modelo y pruebas de rendimiento de OctoLingua. También hablaremos sobre el proceso de agregar la capacidad de reconocer un nuevo idioma.

Fuentes de datos


La versión actual de OctoLingua ha sido entrenada en archivos obtenidos de Rosetta Code y de un conjunto de repositorios internos de crowdsource. Hemos limitado nuestro conjunto de idiomas a los 50 más populares en GitHub.

Rosetta Code fue un excelente conjunto de datos de inicio porque contenía código fuente escrito para realizar la misma tarea, pero en diferentes lenguajes de programación. Por ejemplo, el código para generar números de Fibonacci se presentó en C, C ++, CoffeeScript, D, Java, Julia y otros. Sin embargo, la cobertura de los lenguajes era heterogénea: para algunos lenguajes de programación, solo había unos pocos archivos con código, para otros, los archivos contenían simplemente muy poco código. Por lo tanto, era necesario complementar nuestro conjunto de datos de capacitación con algunas fuentes adicionales y, por lo tanto, mejorar significativamente la cobertura de idiomas y la efectividad del modelo final.

Nuestro proceso de agregar un nuevo idioma no está completamente automatizado. Compilamos programáticamente el código fuente de repositorios públicos en GitHub. Seleccionamos solo aquellos repositorios que cumplen con los criterios mínimos de calificación, como el número mínimo de tenedores que cubren el idioma de destino y las extensiones de archivo específicas. En esta etapa de la recopilación de datos, definimos el idioma principal del repositorio utilizando la clasificación de Linguist.

Síntomas: basados ​​en conocimientos previos


Tradicionalmente, las arquitecturas basadas en memoria, como las redes neuronales recurrentes (RNN) y las redes de memoria a corto plazo (LSTM) se utilizan para resolver problemas de clasificación de texto mediante redes neuronales. Sin embargo, las diferencias en los lenguajes de programación en vocabulario, extensiones de archivo, estructura, estilo de importación de bibliotecas y otros detalles nos obligaron a encontrar un enfoque diferente que utiliza toda esta información, extrayendo algunos signos en forma de tabla para entrenar a nuestro clasificador. Los atributos se recuperan de la siguiente manera:

  1. Los 5 mejores caracteres especiales en un archivo
  2. Top 20 caracteres en un archivo
  3. Extensión de archivo
  4. La presencia de caracteres especiales específicos que se utilizan en el código fuente de los archivos, como dos puntos, llaves, puntos y comas

Modelo de red neuronal artificial (ANN)


Utilizamos los factores anteriores como entrada para una red neuronal de dos capas construida usando Keras con un backend Tensorflow.

El siguiente diagrama muestra que el paso de extracción de características crea una entrada de tabla n-dimensional para nuestro clasificador. A medida que la información se mueve a través de las capas de nuestra red, se ordena al abandonarla y el resultado es una salida de 51 dimensiones, lo que representa la probabilidad de que este código se escriba en cada uno de los 50 idiomas principales en GitHub. También muestra la probabilidad de que el código no esté escrito en ninguno de los 50 idiomas.


Estructura ANN del modelo fuente (50 idiomas + 1 para "otro")

Utilizamos el 90% de nuestra base de datos fuente para la capacitación. Además, en el paso de capacitación del modelo, se eliminó parte de las extensiones de archivo para que el modelo pudiera aprender exactamente del vocabulario de los archivos, y no de sus extensiones, que predicen tan bien el lenguaje de programación.

Prueba de rendimiento


OctoLingua vs Linguist


En la tabla a continuación, mostramos la puntuación F1 (media armónica entre precisión y exhaustividad) para OctoLingua y Linguist calculada en el mismo conjunto de prueba (10% del volumen de nuestra fuente de datos original).

Aquí se muestran tres pruebas. En la primera prueba, el conjunto de datos no se tocó en absoluto; en el segundo, se eliminaron las extensiones de archivo; en el tercero, las extensiones de archivo se mezclaron para confundir al clasificador (por ejemplo, un archivo Java podría tener la extensión ".txt", y un archivo Python podría tener la extensión ".java".

La intuición detrás de barajar o eliminar extensiones de archivo en nuestro conjunto de pruebas es evaluar la confiabilidad de OctoLingua en la clasificación de archivos cuando una etiqueta clave se elimina o es engañosa. Un clasificador que no dependa mucho de la extensión sería extremadamente útil para clasificar registros y fragmentos de código, porque en estos casos la gente generalmente no proporciona información precisa sobre la extensión (por ejemplo, muchos registros relacionados con el código tienen la extensión txt).

La siguiente tabla muestra cómo OctoLingua tiene un buen rendimiento en diversas condiciones, cuando asumimos que el modelo aprende principalmente del vocabulario del código y no de la metainformación (por ejemplo, la extensión del archivo). Al mismo tiempo, Linguist determina el idioma erróneamente, tan pronto como falta información sobre la extensión de archivo correcta.

Rendimiento de OctoLingua vs. Linguist en el mismo conjunto de pruebas

El efecto de eliminar extensiones de archivo al entrenar un modelo


Como se mencionó anteriormente, durante el entrenamiento, eliminamos un cierto porcentaje de extensiones de archivo de los datos para que el modelo aprenda del vocabulario de los archivos. La siguiente tabla muestra el rendimiento de nuestro modelo con varias proporciones de extensiones de archivo eliminadas durante el entrenamiento.


Rendimiento de OctoLingua con diferente porcentaje de extensiones de archivo eliminadas

Tenga en cuenta que un modelo entrenado en archivos con extensiones es significativamente menos efectivo en archivos de prueba sin extensiones o con extensiones mixtas que en datos de prueba regulares. Por otro lado, cuando un modelo se entrena en un conjunto de datos en el que se elimina parte de las extensiones de archivo, el rendimiento del modelo no disminuye mucho en el conjunto de prueba modificado. Esto confirma que al eliminar extensiones de parte de los archivos durante el entrenamiento, nuestro clasificador aprende más del vocabulario de códigos. También muestra que la extensión del archivo tiende a dominar y evita la ponderación del contenido presentado.

Nuevo soporte de idiomas


Agregar un nuevo idioma a OctoLingua es un proceso bastante simple. Comienza con búsquedas y la obtención de una gran cantidad de archivos en un nuevo idioma (podemos hacerlo mediante programación, como se describe en la sección "Fuentes de datos"). Estos archivos se dividen en conjuntos de entrenamiento y pruebas, y luego pasan a través de nuestro preprocesador y extractor de funciones. Se agrega un nuevo conjunto de datos al grupo existente. El kit de prueba nos permite asegurarnos de que la precisión de nuestro modelo siga siendo aceptable.


Agregar un nuevo idioma a OctoLingua

Nuestros planes


OctoLingua se encuentra actualmente en una "etapa avanzada de creación de prototipos". Nuestro mecanismo de clasificación de idiomas ya es confiable, pero aún no es compatible con todos los lenguajes de programación disponibles en GitHub. Además de ampliar el soporte de idiomas, que no es tan difícil, nos esforzamos por proporcionar detección de idiomas con varios niveles de detalle de código. Nuestra implementación actual ya nos permite, con una ligera modificación de nuestro mecanismo de aprendizaje automático, clasificar fragmentos de código. Además, no parece difícil llevar el modelo a la etapa en la que pueda detectar y clasificar de manera confiable los lenguajes incrustados.

También estamos considerando publicar el código fuente de nuestro modelo, pero necesitamos una solicitud de la comunidad.

Conclusión


Nuestro objetivo en el desarrollo de OctoLingua es crear un servicio que proporcione una definición confiable del idioma mediante el código fuente en diferentes niveles de detalle: desde el nivel de archivos o fragmentos de código hasta la posible definición y clasificación del idioma a nivel de línea. Todo nuestro trabajo en este servicio está dirigido a apoyar a los desarrolladores en su trabajo de desarrollo diario, así como a crear condiciones para escribir código de alta calidad.

Si está interesado en contribuir a nuestro trabajo, ¡no dude en contactarnos en Twitter @github !

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


All Articles