Adatok előkészítése modell készítéséhez

Megtudhatja, hogyan készíthet elő adatokat ML.NET további feldolgozásra vagy modell készítésére.

Az adatok gyakran tisztátalanok és ritkák. ML.NET gépi tanulási algoritmusok azt várják, hogy a bemenet vagy a funkciók egyetlen numerikus vektorban legyenek. Hasonlóképpen, az előrejelezendő értéket (címkét) is kódolni kell, különösen kategorikus adatok esetén. Ezért az adat-előkészítés egyik célja az adatok ML.NET algoritmusok által elvárt formátumba való beolvasása.

Adatok felosztása betanítási és tesztelési csoportokra

Az alábbi szakasz a túlillesztés és az alulillesztés néven ismert modell betanítása során előforduló gyakori problémákat ismerteti. Az adatok felosztása és a modellek érvényesítése egy visszatartott készlettel segíthet a problémák azonosításában és megoldásában.

Túlillesztés és alulillesztés

A modell betanítása során a két leggyakoribb probléma a túlillesztés és az alulillesztés. Az alulillesztés azt jelenti, hogy a kiválasztott tréner nem elég alkalmas a betanítási adatkészletek illesztésére, és általában magas veszteséget okoz a betanítás során, és alacsony pontszámot/metrikát eredményez a tesztadatkészleten. A probléma megoldásához egy hatékonyabb modellt kell választania, vagy több funkciófejlesztést kell végrehajtania. A túlillesztés az ellenkezője, ami akkor fordul elő, ha a modell túl jól tanulja meg a betanítási adatokat. Ez általában alacsony veszteségi metrikát eredményez a betanítás során, de a tesztadatkészlet nagy veszteséggel jár.

Ezekhez a fogalmakhoz jó analógia a vizsgára való tanulás. Tegyük fel, hogy előre tudta a kérdéseket és válaszokat. Tanulás után, akkor a teszt, és kap egy tökéletes pontszámot. Nagyszerű hír! Ha azonban ismét vizsgát kap a kérdések átrendezésével és kissé eltérő megfogalmazással, alacsonyabb pontszámot kap. Ez arra utal, hogy memorizálta a válaszokat, és valójában nem tanulta meg azokat a fogalmakat, amelyeken tesztelték. Ez egy példa a túlillesztésre. Az alulillesztés az ellenkezője annak, hogy a kapott tananyagok nem pontosan jelzik, hogy mit értékelnek ki a vizsgán. Ennek eredményeképpen a válaszokat kell kitalálnia, mivel nincs elég tudása a helyes válaszhoz.

Adatfelosztás

Vegye fel a következő bemeneti adatokat, és töltse be egy IDataView úgynevezettba 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
    }
};

Az adatok betanítási/tesztelési csoportokra való felosztásához használja a TrainTestSplit(IDataView, Double, String, Nullable<Int32>) módszert.

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

A testFraction paraméter az adathalmaz 0,2 vagy 20%-át használja tesztelésre. A fennmaradó 80% a betanításhoz használatos.

Az eredmény DataOperationsCatalog.TrainTestData két IDataViews, amely elérhető keresztül TrainSet és TestSet.

Adatok szűrése

Előfordulhat, hogy az adatkészletek nem minden adata releváns az elemzéshez. Az irreleváns adatok eltávolításának egyik módszere a szűrés. Ez DataOperationsCatalog olyan szűrőműveleteket tartalmaz, amelyek IDataView az összes adatot tartalmazzák, és egy olyan IDataView-t ad vissza, amely csak a fontos adatpontokat tartalmazza. Fontos megjegyezni, hogy mivel a szűrőműveletek nem vagy ITransformer hasonlók IEstimator a TransformsCatalogműveletben, nem vehetők fel egy EstimatorChain vagy TransformerChain több adatelőkészítési folyamat részeként.

Vegye fel a következő bemeneti adatokat, és töltse be egy IDataView úgynevezettba data:

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

Ha egy oszlop értéke alapján szeretne adatokat szűrni, használja a metódust FilterRowsByColumn .

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

