Zu migrierende Datenbanken können ein breites Spektrum an Datendarstellungen und Inhalten aufweisen. Von einfachen numerischen Datenfeldern bis hin zu Feldern mit komplexer Struktur und Inhalt, die Dateien, Bilder, Tabellen oder sogar komplexe benutzerdefinierte Objekte (z. B. in den Formaten XML, CLOB, BLOB usw.) enthalten können.
Die Entdeckung einfacherer Daten kann mit herkömmlichen Methoden mit einigen Grundkenntnissen und Wertesätzen einfach und sehr effizient durchgeführt werden. Mit zunehmender Komplexität der Daten nimmt diese Effizienz jedoch ab, bis herkömmliche Methoden nicht mehr ausreichen.
Solche komplexeren Daten können beispielsweise unstrukturierte Text- oder Binärdateien sein, deren Art und Inhalt nicht eindeutig identifiziert und interpretiert werden können. Der Argumentation halber vernachlässigen wir die Tatsache, dass der Einsatz solcher Datentypen in Datenbanken nur in wenigen Einzelfällen gerechtfertigt ist, da dieses Problem häufig bei der Migration komplexer Systeme auftritt. Diese komplexen Datenformate sind in der Regel unstrukturiert und bestehen strukturell lediglich aus einer Reihe von Bytes in einem bestimmten Feld, über die der Benutzer aufgrund unvollständiger Dokumentation häufig keine verlässlichen Informationen hat. Ohne Metainformationen ist es schwierig, Rückschlüsse auf die Art des Inhalts und seine Interpretation zu ziehen. Unsere erste Aufgabe besteht also darin, über diese Felder zu entscheiden, welche Art von Daten sie enthalten.
Der naheliegendste Weg, die Dateitypen zu identifizieren, besteht darin, ihre Erweiterung zu überprüfen. Bei der Speicherung in einer Datenbank sind diese Informationen jedoch normalerweise nicht verfügbar, oder selbst wenn dies der Fall wäre, könnten sie nicht mit maximaler Sicherheit verwendet werden. Unter der Annahme, dass nur die binäre Version der Daten verfügbar ist, also Binary Large Object (BLOB), besteht der erste Schritt darin, sie zu laden. Alle Metadaten werden in diesem BLOB entsprechend dem Format der Datei codiert.
Abhängig vom Format der Datei oder der Art der Daten können die Metadaten in der Datei an mehreren Stellen in der Datei erscheinen, entweder im Header oder am Ende der Datei. Neben der Identifizierung des Dateiformats können Dateiheader auch Metadaten über die Datei und ihren Inhalt enthalten. Zeichenbasierte (Text-)Dateien haben normalerweise zeichenbasierte Header, während Binärformate normalerweise binäre Header haben, obwohl dies kein Standard, sondern lediglich Branchenpraxis ist.
Die Verteilung der Bytewerte in verschiedenen Dateitypen zeigt für jeden Typ ein anderes Muster. Frühe Versuche konzentrierten sich auf die Byteverteilung der gesamten Datei, neuere Methoden führen jedoch andere Stichproben durch, z. B. die Analyse nur Stichproben vom Anfang, Ende und der Mitte der Dateien. Diese Beispiele können eine gute Grundlage dafür bieten maschinelles Lernendas (mit einiger Wahrscheinlichkeit) den Typ unbekannter Dateien mithilfe eines Modells bestimmen kann, das auf den verschiedenen Distributionen basiert. In einem Verfahren basierend auf BFD (Byte Frequency Distribution) ist es nicht notwendig, die gesamte Datei zu lesen, was Zeit spart. Die an mehreren Stellen in der Datei extrahierten Werte werden statistisch analysiert, um einen für die Datei spezifischen Fingerabdruck zu erhalten. Basierend auf diesem Fingerabdruck ist maschinelles Lernen in der Lage, den Dateityp im Modell zu finden – den, den wir ihm mit bekannten Dateien beigebracht haben –, der am besten zu ihm passt.
Die folgende Abbildung zeigt die Byteverteilung einiger Dateitypen:
Bitte beachten Sie, dass alle Codes und Eingabe-/Ausgabedatenbeispiele in diesem Artikel von Clarity Consulting abgeleitet sind MigNon Werkzeug. Diese Datenmigrations-Assistentensoftware ist das Ergebnis eines mehrjährigen Forschungs- und Entwicklungsprojekts, das teilweise von der Europäischen Union finanziert wird.
Anwendung von maschinellem Lernen zur Erkennung von Dateiformaten
Maschinelles Lernen kann eine effektive Methode zur Dateiformaterkennung sein, insbesondere bei der Arbeit mit großen Datenmengen. Für die Dateiformaterkennung kommen folgende Modelle in Betracht:
- Naiver Bayes: Geeignet für byte- oder sequenzbasierte Analysen, bei denen typische Merkmale jedes Dateiformats, wie z. B. Byteverteilungen oder charakteristische Muster, berücksichtigt werden.
- Support Vector Machines (SVM): Eine gute Wahl, wenn die Grenzen zwischen Dateiformaten, dh Entscheidungsoberflächen, auf der Grundlage der Bytehäufigkeit definiert werden müssen.
- Zufälliger Wald: Unter den Ensemble-Lernmethoden wird Random Forest häufig verwendet, da es viele verschiedene Dateiformate verarbeiten und mit verrauschten Daten umgehen kann.
- Faltungs-Neuronale Netze (CNNs): CNNs sind in der Lage, Byte-Verteilungsmuster zu erkennen und Dateien als Bilder zu behandeln, wobei die Byte-Häufigkeit als „Pixel“ interpretiert wird, wodurch verschiedene Dateiformate erkannt werden.
- Autoencoder: kann für unüberwachtes Lernen verwendet werden, insbesondere zur Anomalieerkennung, wenn versucht wird, Dateien mit einem anderen Bytemuster als dem üblichen für ein bestimmtes Dateiformat zu erkennen.
- K-Nächste Nachbarn (KNN): Bei kleinen Datensätzen kann dies eine einfache, aber effektive Möglichkeit sein, Dateiformate anhand der Ähnlichkeit ihrer nächsten Nachbarn zu identifizieren.
- Wiederkehrende neuronale Netze (RNNs): Da RNNs sequentielle Daten effizient verarbeiten, können sie für Aufgaben nützlich sein, bei denen Bytesequenzen in einer Datei wichtig sind.
Für die automatisierte Dateiformaterkennung ist die LightGBM (Light Gradient Boosting Machine) kann aus mehreren Gründen eine gute Wahl sein. Erstens ist es bei großen und vielfältigen Datensätzen hocheffizient, für schnelles Lernen und Vorhersagen optimiert und eignet sich daher gut für Dateiformatanalysen mit großen Byteverteilungen oder vielen Stichproben. Es benötigt wenig Speicher, was bei der Erkennung und Klassifizierung mehrerer Dateiformate in einem System ein wichtiger Gesichtspunkt sein kann. Es gehört zur Familie der Gradient-Boosting-Modelle, mit denen komplexe Entscheidungsoberflächen effizient modelliert werden können. Diese Genauigkeit kann bei der Erkennung von Dateiformaten von entscheidender Bedeutung sein, wenn die Bytehäufigkeit diskrete Verteilungen aufweisen kann.
Die LightGBM-Lösung ist datengesteuert, und da wir eine größere Datenmenge benötigen, um ein Modell in der richtigen Qualität zu erstellen, haben wir in unserem Beispiel dafür ein quasi-automatisiertes Download-System erstellt. Um unser automatisiertes Download-System zu implementieren, verwendeten wir Selenium in Python, um den Browser mithilfe eines Firefox-Treibers zu steuern. Dies ermöglichte es uns, nach Links und HTML-Elementen zu suchen und dann darauf Aktionen auszuführen, wie zum Beispiel das Anklicken oder die Eingabe von Daten. Während der automatischen Downloads haben wir Dateitypen wie CSV, DOC, DOCX, XML, JPG, JSON, PDF, PNG, XLS und XLSX verarbeitet, aber einige Dateien, wie MP3 oder AVI, mussten manuell gesammelt und verarbeitet werden. Die Dateien wurden aus verschiedenen Quellen gesammelt, beispielsweise von kaggle.com für CSV- und JSON-Dateien, während PNG- und JPG-Bilder von imgur.com heruntergeladen wurden. YouTube-Videos wurden im MP4-Format von btclod.com heruntergeladen und mit WinFF in AVI konvertiert. Bei ZIP-Dateien wurden Komprimierung und Download von separaten Python-Skripten durchgeführt. Die automatisierten Downloads wurden sorgfältig in einer geeigneten Verzeichnisstruktur organisiert. Downloadvolumen und Datenqualität wurden durch Parameter innerhalb des Programms gesteuert. Einige unserer Testdaten wurden manuell gesammelt, um sicherzustellen, dass es unterschiedliche Dateien gab. Da wir jedoch nicht von jedem Dateityp ausreichende Mengen sammeln konnten, blieben in vielen Fällen automatische Downloads die primäre Methode zur Generierung von Eingaben.
Die erhaltenen Eingabedatenmengen waren wie folgt:


