Gegevens voorbereiden voor het bouwen van een model

Meer informatie over het gebruik van ML.NET om gegevens voor te bereiden op aanvullende verwerking of het bouwen van een model.

Gegevens zijn vaak onreine en parserend. ML.NET machine learning-algoritmen verwachten dat invoer of functies in één numerieke vector staan. Op dezelfde manier moet de waarde die moet worden voorspeld (label), met name wanneer het categorische gegevens zijn, worden gecodeerd. Daarom is een van de doelen van gegevensvoorbereiding het ophalen van de gegevens in de indeling die wordt verwacht door ML.NET algoritmen.

Gegevens splitsen in trainings- en testsets

In de volgende sectie worden veelvoorkomende problemen beschreven bij het trainen van een model dat overfitting en underfitting wordt genoemd. Het splitsen van uw gegevens en validatie van uw modellen met behulp van een vastgezette set kan u helpen deze problemen te identificeren en te verhelpen.

Overfitting & underfitting

Overfitting en underfitting zijn de twee meest voorkomende problemen die u ondervindt bij het trainen van een model. Underfitting betekent dat de geselecteerde trainer niet in staat is om de trainingsgegevensset aan te passen en meestal resulteert in een hoog verlies tijdens de training en een lage score/meetwaarde voor de testgegevensset. U kunt dit oplossen door een krachtiger model te selecteren of meer functie-engineering uit te voeren. Overfitting is het tegenovergestelde, wat gebeurt wanneer het model de trainingsgegevens te goed leert. Dit resulteert meestal in een metrische waarde met weinig verlies tijdens de training, maar een hoog verlies bij de testgegevensset.

Een goede analogie voor deze concepten is studeren voor een examen. Stel dat u de vragen en antwoorden van tevoren wist. Na het studeren neemt u de test en krijgt u een perfecte score. Geweldig nieuws! Wanneer u het examen echter opnieuw krijgt met de vragen gerangschikt en met iets andere formulering krijgt u een lagere score. Dat stelt voor dat u de antwoorden hebt onthouden en niet de concepten hebt geleerd waarop u bent getest. Dit is een voorbeeld van overfitting. Underfitting is het tegenovergestelde waar de studiematerialen die u hebt gegeven niet nauwkeurig vertegenwoordigen waar u op het examen bent geëvalueerd. Als gevolg hiervan kunt u de antwoorden raden omdat u niet voldoende kennis hebt om correct te antwoorden.

Gegevens splitsen

Neem de volgende invoergegevens en laad deze in een IDataView aangeroepen naam data:

var homeDataList = new HomeData[]
{
    new()
    {
        NumberOfBedrooms = 1f,
        Price = 100_000f
    },
    new()
    {
        NumberOfBedrooms = 2f,
        Price = 300_000f
    },
    new()
    {
        NumberOfBedrooms = 6f,
        Price = 600_000f
    },
    new()
    {
        NumberOfBedrooms = 3f,
        Price = 300_000f
    },
    new()
    {
        NumberOfBedrooms = 2f,
        Price = 200_000f
    }
};

Als u gegevens wilt splitsen in trainings-/testsets, gebruikt u de TrainTestSplit(IDataView, Double, String, Nullable<Int32>) methode.

// Apply filter
TrainTestData dataSplit = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);

De testFraction parameter wordt gebruikt voor het testen van 0,2 of 20% van de gegevensset. De resterende 80% wordt gebruikt voor training.

Het resultaat is DataOperationsCatalog.TrainTestData met twee IDataViews waartoe u toegang hebt via TrainSet en TestSet.

Gegevens filteren

Soms zijn niet alle gegevens in een gegevensset relevant voor analyse. Een benadering voor het verwijderen van irrelevante gegevens is filteren. De DataOperationsCatalog bevat een set filterbewerkingen die IDataView alle gegevens bevatten en een IDataView retourneren die alleen de nuttige gegevenspunten bevat. Het is belangrijk om te weten dat omdat filterbewerkingen geen IEstimator of ITransformer vergelijkbaar filterbewerkingen zijn, TransformsCatalogze niet kunnen worden opgenomen als onderdeel van een EstimatorChain pijplijn of TransformerChain gegevensvoorbereidingspijplijn.

