Databases die moeten worden gemigreerd, kunnen een breed scala aan gegevensrepresentaties en inhoud hebben. Van eenvoudige numerieke gegevensvelden tot velden met een complexe structuur en inhoud, die bestanden, afbeeldingen, tabellen of zelfs complexe aangepaste objecten kunnen bevatten (bijvoorbeeld in XML-, CLOB-, BLOB enz.-formaten).
Het ontdekken van eenvoudigere gegevens kan eenvoudig en zeer efficiënt worden gedaan met behulp van traditionele methoden met enige basiskennis en waardensets. Naarmate de gegevens echter complexer worden, neemt deze efficiëntie af totdat traditionele methoden niet langer voldoende zijn.
Dergelijke complexere gegevens kunnen bijvoorbeeld ongestructureerde tekst of binaire bestanden zijn waarvan het type en de inhoud niet duidelijk kunnen worden geïdentificeerd en geïnterpreteerd. Laten we ter wille van de discussie voorbijgaan aan het feit dat het gebruik van dergelijke gegevenstypen in databases slechts in een paar specifieke gevallen gerechtvaardigd is, aangezien dit probleem zich vaak voordoet bij het migreren van complexe systemen. Deze complexe dataformaten zijn meestal ongestructureerd, structureel slechts een set bytes in een bepaald veld, waarover de gebruiker vaak geen betrouwbare informatie heeft vanwege onvolledige documentatie. Zonder meta-informatie is het moeilijk om conclusies te trekken over het type inhoud en de interpretatie ervan. Onze eerste taak is dus om over deze velden te beslissen wat voor soort gegevens ze bevatten.
De meest voor de hand liggende manier om de typen bestanden te identificeren is door hun extensie te controleren, maar wanneer deze informatie in een database wordt opgeslagen, is deze informatie doorgaans niet beschikbaar, of zelfs als dat wel het geval zou zijn, zou deze niet met maximaal vertrouwen kunnen worden gebruikt. Ervan uitgaande dat alleen de binaire versie van de gegevens beschikbaar is, dat wil zeggen Binary Large Object (BLOB), is de eerste stap het laden ervan. Alle metadata worden in deze BLOB gecodeerd, volgens het formaat van het bestand.
Afhankelijk van het formaat van het bestand of het type gegevens kunnen de metadata in het bestand op meerdere plaatsen in het bestand voorkomen: in de header of aan het einde van het bestand. Naast het identificeren van het bestandsformaat, kunnen bestandskoppen ook metagegevens over het bestand en de inhoud ervan bevatten. Op tekens gebaseerde (tekst)bestanden hebben doorgaans op tekens gebaseerde headers, terwijl binaire formaten meestal binaire headers hebben, hoewel dit geen standaard is, maar slechts een industriële praktijk.
De verdeling van bytewaarden in verschillende bestandstypen vertoont voor elk type een ander patroon. Vroege pogingen waren gericht op de byteverdeling van het hele bestand, maar recentere methoden voeren verschillende steekproeven uit, zoals het analyseren van alleen monsters vanaf het begin, het einde en het midden van bestanden. Deze monsters kunnen hiervoor een goede basis bieden machinaal lerendie (met enige waarschijnlijkheid) het type onbekende bestanden kan bepalen met behulp van een model dat is gebouwd op de verschillende distributies. In een procedure gebaseerd op BFD (Byte Frequency Distribution) is het niet nodig om het hele bestand te lezen, wat tijd bespaart. De waarden die uit verschillende posities in het bestand worden gehaald, worden statistisch geanalyseerd om een vingerafdruk te verkrijgen die specifiek is voor het bestand. Op basis van deze vingerafdruk kan machine learning het bestandstype vinden in het model – het model dat we hebben aangeleerd met bekende bestanden – dat er het beste bij past.
De onderstaande afbeelding toont de byteverdeling van sommige bestandstypen:
Houd er rekening mee dat alle codes en voorbeelden van invoer-/uitvoergegevens in dit artikel zijn afgeleid van die van Clarity Consulting MigNon hulpmiddel. Deze assistent-software voor gegevensmigratie is het resultaat van een meerjarig R&D-project, gedeeltelijk gefinancierd door de Europese Unie.
Machine learning toepassen op herkenning van bestandsformaten
Machine learning kan een effectieve methode zijn voor het herkennen van bestandsformaten, vooral bij het werken met grote datasets. Voor de detectie van bestandsformaten kunnen de volgende modellen worden overwogen:
- Naïeve Bayes: Geschikt voor byte- of sequentiegebaseerde analyse, waarbij rekening wordt gehouden met typische kenmerken van elk bestandsformaat, zoals byteverdelingen of karakteristieke patronen.
- Ondersteuning van vectormachines (SVM): Een goede keuze wanneer de grenzen tussen bestandsformaten, dat wil zeggen beslissingsoppervlakken, moeten worden gedefinieerd op basis van bytefrequentie.
- Willekeurig bos: Onder de ensemble-leermethoden wordt Random Forest vaak gebruikt omdat het veel verschillende bestandsformaten kan verwerken en met ruis kan omgaan.
- Convolutionele neurale netwerken (CNN’s): CNN’s zijn in staat byte-distributiepatronen te herkennen en kunnen bestanden behandelen als afbeeldingen waarbij de bytefrequentie wordt geïnterpreteerd als “pixels”, waardoor verschillende bestandsformaten worden herkend.
- Automatische encoder: kan worden gebruikt voor leren zonder toezicht, vooral voor het detecteren van afwijkingen, wanneer wordt geprobeerd bestanden te detecteren met een bytepatroon dat verschilt van het gebruikelijke patroon voor een bepaald bestandsformaat.
- K-dichtstbijzijnde buren (KNN): Voor kleine datasets kan dit een eenvoudige maar effectieve manier zijn om bestandsformaten te identificeren op basis van de gelijkenis van hun naaste buren.
- Terugkerende neurale netwerken (RNN’s): Omdat RNN’s efficiënt omgaan met sequentiële gegevens, kunnen ze nuttig zijn voor taken waarbij reeksen bytes in een bestand belangrijk zijn.
Voor automatische herkenning van bestandsformaten kan de LichtGBM (Light Gradient Boosting Machine)-model kan om verschillende redenen een goede keuze zijn. Ten eerste is het zeer efficiënt op grote en diverse datasets, geoptimaliseerd voor snel leren en voorspellen, en presteert het dus goed voor de analyse van bestandsformaten met grote byteverdelingen of veel samples. Het vereist weinig geheugen, wat een belangrijke overweging kan zijn bij het detecteren en classificeren van meerdere bestandsformaten in een systeem. Het is een lid van de gradiëntversterkende modelfamilie, die complexe beslissingsoppervlakken efficiënt kan modelleren. Deze nauwkeurigheid kan van cruciaal belang zijn bij de detectie van bestandsformaten, waarbij de bytefrequentie discrete distributies kan hebben.
De LightGBM-oplossing is datagedreven en omdat we een grotere hoeveelheid data nodig hebben om een model van de juiste kwaliteit te bouwen, hebben we hier in ons voorbeeld een quasi-geautomatiseerd downloadsysteem voor gemaakt. Om ons geautomatiseerde downloadsysteem te implementeren, hebben we Selenium in Python gebruikt om de browser te besturen met behulp van een Firefox-stuurprogramma. Hierdoor konden we naar links en HTML-elementen zoeken en er vervolgens acties op uitvoeren, zoals klikken of gegevens invoeren. Tijdens automatische downloads verwerkten we bestandstypen zoals CSV, DOC, DOCX, XML, JPG, JSON, PDF, PNG, XLS en XLSX, maar sommige bestanden, zoals MP3 of AVI, moesten handmatig worden verzameld en verwerkt. Bestanden werden verzameld uit verschillende bronnen, zoals kaggle.com voor CSV- en JSON-bestanden, terwijl PNG- en JPG-afbeeldingen werden gedownload van imgur.com. YouTube-video’s zijn gedownload in MP4-formaat van btclod.com en geconverteerd naar AVI met behulp van WinFF. Voor ZIP-bestanden werden de compressie en het downloaden afgehandeld door afzonderlijke Python-scripts. De geautomatiseerde downloads werden zorgvuldig georganiseerd in een geschikte directorystructuur. Het downloadvolume en de gegevenskwaliteit werden gecontroleerd door parameters binnen het programma. Sommige van onze testgegevens werden handmatig verzameld om er zeker van te zijn dat er verschillende bestanden waren, maar we konden niet van alle bestandstypen voldoende hoeveelheden verzamelen, dus in veel gevallen bleven automatische downloads de primaire methode om invoer te genereren.
De verkregen hoeveelheden inputgegevens waren als volgt:


Het herkennen van de details van het bytefrequentieverdelingspatroon dat in de inleiding wordt genoemd, vormt de basis voor het bouwen van het LightGBM-model op basis van de verzamelde gegevens. Het verwerken van een volledige bytelijst is kostbaar, dus om de bestandsextensie te bepalen worden de gegevens gefilterd via een BFD, wat gezien kan worden als een soort “partial Fingerprinting”. Door dit als invoergegevens te gebruiken, kunnen we het type van sommige bestanden voor het model bepalen. Dit wordt gedaan door een frequentie-HASH-MAP te maken op basis van een array van bytes, waarbij de sleutels de bytes zijn en de waarden het aantal keren dat deze voorkomen. Omdat de sleutels positieve getallen zijn (0 tot 255), kan deze HASH-MAP eenvoudig worden geconverteerd naar een array, wat het normalisatieproces versnelt. Normalisatie betekent in dit geval het construeren van een waarschijnlijkheidsverdeling op basis van de frequentiewaarden. Als gevolg hiervan zal de som van de genormaliseerde frequenties de waarde 1 opleveren. Deze genormaliseerde vorm zal de BFD zijn.
Testen en afstemmen van het model
Het voornaamste probleem bij het definiëren van bestandsextensies was dat het oorspronkelijke model, dat met 256 bytes werkte, geen onderscheid kon maken tussen vergelijkbare formaten zoals XML, JSON, ZIP, DOCX en XLSX. Hiervan was het ZIP-formaat bijzonder verwarrend omdat zowel DOCX als XLSX XML bevatten, verpakt in een ZIP-bestand. Verwarring tussen XML en JSON kwam ook veel voor, omdat ze qua structuur erg op elkaar lijken. Vanwege deze factoren bleef de nauwkeurigheid van het model voor deze bestandstypen laag, waardoor het noodzakelijk was het model te verbeteren en nieuwe functies te introduceren.
Om de nauwkeurigheid te verbeteren zijn de volgende functies toegevoegd
- Bytesnelheden van 60, 62
- Bytesnelheden van 123, 125
- sharedStrings bytereeks
Om het model te verfijnen, hebben we verschillende bytespecifieke functies geïntroduceerd om verschillende bestandstypen te identificeren. Bytes 60 en 62, die overeenkomen met de symbolen ‘<' en '>‘, speelden bijvoorbeeld een sleutelrol bij het nauwkeurig identificeren van XML-bestanden. Op dezelfde manier waren bytes 123 en 125, die de tekens ‘{‘ en ‘}’ vertegenwoordigen, nuttig bij het identificeren van JSON-bestanden. Voor het herkennen van DOCX-bestanden gebruikten we de verhouding van de bytereeks ‘ Voor de detectie van XLSX-bestanden werkte de bytereeks “sharedStrings” heel goed omdat alle XLSX-bestanden het bestand sharedStrings.xml bevatten, dat niet wordt geparseerd door het ZIP-formaat. Dit kenmerk werd uiteindelijk echter verworpen omdat het door zijn lengte te gevoelig was voor zelfs de kleinste veranderingen. Hoewel deze functies de efficiëntie van het model verbeterden, bleef de exacte identificatie van de ZIP-bestanden problematisch en moesten we een andere methode gebruiken om ze te identificeren. Omdat we niet precies wisten welke functies nodig zouden zijn om ZIP-bestanden betrouwbaar te identificeren, hebben we besloten om alle mogelijke combinaties van 2 bytes in het model op te nemen om de nauwkeurigheid te vergroten. Deze aanpak vroeg echter extreem veel geheugen, tijd en processor, omdat het leerproces een enorme hoeveelheid gegevens moest verwerken. Om dit te optimaliseren, waren we van plan alleen de 500 belangrijkste 2-bytefuncties te gebruiken, waardoor de belasting van de computerbronnen aanzienlijk zou worden verminderd zonder de efficiëntie van het model in gevaar te brengen. Op basis van onze eerste analyses bereikten we een nauwkeurigheid van meer dan 90% voor alle klassen afzonderlijk, behalve voor XML-bestanden, waar we slechts 49% bereikten. Dit gaf aan dat het model mogelijk een overfittingprobleem heeft. Overfitting kan optreden wanneer het model te veel functies gebruikt, waardoor het sneller beslissingen neemt, bijvoorbeeld op de eindpunten van beslissingsbomen. Dit kan resulteren in een hoge nauwkeurigheid op de trainingsset, maar in een slechtere generalisatie op echte gegevens. Een van de meest effectieve manieren om overfitting aan te pakken, is het verminderen van het aantal gebruikte functies. Het uiteindelijke model bevat een combinatie van drie kenmerken. Ten eerste 256 single-byte-functies die de frequentie van voorkomen van elke byte onderzoeken. Dit wordt gevolgd door een extra functie die de verhouding van ‘<'- en '>‘-symbolen meet (bytes 60 en 62), die vooral handig zijn voor het herkennen van XML-bestanden. Ten slotte bevat het model 42 geselecteerde twee-byte-functies die, op basis van eerdere analyses, het meest relevant zijn voor de identificatie van bestandstypen. Deze gecombineerde functies helpen de nauwkeurigheid van het model te vergroten bij het identificeren van verschillende bestandstypen. Nadat het model was voltooid, werden de volgende nauwkeurigheden gevonden op de teststack, uitgesplitst naar bestandstype. Omdat de elementen van een kolom in een tabel van hetzelfde type zijn, kan de nauwkeurigheid worden vergroot door deze binaire datapunten tegelijkertijd in een set te classificeren. Zelfs als er één verkeerd geclassificeerd datapunt in de set zit, zullen de andere datapunten de druk op de ander vergroten. gemiddelde richting de juiste classificatie. API-runtimemetingen voor verschillende setgroottes voor het model leverden de volgende resultaten op (de gemiddelde bestandsgrootte was 5 MB en de tests werden uitgevoerd op een machine met een Intel Core i7-2600 3,4 GHz processor en 1333 MHz RAM). Afhankelijk van het geheugengebruik zijn de volgende looptijden gemeten: – 89,428 seconden met een maximaal RAM-gebruik van 7,28 GB – 56,451 seconden met een maximaal RAM-gebruik van 4,55 GB – 30,186 seconden met een maximaal RAM-gebruik van 2,58 GB De Docker-image bestaat uit de volgende bestanden: De structuur van dockerfile is als volgt: Herkenning van bestandsformaten is een uitdaging bij datamigratie, vooral voor ongedocumenteerde oudere systemen. De coderingsstructuur van bestanden, zoals BLOB’s, maakt identificatie van formaten moeilijk en er zijn meer geavanceerde methoden nodig. Onze ervaring leert dat het combineren van machine learning met bytefrequentieverdeling (BFD) bestanden efficiënt kan identificeren op basis van hun bytedistributiepatronen. De nauwkeurigheid van het model kan worden vergroot door specifieke bytereeksen en functies toe te voegen om op betrouwbare wijze onderscheid te maken tussen verschillende formaten. Het resulterende uiteindelijke model, dat draait in een Dockerized-omgeving, kan worden geïmplementeerd als een flexibele en efficiënte service die kan worden gebruikt in datamigratieprojecten. .
De afbeelding hierboven toont de voortgang van de nauwkeurigheid voor de 3 laagste nauwkeurigheidsklassen (XLSX, XLS, XML) voor verschillende setgroottes. De drie laagste nauwkeurigheidsklassen zijn gekozen omdat ze de grootste setgrootte vereisen om een algehele nauwkeurigheid van 100% te bereiken. Met deze methode kunnen we de minimale setgrootte bepalen die in het ergste geval nodig is. Het is duidelijk dat zelfs in het ergste geval de gemiddelde nauwkeurigheid van het model toeneemt tot bijna 100% bij het classificeren van 7 bestanden tegelijk.
Op microservices gebaseerde implementatie van bestandsherkenning
De service is gecontaineriseerd met behulp van Docker, voortbouwend op de Python fastAPI- en uvicorn-modules. Tijdens het API-oproepproces ontvangt het systeem eerst het verzoek en converteert het vervolgens de ontvangen gegevens naar binair (Base64) formaat. De binaire gegevens worden vervolgens gebruikt om de Byte Frequency Distribution (BFD)-waarde van het datapunt te genereren. Zodra de BFD is gegenereerd, worden de BFD die aan het datapunt is gekoppeld en een model van het lightGBM-type gebruikt voor classificatie van de detectie van het bestandstype. Het systeem registreert de gebeurtenissen en handelt eventuele fouten af. Ten slotte stuurt het systeem aan het einde van het proces een antwoord naar de gebruiker.
In de serviceaanroep bevat de Body-structuur slechts twee velden “data”, dit attribuut is een lijst met JSON-objecten en “id”. Deze JSON-objecten hebben een “bit”-veld (een tekenreeks die de base64-gecodeerde versie van het bestand bevat).
Het antwoord van het /predict-eindpunt is een JSON-object dat een statuscode bevat. De structuur van het JSON-object is vergelijkbaar met de hoofdtekst van het verzoek. Het antwoord bevat een veld ‘gegevens’ waarvan de waarde een lijst is. Deze lijst bevat aanvullende JSON-objecten die de velden ‘id’ en ‘pred’ bevatten. De waarde van het “id”-veld kan de identificatie zijn die aan het ingediende item is toegewezen, of een gegenereerde identificatie als deze oorspronkelijk niet voor het “bit”-veld is opgegeven. Het voorspellingsveld (“pred”) bevat ook een JSON-object dat sleutel-waardeparen voor extensie en waarschijnlijkheid bevat.
Afsluitende gedachten