Das Erkennen der Details des in der Einleitung erwähnten Byte-Häufigkeitsverteilungsmusters ist die Grundlage für den Aufbau des LightGBM-Modells auf den gesammelten Daten. Die Verarbeitung einer vollständigen Byteliste ist kostspielig. Um die Dateierweiterung zu ermitteln, werden die Daten daher über ein BFD gefiltert, was als eine Art „partielles Fingerprinting“ angesehen werden kann. Mithilfe dieser Eingabedaten können wir den Typ einiger Dateien für das Modell bestimmen. Dies geschieht durch die Erstellung einer Häufigkeits-HASH-MAP aus einem Array von Bytes, wobei die Schlüssel die Bytes und die Werte die Anzahl der Vorkommen sind. Da es sich bei den Schlüsseln um positive Zahlen (0 bis 255) handelt, kann diese HASH-MAP problemlos in ein Array umgewandelt werden, was den Normalisierungsprozess beschleunigt. Unter Normalisierung versteht man in diesem Fall die Konstruktion einer Wahrscheinlichkeitsverteilung aus den Häufigkeitswerten. Als Ergebnis ergibt die Summe der normalisierten Häufigkeiten den Wert 1. Diese normalisierte Form ist der BFD.
Testen und Tuning des Modells
Das Hauptproblem bei der Definition von Dateierweiterungen bestand darin, dass das ursprüngliche Modell, das mit 256 Bytes arbeitete, nicht in der Lage war, zwischen ähnlichen Formaten wie XML, JSON, ZIP, DOCX und XLSX zu unterscheiden. Dabei war das ZIP-Format besonders verwirrend, da sowohl DOCX als auch XLSX in einer ZIP-Datei verpacktes XML enthalten. Auch Verwechslungen zwischen XML und JSON kamen häufig vor, da sie sich in der Struktur sehr ähneln. Aufgrund dieser Faktoren blieb die Genauigkeit des Modells für diese Dateitypen gering, was eine Verbesserung des Modells und die Einführung neuer Funktionen erforderlich machte.
Um die Genauigkeit zu verbessern, wurden die folgenden Funktionen hinzugefügt
- Byteraten von 60, 62
- Byteraten von 123, 125
- sharedStrings-Byteserie
Um das Modell zu verfeinern, haben wir mehrere bytespezifische Funktionen eingeführt, um verschiedene Dateitypen zu identifizieren. Beispielsweise spielten die Bytes 60 und 62, die den Symbolen „<“ und „>“ entsprechen, eine Schlüsselrolle bei der genauen Identifizierung von XML-Dateien. Ebenso waren die Bytes 123 und 125, die die Zeichen „{“ und „}“ darstellen, bei der Identifizierung von JSON-Dateien hilfreich. Zur Erkennung von DOCX-Dateien haben wir das Verhältnis der Bytefolge „ Für die Erkennung von XLSX-Dateien hat die Bytefolge „sharedStrings“ sehr gut funktioniert, da alle XLSX-Dateien die Datei „sharedStrings.xml“ enthalten, die nicht vom ZIP-Format geparst wird. Diese Funktion wurde jedoch schließlich verworfen, da sie aufgrund ihrer Länge zu empfindlich auf selbst kleinste Änderungen reagierte. Obwohl diese Funktionen die Effizienz des Modells verbesserten, blieb die genaue Identifizierung der ZIP-Dateien problematisch und wir mussten eine andere Methode verwenden, um sie zu identifizieren. Da wir nicht genau wussten, welche Funktionen zur zuverlässigen Identifizierung von ZIP-Dateien erforderlich wären, entschieden wir uns, alle möglichen 2-Byte-Kombinationen in das Modell einzubeziehen, um die Genauigkeit zu erhöhen. Allerdings war dieser Ansatz äußerst speicher-, zeit- und prozessorintensiv, da der Lernprozess große Datenmengen verarbeiten musste. Um dies zu optimieren, planten wir, nur die 500 wichtigsten 2-Byte-Features zu verwenden und so die Belastung der Rechenressourcen deutlich zu reduzieren, ohne die Effizienz des Modells zu beeinträchtigen. Basierend auf unseren ersten Analysen haben wir für alle Klassen einzeln eine Genauigkeit von über 90 % erreicht, mit Ausnahme von XML-Dateien, wo wir nur 49 % erreichten. Dies deutete darauf hin, dass das Modell möglicherweise ein Überanpassungsproblem aufweist. Eine Überanpassung kann auftreten, wenn das Modell zu viele Funktionen verwendet, was dazu führt, dass Entscheidungen schneller getroffen werden, beispielsweise an den Endpunkten von Entscheidungsbäumen. Dies kann zu einer hohen Genauigkeit des Trainingssatzes, aber zu einer schlechteren Verallgemeinerung realer Daten führen. Eine der effektivsten Möglichkeiten, mit Überanpassung umzugehen, besteht darin, die Anzahl der verwendeten Funktionen zu reduzieren. Das endgültige Modell enthält eine Kombination aus drei Funktionen. Erstens 256 Einzelbyte-Funktionen, die die Häufigkeit des Auftretens jedes Bytes untersuchen. Darauf folgt eine zusätzliche Funktion, die den Anteil der „<“- und „>“-Symbole (Byte 60 und 62) misst, die besonders für die Erkennung von XML-Dateien nützlich sind. Schließlich umfasst das Modell 42 ausgewählte Zwei-Byte-Merkmale, die basierend auf früheren Analysen für die Identifizierung des Dateityps am relevantesten sind. Diese kombinierten Funktionen tragen dazu bei, die Genauigkeit des Modells bei der Identifizierung verschiedener Dateitypen zu erhöhen. Nach der Fertigstellung des Modells wurden auf dem Teststapel die folgenden Genauigkeiten gefunden, aufgeschlüsselt nach Dateityp. Da die Elemente einer Spalte in einer Tabelle vom gleichen Typ sind, kann die Genauigkeit erhöht werden, indem diese binären Datenpunkte gleichzeitig in einem Satz klassifiziert werden, denn selbst wenn ein falsch klassifizierter Datenpunkt im Satz vorhanden ist, werden die anderen Datenpunkte dies verdrängen Durchschnitt in Richtung der korrekten Klassifizierung. API-Laufzeitmessungen für verschiedene Satzgrößen für das Modell ergaben die folgenden Ergebnisse (die durchschnittliche Dateigröße betrug 5 MB und der Test wurde auf einem Computer mit einem Intel Core i7-2600 3,4-GHz-Prozessor und 1333 MHz RAM durchgeführt). Abhängig von der Speichernutzung wurden folgende Laufzeiten gemessen: – 89,428 Sekunden bei einer maximalen RAM-Nutzung von 7,28 GB – 56,451 Sekunden bei einer maximalen RAM-Nutzung von 4,55 GB – 30,186 Sekunden bei einer maximalen RAM-Nutzung von 2,58 GB Das Docker-Image besteht aus den folgenden Dateien: Die Struktur der Docker-Datei ist wie folgt: Die Erkennung von Dateiformaten ist eine Herausforderung bei der Datenmigration, insbesondere für undokumentierte Altsysteme. Die Kodierungsstruktur von Dateien wie BLOBs erschwert die Formatidentifizierung und erfordert fortschrittlichere Methoden. Unsere Erfahrung zeigt, dass durch die Kombination von maschinellem Lernen mit der Byte-Häufigkeitsverteilung (BFD) Dateien anhand ihrer Byte-Verteilungsmuster effizient identifiziert werden können. Die Genauigkeit des Modells kann durch das Hinzufügen spezifischer Bytesequenzen und Funktionen erhöht werden, um zuverlässig zwischen verschiedenen Formaten zu unterscheiden. Das resultierende endgültige Modell, das in einer Docker-Umgebung ausgeführt wird, kann als flexibler und effizienter Dienst implementiert werden, der in Datenmigrationsprojekten verwendet werden kann .
Die obige Abbildung zeigt den Genauigkeitsverlauf für die drei niedrigsten Genauigkeitsklassen (XLSX, XLS, XML) für verschiedene Satzgrößen. Die drei niedrigsten Genauigkeitsklassen werden ausgewählt, da sie die größte Satzgröße erfordern, um eine Gesamtgenauigkeit von 100 % zu erreichen. Die Methode ermöglicht es uns, die im schlimmsten Fall erforderliche Mindestsatzgröße zu bestimmen. Es ist ersichtlich, dass selbst im schlimmsten Fall die durchschnittliche Genauigkeit des Modells bei der gleichzeitigen Klassifizierung von 7 Dateien auf nahezu 100 % steigt.
Microservice-basierte Implementierung der Dateierkennung
Der Dienst wird mithilfe von Docker in Containern verpackt und basiert auf den Python-Modulen fastAPI und uvicorn. Beim API-Aufrufprozess empfängt das System zunächst die Anfrage und konvertiert dann die empfangenen Daten in das Binärformat (Base64). Die Binärdaten werden dann verwendet, um den BFD-Wert (Byte Frequency Distribution) des Datenpunkts zu generieren. Sobald das BFD generiert ist, werden das mit dem Datenpunkt verknüpfte BFD und ein LightGBM-Typmodell zur Klassifizierung der Dateityperkennung verwendet. Das System protokolliert die Ereignisse und behandelt etwaige Fehler. Am Ende des Prozesses sendet das System schließlich eine Antwort an den Benutzer.
Im Serviceaufruf enthält die Body-Struktur nur zwei Felder „data“, dieses Attribut ist eine Liste von JSON-Objekten, und „id“. Diese JSON-Objekte verfügen über ein „Bit“-Feld (eine Zeichenfolge, die die Base64-codierte Version der Datei enthält).
Die Antwort vom /predict-Endpunkt ist ein JSON-Objekt, das einen Statuscode enthält. Die Struktur des JSON-Objekts ähnelt dem Hauptteil der Anfrage. Die Antwort enthält ein „Daten“-Feld, dessen Wert eine Liste ist. Diese Liste enthält zusätzliche JSON-Objekte, die die Felder „id“ und „pred“ enthalten. Der Wert des Felds „id“ kann entweder die dem übermittelten Element zugewiesene Kennung oder eine generierte Kennung sein, wenn sie ursprünglich nicht für das Feld „bit“ angegeben wurde. Das Vorhersagefeld („pred“) enthält auch ein JSON-Objekt, das Schlüssel-Wert-Paare aus Erweiterung und Wahrscheinlichkeit enthält.
Abschließende Gedanken