Neem de volgende invoergegevens en laad deze in een IDataView aangeroepen naam data:

HomeData[] homeDataList = new HomeData[]
{
    new ()
    {
        NumberOfBedrooms=1f,
        Price=100000f
    },
    new ()
    {
        NumberOfBedrooms=2f,
        Price=300000f
    },
    new ()
    {
        NumberOfBedrooms=6f,
        Price=600000f
    }
};

Als u gegevens wilt filteren op basis van de waarde van een kolom, gebruikt u de FilterRowsByColumn methode.

// Apply filter
IDataView filteredData = mlContext.Data.FilterRowsByColumn(data, "Price", lowerBound: 200000, upperBound: 1000000);

Het bovenstaande voorbeeld neemt rijen in de gegevensset met een prijs tussen 200000 en 1000000. Het resultaat van het toepassen van dit filter retourneert alleen de laatste twee rijen in de gegevens en sluit de eerste rij uit omdat de prijs 100000 is en niet tussen het opgegeven bereik.

Ontbrekende waarden vervangen

Ontbrekende waarden zijn een veelvoorkomend exemplaar in gegevenssets. Een benadering voor het omgaan met ontbrekende waarden is om deze te vervangen door de standaardwaarde voor het opgegeven type, indien van toepassing of een andere zinvolle waarde, zoals de gemiddelde waarde in de gegevens.

Neem de volgende invoergegevens en laad deze in een IDataView aangeroepen naam data:

HomeData[] homeDataList = new HomeData[]
{
    new ()
    {
        NumberOfBedrooms=1f,
        Price=100000f
    },
    new ()
    {
        NumberOfBedrooms=2f,
        Price=300000f
    },
    new ()
    {
        NumberOfBedrooms=6f,
        Price=float.NaN
    }
};

U ziet dat het laatste element in onze lijst een ontbrekende waarde heeft voor Price. Als u de ontbrekende waarden in de Price kolom wilt vervangen, gebruikt u de ReplaceMissingValues methode om die ontbrekende waarde in te vullen.

Belangrijk

ReplaceMissingValue werkt alleen met numerieke gegevens.

// Define replacement estimator
var replacementEstimator = mlContext.Transforms.ReplaceMissingValues("Price", replacementMode: MissingValueReplacingEstimator.ReplacementMode.Mean);

// Fit data to estimator
// Fitting generates a transformer that applies the operations of defined by estimator
ITransformer replacementTransformer = replacementEstimator.Fit(data);

// Transform data
IDataView transformedData = replacementTransformer.Transform(data);

ML.NET ondersteunt verschillende vervangingsmodi. In het bovenstaande voorbeeld wordt de Mean vervangingsmodus gebruikt, waarmee de ontbrekende waarde wordt ingevuld met de gemiddelde waarde van die kolom. Het resultaat van de vervanging vult de Price eigenschap in voor het laatste element in onze gegevens met 200.000, omdat dit het gemiddelde is van 100.000 en 300.000.

Normalizers gebruiken

Normalisatie is een techniek voor gegevensverwerking die wordt gebruikt om functies in hetzelfde bereik te schalen, meestal tussen 0 en 1, zodat ze nauwkeuriger kunnen worden verwerkt door een machine learning-algoritme. De bereiken voor leeftijd en inkomen variëren bijvoorbeeld aanzienlijk met leeftijd in het algemeen in het bereik van 0-100 en inkomen in het algemeen in het bereik van nul tot duizenden. Ga naar de pagina transformaties voor een gedetailleerdere lijst en beschrijving van normalisatietransformaties.

Minimale normalisatie

Neem de volgende invoergegevens en laad deze in een IDataView aangeroepen naam data:

HomeData[] homeDataList = new HomeData[]
{
    new ()
    {
        NumberOfBedrooms = 2f,
        Price = 200000f
    },
    new ()
    {
        NumberOfBedrooms = 1f,
        Price = 100000f
    }
};

Normalisatie kan worden toegepast op kolommen met enkele numerieke waarden en vectoren. Normaliseer de gegevens in de Price kolom met behulp van minimale normalisatie met de NormalizeMinMax methode.

// Define min-max estimator
var minMaxEstimator = mlContext.Transforms.NormalizeMinMax("Price");