A fenti minta 200000 és 1000000 közötti áron veszi fel az adathalmaz sorait. A szűrő alkalmazásának eredménye csak az adatok utolsó két sorát adja vissza, és kizárja az első sort, mert az ára 100000, és nem a megadott tartomány között.

Hiányzó értékek cseréje

A hiányzó értékek gyakran előfordulnak az adathalmazokban. A hiányzó értékek kezelésének egyik módszere az, ha azokat az adott típus alapértelmezett értékére cseréli, ha van ilyen vagy egy másik jelentőségteljes érték, például az adatok középértéke.

Vegye fel a következő bemeneti adatokat, és töltse be egy IDataView úgynevezettba data:

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

Figyelje meg, hogy a lista utolsó elemének hiányzik az értéke Price. Az oszlop hiányzó Price értékeinek cseréjéhez használja a metódust a ReplaceMissingValues hiányzó érték kitöltéséhez.

Fontos

ReplaceMissingValue csak numerikus adatokkal működik.

// 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 különböző cseremódokat támogat. A fenti minta a Mean helyettesítő módot használja, amely kitölti a hiányzó értéket az oszlop átlagértékével. A csere eredménye 200 000-zel tölti ki az Price adatok utolsó elemének tulajdonságát, mivel ez az átlag 100 000 és 300 000.

Normalizerek használata

A normalizálás egy adatelőfeldolgozási technika, amellyel a funkciók skálázása azonos tartományban, általában 0 és 1 között történik, hogy pontosabban lehessen feldolgozni őket egy gépi tanulási algoritmussal. Például az életkor és a jövedelem tartományai jelentősen eltérnek, mivel az életkor általában 0 és 100 között van, a jövedelmek pedig általában nulla és ezres közötti tartományban. A normalizálási átalakítások részletesebb listáját és leírását az átalakítások oldalon találja.

Minimális normalizálás

Vegye fel a következő bemeneti adatokat, és töltse be egy IDataView úgynevezettba data:

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

A normalizálás alkalmazható egyetlen numerikus értékkel és vektorokkal rendelkező oszlopokra. Normalizálja az oszlopban lévő adatokat a Price metódus minimális normalizálásával 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);

Az eredeti árértékek [200000,100000] a MinMax 0–1 tartományban kimeneti értékeket generáló normalizálási képlet használatával lesznek konvertálva[ 1, 0.5 ].

Binning

A binning a folyamatos értékeket a bemenet különálló ábrázolására alakítja át. Tegyük fel például, hogy az egyik funkciója az életkor. A tényleges korérték használata helyett a binning tartományokat hoz létre az adott értékhez. 0-18 lehet egy doboz, egy másik lehet 19-35 és így tovább.

Vegye fel a következő bemeneti adatokat, és töltse be egy IDataView úgynevezettba data:

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

Normalizálja az adatokat tárolókba a NormalizeBinning metódus használatával. A maximumBinCount paraméter lehetővé teszi az adatok besorolásához szükséges tárolók számának megadását. Ebben a példában az adatok két tárolóba kerülnek.

// 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);

A binning eredménye létrehozza a tárolók határait.[0,200000,Infinity] Ezért az eredményként kapott tárolók azért vannak [0,1,1] , mert az első megfigyelés 0 és 200000 között van, míg a többi nagyobb, mint 200000, de kisebb a végtelennél.

Kategorikus adatok használata

Az egyik leggyakoribb adattípus a kategorikus adatok. A kategorikus adatoknak véges számú kategóriájuk van. Például az USA államai, vagy a képeken található állatok típusainak listája. Függetlenül attól, hogy a kategorikus adatok jellemzők vagy címkék, numerikus értékre kell képezni őket, hogy gépi tanulási modellt lehessen létrehozni. A kategorikus adatok számos módon használhatók a ML.NET a megoldódott problémától függően.

Kulcsérték-leképezés

A ML.NET a kulcs egy egész szám, amely egy kategóriát jelöl. A kulcsérték-leképezés leggyakrabban a sztringfeliratok betanításhoz használt egyedi egész számértékekre való leképezésére szolgál, majd vissza a sztringértékekre, amikor a modell előrejelzést készít.

