Delen via


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-& 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 & onderfitting

Overfitting en underfitting zijn de twee meest voorkomende problemen die je tegenkomt 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 fenomeen, dat 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 geval waarin de studiematerialen die u zijn gegeven niet goed overeenkomen met waarop u wordt beoordeeld tijdens het examen. 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 met de 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
    }
};

Gebruik de methode TrainTestSplit(IDataView, Double, String, Nullable<Int32>) om gegevens te splitsen in trainings-/testsets.

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

De parameter testFraction wordt gebruikt om 0,2 of 20% van de gegevensset te gebruiken om te testen. 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 een IDataView met alle gegevens ontvangen en een IDataView- retourneren, die alleen de relevante gegevenspunten bevat. Het is belangrijk te weten dat, omdat filterbewerkingen geen IEstimator of ITransformer zijn zoals die in de TransformsCatalog, ze niet kunnen worden opgenomen als onderdeel van een EstimatorChain of TransformerChain gegevensvoorbereidingspijplijn.

Neem de volgende invoergegevens en laad deze in een IDataView met de 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 methode FilterRowsByColumn.

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

Het bovenstaande voorbeeld selecteert rijen in de dataset 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 verschijnsel in datasets. 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 met de 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 de lijst een ontbrekende waarde heeft voor Price. Als u de ontbrekende waarden in de kolom Price wilt vervangen, gebruikt u de methode ReplaceMissingValues 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 eigenschap Price in voor het laatste element in de gegevens met 200.000, omdat dit het gemiddelde is van 100.000 en 300.000.

Normalizers gebruiken

Normalisatie is een techniek voor gegevensvoorverwerking 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 van leeftijd en inkomen variëren bijvoorbeeld aanzienlijk, waarbij leeftijd over het algemeen varieert van 0 tot 100, en inkomen meestal varieert van nul tot enkele duizenden. Ga naar de pagina transformaties voor een gedetailleerdere lijst en beschrijving van normalisatietransformaties.

Min-max-normalisatie

Neem de volgende invoergegevens en laad deze in een IDataView met de 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 kolom Price met min-max-normalisatie met behulp van de methode NormalizeMinMax.

// 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 ] met behulp van de MinMax normalisatieformule die uitvoerwaarden genereert in het bereik van 0-1.

Binning

Binning- continue waarden converteert naar een discrete weergave van de invoer. Stel dat een van uw kenmerken leeftijd is. In plaats van de werkelijke leeftijdswaarde te gebruiken, maakt binning reeksen 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 met de 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 categorieën met behulp van de NormalizeBinning-methode. Met de parameter maximumBinCount 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 het binningproces creëert de bin-grenzen van [0,200000,Infinity]. Daarom zijn de resulterende klassen [0,1,1] omdat de eerste observatie tussen 0 en 200000 ligt en de andere klassen groter zijn dan 200000 maar minder 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.

Sleutel-waardetoewijzing

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 uitvoeren 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 one-hot gecodeerde getallen 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 Hash transformatie om hashing uit te voeren op tekst, datums en numerieke gegevens. Net als bij de waarde-sleuteltoewijzing 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 meer gedetailleerde lijst en beschrijving van teksttransformaties.

Gebruik onderstaande gegevens die zijn geladen 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 FeaturizeText transformatie die de tekenreekswaarde van een tekst gebruikt en een set 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);

De resulterende transformatie converteert de tekstwaarden in de kolom Description 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 FeaturizeText bestaat, 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 worden uitgevoerd door de methode FeaturizeText. 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 Resultaat
1. NormalizeText Converteert alle letters standaard naar kleine letters dit is een goed product
2. TokenizeWords Splitst de tekenreeks in afzonderlijke woorden Dit is een goed product.
3. StandaardstopwoordenVerwijderen Verwijdert stopwoorden zoals is en een. ["goede","product"]
4. MapValueToKey Wijst de waarden toe aan 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 volgens hun lp-norm [ 0.577350529, 0.577350529, 0.577350529, 0, 0 ]