// Fit data to estimator
// Fitting generates a transformer that applies the operations of defined by estimator
ITransformer minMaxTransformer = minMaxEstimator.Fit(data);

// Transform data
IDataView transformedData = minMaxTransformer.Transform(data);

De oorspronkelijke prijswaarden [200000,100000] worden geconverteerd naar [ 1, 0.5 ] het gebruik van de MinMax normalisatieformule waarmee uitvoerwaarden in het bereik van 0-1 worden gegenereerd.

Binning

Binning converteert doorlopende waarden naar een discrete weergave van de invoer. Stel dat een van uw functies leeftijd is. In plaats van de werkelijke leeftijdswaarde te gebruiken, maakt binning bereiken voor die waarde. 0-18 kan één bin zijn, een andere kan 19-35 zijn, enzovoort.

Neem de volgende invoergegevens en laad deze in een IDataView aangeroepen naam data:

HomeData[] homeDataList = new HomeData[]
{
    new ()
    {
        NumberOfBedrooms=1f,
        Price=100000f
    },
    new ()
    {
        NumberOfBedrooms=2f,
        Price=300000f
    },
    new ()
    {
        NumberOfBedrooms=6f,
        Price=600000f
    }
};

Normaliseer de gegevens in opslaglocaties met behulp van de NormalizeBinning methode. Met de maximumBinCount parameter kunt u het aantal opslaglocaties opgeven dat nodig is om uw gegevens te classificeren. In dit voorbeeld worden gegevens in twee opslaglocaties geplaatst.

// Define binning estimator
var binningEstimator = mlContext.Transforms.NormalizeBinning("Price", maximumBinCount: 2);

// Fit data to estimator
// Fitting generates a transformer that applies the operations of defined by estimator
var binningTransformer = binningEstimator.Fit(data);

// Transform Data
IDataView transformedData = binningTransformer.Transform(data);

Het resultaat van binning maakt bin-grenzen van [0,200000,Infinity]. Daarom zijn [0,1,1] de resulterende klassen omdat de eerste observatie tussen 0 en 200000 ligt en de andere klassen groter zijn dan 200000, maar kleiner dan oneindig.

Werken met categorische gegevens

Een van de meest voorkomende typen gegevens is categorische gegevens. Categorische gegevens hebben een eindig aantal categorieën. Bijvoorbeeld de staten van de VS of een lijst met de soorten dieren die in een set afbeeldingen zijn gevonden. Of de categorische gegevens functies of labels zijn, ze moeten worden toegewezen aan een numerieke waarde, zodat ze kunnen worden gebruikt om een machine learning-model te genereren. Er zijn verschillende manieren om te werken met categorische gegevens in ML.NET, afhankelijk van het probleem dat u oplost.

Sleutelwaardetoewijzing

In ML.NET is een sleutel een geheel getal dat een categorie vertegenwoordigt. Sleutelwaardetoewijzing wordt meestal gebruikt om tekenreekslabels toe te wijzen aan unieke gehele getallen voor training en vervolgens terug naar de tekenreekswaarden wanneer het model wordt gebruikt om een voorspelling te doen.

De transformaties die worden gebruikt om sleutelwaardetoewijzing uit te voeren, zijn MapValueToKey en MapKeyToValue.

MapValueToKey voegt een woordenlijst met toewijzingen toe aan het model, zodat MapKeyToValue de omgekeerde transformatie kan worden uitgevoerd bij het maken van een voorspelling.

Eén dynamische codering

Eén dynamische codering neemt een eindige set waarden en wijst deze toe aan gehele getallen waarvan de binaire weergave één 1 waarde in unieke posities in de tekenreeks heeft. Een dynamische codering kan de beste keuze zijn als er geen impliciete volgorde van de categorische gegevens is. In de volgende tabel ziet u een voorbeeld met postcodes als onbewerkte waarden.

Onbewerkte waarde Eén dynamisch gecodeerde waarde
98052 00...01
98100 00...10
... ...
98109 10...00

De transformatie voor het converteren van categorische gegevens naar gecodeerde getallen met één hot is OneHotEncoding.

Hashing