A kulcsérték-leképezés végrehajtásához használt átalakítások a MapValueToKey és a MapKeyToValue.

MapValueToKey Hozzáad egy leképezési szótárt a modellben, így MapKeyToValue az előrejelzés során végrehajthatja a fordított átalakítást.

Egy gyakori kódolás

Egy gyakori kódolás véges értékkészletet használ, és egész számokra képezi le őket, amelyek bináris ábrázolása egyetlen 1 értékkel rendelkezik a sztring egyedi pozícióiban. Egy gyakori kódolás akkor lehet a legjobb választás, ha a kategorikus adatok implicit sorrendje nincs. Az alábbi táblázat egy példát mutat be, amely nyers értékként tartalmazza az irányítószámokat.

Nyers érték Egy gyakori kódolt érték
98052. 00...01
98100 00...10
... ...
98109 10...00

A kategorikus adatok egy gyakori kódolt számmá alakításához az átalakítás a következő OneHotEncoding: .

Kivonatoláshoz

A kivonatolás egy másik módja a kategorikus adatok számmá alakításának. A kivonatfüggvény tetszőleges méretű adatokat (például szöveges sztringet) képez le rögzített tartományú számra. A kivonatolás a funkciók vektorizálásának gyors és helyhatékony módja lehet. A gépi tanulásban a kivonatolás egyik jelentős példája az e-mailek levélszemétszűrése, ahol az ismert szavak szótárának fenntartása helyett az e-mail minden szavát kivonatoltuk, és hozzáadjuk egy nagy funkcióvektorhoz. A kivonatolás ily módon elkerüli a kártékony levélszemétszűrés megkerülésének problémáját olyan szavak használatával, amelyek nem szerepelnek a szótárban.

ML.NET kivonatátalakítást biztosít a szöveges, dátum- és numerikus adatok kivonatolásához. Az értékkulcs-leképezéshez hasonlóan a kivonat-átalakítás kimenetei is kulcstípusok.

Szövegadatok használata

A kategorikus adatokhoz hasonlóan a szöveges adatokat is numerikus funkciókká kell alakítani, mielőtt gépi tanulási modell készítéséhez használná őket. A szövegátalakítások részletesebb listájáért és leírásáért látogasson el az átalakítások oldalra .

Olyan adatok használata, mint az alábbi adatok, amelyek betöltve lettek a következőbe 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 olyan FeaturizeText átalakítást biztosít, amely egy szöveg sztringértékét veszi fel, és egy sor egyéni átalakítás alkalmazásával létrehoz egy funkciókészletet a szövegből.

// 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);

Az eredményként kapott átalakítás az oszlop szöveges Description értékeit numerikus vektorsá alakítja, amely az alábbi kimenethez hasonlóan néz ki:

[ 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 ]

A létrehozott FeaturizeText átalakítások egyenként is alkalmazhatók a funkciógenerálás finomabb szemcsés vezérléséhez.

// 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 a metódus által végrehajtott műveletek egy részhalmazát FeaturizeText tartalmazza. Az összetettebb folyamatok előnye az adatokra alkalmazott átalakítások szabályozása és láthatósága.

Az első bejegyzést példaként használva az alábbiakban részletes leírást láthat a következő átalakítási lépések által textEstimatorlétrehozott eredményekről:

Eredeti szöveg: Ez egy jó termék

Átalakítás Leírás Eredmény
1. Szöveg normalizálása Alapértelmezés szerint az összes betűt kisbetűssé alakítja ez egy jó termék
2. TokenizeWords Sztring felosztása egyes szavakra ["this","is","a","good","product"]
3. RemoveDefaultStopWords Eltávolítja a stop szavakat, mint az is és a. ["good","product"]
4. MapValueToKey Térképek a kulcsok (kategóriák) értékeit a bemeneti adatok alapján [1,2]
5. ProduceNGrams Egymást követő szavak sorozatává alakítja a szöveget [1,1,1,0,0]
6. NormalizeLpNorm Bemenetek skálázása az lp-norma szerint [ 0.577350529, 0.577350529, 0.577350529, 0, 0 ]