Las bases de datos que se van a migrar pueden tener una amplia gama de representaciones y contenidos de datos. Desde simples campos de datos numéricos hasta campos con estructura y contenido complejos, que pueden contener archivos, imágenes, tablas o incluso objetos personalizados complejos (por ejemplo, en formatos XML, CLOB, BLOB, etc.).
El descubrimiento de datos más simples se puede realizar de manera fácil y muy eficiente utilizando métodos tradicionales con algunos conocimientos básicos y conjuntos de valores. Sin embargo, a medida que los datos se vuelven más complejos, esta eficiencia disminuye hasta que los métodos tradicionales ya no son suficientes.
Estos datos más complejos pueden ser, por ejemplo, textos no estructurados o archivos binarios cuyo tipo y contenido no pueden identificarse e interpretarse claramente. A modo de argumentación, ignoremos el hecho de que el uso de este tipo de datos en bases de datos sólo se justifica en unos pocos casos específicos, ya que este problema surge a menudo al migrar sistemas complejos. Estos formatos de datos complejos normalmente no están estructurados, estructuralmente sólo son un conjunto de bytes en un campo determinado, sobre los cuales el usuario a menudo no tiene información fiable debido a una documentación incompleta. Sin metainformación es difícil sacar conclusiones sobre el tipo de contenido y su interpretación. Entonces, nuestra primera tarea es decidir sobre estos campos qué tipo de datos contienen.
La forma más obvia de identificar los tipos de archivos sería verificar su extensión, pero cuando se almacena en una base de datos, esta información generalmente no está disponible, o incluso si lo estuviera, no podría usarse con la máxima confianza. Suponiendo que solo está disponible la versión binaria de los datos, es decir, el objeto binario grande (BLOB), el primer paso es cargarlo. Todos los metadatos están codificados en este BLOB, según el formato del archivo.
Dependiendo del formato del archivo o del tipo de datos, los metadatos del archivo pueden aparecer en varios lugares del archivo, ya sea en el encabezado o al final del archivo. Además de identificar el formato del archivo, los encabezados de los archivos también pueden contener metadatos sobre el archivo y su contenido. Los archivos basados en caracteres (texto) suelen tener encabezados basados en caracteres, mientras que los formatos binarios suelen tener encabezados binarios, aunque esto no es un estándar, solo una práctica industrial.
La distribución de valores de bytes en diferentes tipos de archivos muestra un patrón diferente para cada tipo. Los primeros intentos se centraron en la distribución de bytes de todo el archivo, pero los métodos más recientes realizan un muestreo diferente, como analizar solo muestras del principio, el final y la mitad de los archivos. Estas muestras pueden proporcionar una buena base para aprendizaje automáticoque puede determinar (con cierta probabilidad) el tipo de archivos desconocidos utilizando un modelo construido sobre las diferentes distribuciones. En un procedimiento basado en BFD (Distribución de frecuencia de bytes), no es necesario leer el archivo completo, lo que ahorra tiempo. Los valores extraídos de varias posiciones del archivo se analizan estadísticamente para obtener una huella digital específica del archivo. Basándose en esta huella digital, el aprendizaje automático es capaz de encontrar el tipo de archivo en el modelo (el que le enseñamos con archivos conocidos) que mejor se adapta a él.
La siguiente figura muestra la distribución de bytes de algunos tipos de archivos:
Tenga en cuenta que todos los códigos y ejemplos de datos de entrada/salida de este artículo se derivan de Clarity Consulting. MigNon herramienta. Este software asistente de migración de datos es el resultado de un proyecto de I+D de varios años, parcialmente financiado por la Unión Europea.
Aplicar el aprendizaje automático al reconocimiento de formatos de archivos
El aprendizaje automático puede ser un método eficaz para el reconocimiento de formatos de archivos, especialmente cuando se trabaja con grandes conjuntos de datos. Se pueden considerar los siguientes modelos para la detección de formatos de archivos:
- Bayes ingenuo: Adecuado para análisis basados en bytes o secuencias, donde se tienen en cuenta las características típicas de cada formato de archivo, como distribuciones de bytes o patrones característicos.
- Máquinas de vectores de soporte (SVM): Una buena opción cuando los límites entre formatos de archivos, es decir, superficies de decisión, deben definirse en función de la frecuencia de bytes.
- Bosque aleatorio: Entre los métodos de aprendizaje conjunto, se utiliza a menudo Random Forest porque puede manejar muchos formatos de archivos diferentes y puede hacer frente a datos ruidosos.
- Redes neuronales convolucionales (CNN): Las CNN son capaces de reconocer patrones de distribución de bytes y pueden tratar archivos como imágenes donde la frecuencia de bytes se interpreta como «píxeles», reconociendo así diferentes formatos de archivo.
- codificador automático: se puede utilizar para el aprendizaje no supervisado, especialmente para la detección de anomalías, cuando se intenta detectar archivos con un patrón de bytes diferente al habitual para un formato de archivo determinado.
- K-Vecinos más cercanos (KNN): Para conjuntos de datos pequeños, esta puede ser una forma sencilla pero eficaz de identificar formatos de archivos en función de la similitud de sus vecinos más cercanos.
- Redes neuronales recurrentes (RNN): Debido a que los RNN manejan de manera eficiente datos secuenciales, pueden ser útiles para tareas donde las secuencias de bytes en un archivo son importantes.
Para el reconocimiento automático del formato de archivo, el Luz GBM El modelo (Light Gradient Boosting Machine) puede ser una buena opción por varias razones. En primer lugar, es muy eficiente en conjuntos de datos grandes y diversos, está optimizado para un aprendizaje y una predicción rápidos y, por lo tanto, funciona bien para el análisis de formatos de archivos con grandes distribuciones de bytes o muchas muestras. Requiere poca memoria, lo que puede ser una consideración importante al detectar y clasificar múltiples formatos de archivos en un sistema. Es miembro de la familia de modelos de aumento de gradiente, que puede modelar de manera eficiente superficies de decisión complejas y esta precisión puede ser crítica en la detección de formatos de archivos donde la frecuencia de bytes puede tener distribuciones discretas.
La solución LightGBM se basa en datos y, dado que necesitamos una mayor cantidad de datos para construir un modelo de la calidad adecuada, hemos creado un sistema de descarga casi automatizado para esto en nuestro ejemplo. Para implementar nuestro sistema de descarga automatizado, utilizamos Selenium en Python para controlar el navegador mediante un controlador de Firefox. Esto nos permitió buscar enlaces y elementos HTML y luego realizar acciones sobre ellos, como hacer clic o ingresar datos. Durante las descargas automáticas, manejamos tipos de archivos como CSV, DOC, DOCX, XML, JPG, JSON, PDF, PNG, XLS y XLSX, pero algunos archivos, como MP3 o AVI, tuvieron que recopilarse y procesarse manualmente. Los archivos se recopilaron de varias fuentes, como kaggle.com para archivos CSV y JSON, mientras que las imágenes PNG y JPG se descargaron de imgur.com. Los videos de YouTube se descargaron en formato MP4 desde btclod.com y se convirtieron a AVI usando WinFF. Para los archivos ZIP, la compresión y la descarga se manejaron mediante scripts de Python separados. Las descargas automáticas se organizaron cuidadosamente en una estructura de directorio adecuada. El volumen de descarga y la calidad de los datos se controlaron mediante parámetros dentro del programa. Algunos de nuestros datos de prueba se recopilaron manualmente para garantizar que hubiera diferentes archivos, pero no pudimos recopilar cantidades suficientes de cada tipo de archivo, por lo que en muchos casos las descargas automáticas siguieron siendo el método principal para generar información.
Las cantidades de datos de entrada obtenidos fueron las siguientes:


Reconocer los detalles del patrón de distribución de frecuencia de bytes mencionado en la introducción es la base para construir el modelo LightGBM a partir de los datos recopilados. Procesar una lista de bytes completa es costoso, por lo que para determinar la extensión del archivo, los datos se filtran a través de un BFD, lo que puede verse como una especie de “huella digital parcial”. Usando esto como datos de entrada, podemos determinar el tipo de algunos archivos para el modelo. Esto se hace creando un HASH-MAP de frecuencia a partir de una matriz de bytes, donde las claves son los bytes y los valores son el número de ocurrencias. Dado que las claves son números positivos (0 a 255), este HASH-MAP se puede convertir fácilmente en una matriz, lo que acelera el proceso de normalización. La normalización en este caso significa construir una distribución de probabilidad a partir de los valores de frecuencia. Como resultado, la suma de las frecuencias normalizadas dará un valor de 1. Esta forma normalizada será la BFD.
Probando y ajustando el modelo.
El principal problema al definir las extensiones de archivos fue que el modelo inicial, que funcionaba con 256 bytes, no podía distinguir entre formatos similares como XML, JSON, ZIP, DOCX y XLSX. De estos, el formato ZIP era particularmente confuso porque tanto DOCX como XLSX contienen XML empaquetado en un archivo ZIP. La confusión entre XML y JSON también era común, ya que tienen una estructura muy similar. Debido a estos factores, la precisión del modelo para estos tipos de archivos siguió siendo baja, por lo que fue necesario mejorar el modelo e introducir nuevas funciones.
Para mejorar la precisión, se agregaron las siguientes características
- Tasas de bytes de 60, 62
- Tasas de bytes de 123, 125
- serie de bytes de cadenas compartidas
Para refinar el modelo, introdujimos varias características específicas de bytes para identificar diferentes tipos de archivos. Por ejemplo, los bytes 60 y 62, que corresponden a los símbolos ‘<' y '>‘, desempeñaron un papel clave en la identificación precisa de archivos XML. De manera similar, los bytes 123 y 125, que representan los caracteres ‘{‘ y ‘}’, fueron útiles para identificar archivos JSON. Para reconocer archivos DOCX, utilizamos la proporción de la secuencia de bytes ‘ Para la detección de archivos XLSX, la secuencia de bytes «sharedStrings» funcionó muy bien porque todos los archivos XLSX contienen el archivosharedStrings.xml, que no se analiza con el formato ZIP. Sin embargo, esta característica finalmente fue descartada porque su longitud la hacía demasiado sensible incluso a los cambios más pequeños. Aunque estas características mejoraron la eficiencia del modelo, la identificación exacta de los archivos ZIP siguió siendo problemática y tuvimos que utilizar otro método para identificarlos. Como no sabíamos exactamente qué funciones serían necesarias para identificar de manera confiable los archivos ZIP, decidimos incluir todas las combinaciones posibles de 2 bytes en el modelo para aumentar la precisión. Sin embargo, este enfoque requería mucha memoria, tiempo y procesador porque el proceso de aprendizaje tenía que manejar una gran cantidad de datos. Para optimizar esto, planeamos utilizar solo las 500 funciones de 2 bytes más importantes, reduciendo así significativamente la carga de recursos computacionales sin comprometer la eficiencia del modelo. Según nuestros análisis iniciales, logramos más del 90 % de precisión para todas las clases individualmente, excepto para los archivos XML, donde logramos solo el 49 %. Esto indicó que el modelo puede tener un problema de sobreajuste. El sobreajuste puede ocurrir cuando el modelo usa demasiadas características, lo que hace que tome decisiones más rápido, por ejemplo, en los puntos finales de los árboles de decisión. Esto puede dar como resultado una alta precisión en el conjunto de entrenamiento, pero una peor generalización de los datos reales. Una de las formas más efectivas de lidiar con el sobreajuste es reducir la cantidad de funciones utilizadas. El modelo final contiene una combinación de tres características. Primero, 256 funciones de un solo byte que examinan la frecuencia de aparición de cada byte. A esto le sigue una característica adicional que mide la proporción de los símbolos ‘<' y '>‘ (bytes 60 y 62), que son particularmente útiles para reconocer archivos XML. Finalmente, el modelo incluye 42 características seleccionadas de dos bytes que, según un análisis previo, son más relevantes para la identificación del tipo de archivo. Estas características combinadas ayudan a aumentar la precisión del modelo a la hora de identificar diferentes tipos de archivos. Una vez finalizado el modelo, se encontraron las siguientes precisiones en la pila de prueba, desglosadas por tipo de archivo. Dado que los elementos de una columna en una tabla son del mismo tipo, se puede aumentar la precisión clasificando estos puntos de datos binarios simultáneamente en un conjunto, ya que incluso si hay un punto de datos mal clasificado en el conjunto, los otros puntos de datos empujarán el promedio hacia la clasificación correcta. Las mediciones del tiempo de ejecución de API para diferentes tamaños de conjuntos para el modelo arrojaron los siguientes resultados (el tamaño promedio de archivo fue de 5 MB y las pruebas se realizaron en una máquina con un procesador Intel Core i7-2600 de 3,4 GHz y 1333 MHz de RAM). Se midieron los siguientes tiempos de ejecución según el uso de la memoria: – 89,428 segundos con un uso máximo de RAM de 7,28 GB – 56,451 segundos con un uso máximo de RAM de 4,55 GB – 30,186 segundos con un uso máximo de RAM de 2,58 GB La imagen de Docker consta de los siguientes archivos: La estructura del dockerfile es la siguiente: El reconocimiento del formato de archivo es un desafío en la migración de datos, especialmente para sistemas heredados no documentados. La estructura de codificación de los archivos, como los BLOB, dificulta la identificación del formato y se necesitan métodos más avanzados. Nuestra experiencia muestra que la combinación del aprendizaje automático con la distribución de frecuencia de bytes (BFD) puede identificar archivos de manera eficiente en función de sus patrones de distribución de bytes. La precisión del modelo se puede aumentar agregando secuencias de bytes específicas y características para distinguir de manera confiable entre diferentes formatos. El modelo final resultante, que se ejecuta en un entorno Dockerizado, se puede implementar como un servicio flexible y eficiente que se puede utilizar en proyectos de migración de datos. .
La figura anterior muestra la progresión de la precisión para las 3 clases de precisión más bajas (XLSX, XLS, XML) para diferentes tamaños de conjuntos. Se eligen las tres clases de precisión más bajas porque requieren el tamaño de conjunto más grande para lograr una precisión general del 100%. El método nos permite determinar el tamaño mínimo de conjunto requerido en el peor de los casos. Se puede ver que incluso en el peor de los casos, la precisión promedio del modelo aumenta a casi el 100% al clasificar 7 archivos a la vez.
Implementación de reconocimiento de archivos basada en microservicios
El servicio está en contenedores utilizando Docker, basándose en los módulos fastAPI y uvicorn de Python. En el proceso de llamada a la API, el sistema primero recibe la solicitud y luego convierte los datos recibidos al formato binario (Base64). Luego, los datos binarios se utilizan para generar el valor de Distribución de frecuencia de bytes (BFD) del punto de datos. Una vez que se genera el BFD, el BFD asociado con el punto de datos y un modelo de tipo lightGBM se utilizan para clasificar la detección del tipo de archivo. El sistema registra los eventos y maneja cualquier error. Finalmente, al finalizar el proceso, el sistema envía una respuesta al usuario.
En la llamada de servicio, la estructura del cuerpo contiene solo dos campos «datos», este atributo es una lista de objetos JSON y «id». Estos objetos JSON tienen un campo de «bit» (que es una cadena que contiene la versión codificada en base64 del archivo).
La respuesta del punto final /predict es un objeto JSON que contiene un código de estado. La estructura del objeto JSON es similar al cuerpo de la solicitud. La respuesta contendrá un campo de “datos” cuyo valor es una lista. Esta lista contiene objetos JSON adicionales que contienen los campos «id» y «pred». El valor del campo «id» puede ser el identificador asignado al elemento enviado o un identificador generado si no se especificó originalmente para el campo «bit». El campo de predicción («pred») también contiene un objeto JSON que contiene pares clave-valor de extensión y probabilidad.
Pensamientos finales