Hashing is een andere manier om categorische gegevens te converteren naar getallen. Met een hash-functie worden gegevens van een willekeurige grootte (bijvoorbeeld een tekenreeks) toegewezen aan een getal met een vast bereik. Hashing kan een snelle en ruimte-efficiënte manier zijn om functies te vectoriseren. Een opmerkelijk voorbeeld van hashing in machine learning is spamfiltering voor e-mail, waarbij in plaats van een woordenlijst van bekende woorden elk woord in de e-mail wordt gehasht en toegevoegd aan een grote functievector. Door hashing op deze manier te gebruiken, voorkomt u het probleem van schadelijke spamfilters door het gebruik van woorden die niet in de woordenlijst staan.

ML.NET biedt hashtransformatie om hashing uit te voeren op tekst, datums en numerieke gegevens. Net als waardesleuteltoewijzing zijn de uitvoer van de hash-transformatie sleuteltypen.

Werken met tekstgegevens

Net als categorische gegevens moeten tekstgegevens worden omgezet in numerieke functies voordat ze worden gebruikt om een machine learning-model te bouwen. Ga naar de pagina transformaties voor een gedetailleerdere lijst en beschrijving van teksttransformaties.

Gegevens zoals de onderstaande gegevens gebruiken die in een IDataView:

ReviewData[] reviews = new ReviewData[]
{
    new ReviewData
    {
        Description="This is a good product",
        Rating=4.7f
    },
    new ReviewData
    {
        Description="This is a bad product",
        Rating=2.3f
    }
};

ML.NET biedt de transformatie die de FeaturizeText tekenreekswaarde van een tekst gebruikt en een reeks functies van de tekst maakt door een reeks afzonderlijke transformaties toe te passen.

// Define text transform estimator
var textEstimator  = mlContext.Transforms.Text.FeaturizeText("Description");

// Fit data to estimator
// Fitting generates a transformer that applies the operations of defined by estimator
ITransformer textTransformer = textEstimator.Fit(data);

// Transform data
IDataView transformedData = textTransformer.Transform(data);

Met de resulterende transformatie worden de tekstwaarden in de Description kolom geconverteerd naar een numerieke vector die er ongeveer als volgt uitziet:

[ 0.2041241, 0.2041241, 0.2041241, 0.4082483, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0.2041241, 0, 0, 0, 0, 0.4472136, 0.4472136, 0.4472136, 0.4472136, 0.4472136, 0 ]

De transformaties waaruit bestaat FeaturizeText , kunnen ook afzonderlijk worden toegepast voor nauwkeurigere controle over het genereren van functies.

// Define text transform estimator
var textEstimator = mlContext.Transforms.Text.NormalizeText("Description")
    .Append(mlContext.Transforms.Text.TokenizeIntoWords("Description"))
    .Append(mlContext.Transforms.Text.RemoveDefaultStopWords("Description"))
    .Append(mlContext.Transforms.Conversion.MapValueToKey("Description"))
    .Append(mlContext.Transforms.Text.ProduceNgrams("Description"))
    .Append(mlContext.Transforms.NormalizeLpNorm("Description"));

textEstimator bevat een subset van bewerkingen die door de FeaturizeText methode worden uitgevoerd. Het voordeel van een complexere pijplijn is controle en zichtbaarheid van de transformaties die op de gegevens worden toegepast.

Met behulp van de eerste vermelding als voorbeeld is het volgende een gedetailleerde beschrijving van de resultaten die worden geproduceerd door de transformatiestappen die zijn gedefinieerd door textEstimator:

Oorspronkelijke tekst: Dit is een goed product

Transformeren Beschrijving Result
1. NormalizeText Converteert alle letters standaard naar kleine letters dit is een goed product
2. TokenizeWords Splitst de tekenreeks in afzonderlijke woorden ["this","is","a","good","product"]
3. RemoveDefaultStopWords Hiermee verwijdert u stopwoorden zoals is en a. ["goed","product"]
4. MapValueToKey Kaarten de waarden voor sleutels (categorieën) op basis van de invoergegevens [1,2]
5. ProduceNGrams Transformeert tekst in volgorde van opeenvolgende woorden [1,1,1,0,0]
6. NormalizeLpNorm Invoer schalen op lp-norm [ 0.577350529, 0.577350529, 0.577350529, 0, 0 ]