Esaminare i dati intermedi durante l'elaborazione
Di seguito viene descritto come esaminare i dati intermedi durante il caricamento, l'elaborazione e i passaggi di training del modello in ML.NET. I dati intermedi corrispondono all'output di ogni fase della pipeline di Machine Learning.
Si considerino i dati abitativi seguenti:
HousingData[] housingData = new HousingData[]
{
new HousingData
{
Size = 600f,
HistoricalPrices = new float[] { 100000f ,125000f ,122000f },
CurrentPrice = 170000f
},
new HousingData
{
Size = 1000f,
HistoricalPrices = new float[] { 200000f, 250000f, 230000f },
CurrentPrice = 225000f
},
new HousingData
{
Size = 1000f,
HistoricalPrices = new float[] { 126000f, 130000f, 200000f },
CurrentPrice = 195000f
},
new HousingData
{
Size = 850f,
HistoricalPrices = new float[] { 150000f,175000f,210000f },
CurrentPrice = 205000f
},
new HousingData
{
Size = 900f,
HistoricalPrices = new float[] { 155000f, 190000f, 220000f },
CurrentPrice = 210000f
},
new HousingData
{
Size = 550f,
HistoricalPrices = new float[] { 99000f, 98000f, 130000f },
CurrentPrice = 180000f
}
};
In ML.NET è possibile esaminare i dati intermedi come questo caricato in un IDataView
in vari modi, come descritto nelle sezioni seguenti.
Convertire IDataView in IEnumerable
Uno dei modi più rapidi per esaminare un'interfaccia IDataView
consiste nel convertirla in un'interfaccia IEnumerable
. Per eseguire questa conversione, usare il metodo CreateEnumerable
.
Per ottimizzare le prestazioni, impostare reuseRowObject
su true
. In questo modo, lo stesso oggetto viene popolato in modo pigro con i dati della riga corrente, invece di creare un nuovo oggetto per ogni riga del dataset.
// Create an IEnumerable of HousingData objects from IDataView
IEnumerable<HousingData> housingDataEnumerable =
mlContext.Data.CreateEnumerable<HousingData>(data, reuseRowObject: true);
// Iterate over each row
foreach (HousingData row in housingDataEnumerable)
{
// Do something (print out Size property) with current Housing Data object being evaluated
Console.WriteLine(row.Size);
}
Accedere a indici specifici con IEnumerable
Se è sufficiente accedere a una parte dei dati o a indici specifici, usare CreateEnumerable
e impostare il valore del parametro reuseRowObject
su false
, in modo che venga creato un nuovo oggetto per ogni riga richiesta del set di dati. Quindi, convertire IEnumerable
in una matrice o in un elenco.
Avviso
La conversione del risultato di CreateEnumerable
in una matrice o un elenco carica tutte le righe IDataView
richieste in memoria, che potrebbero influire sulle prestazioni.
Dopo aver creata la raccolta, sarà possibile eseguire operazioni sui dati. Il frammento di codice seguente seleziona le prime tre righe del dataset e calcola il prezzo corrente medio.
// Create an Array of HousingData objects from IDataView
HousingData[] housingDataArray =
mlContext.Data.CreateEnumerable<HousingData>(data, reuseRowObject: false)
.Take(3)
.ToArray();
// Calculate Average CurrentPrice of First Three Elements
HousingData firstRow = housingDataArray[0];
HousingData secondRow = housingDataArray[1];
HousingData thirdRow = housingDataArray[2];
float averageCurrentPrice = (firstRow.CurrentPrice + secondRow.CurrentPrice + thirdRow.CurrentPrice) / 3;
Esaminare i valori in una singola colonna
In qualsiasi momento del processo di creazione del modello, è possibile accedere ai valori in una singola colonna di un elemento IDataView
tramite il metodo GetColumn
. Il metodo GetColumn
restituisce tutti i valori in una singola colonna come IEnumerable
.
IEnumerable<float> sizeColumn = data.GetColumn<float>("Size").ToList();
Esaminare i valori IDataView una riga alla volta
L'interfaccia IDataView
viene valutata in modo differito. Per scorrere le righe di un'interfaccia IDataView
senza eseguire la conversione in IEnumerable
, come illustrato nelle sezioni precedenti di questo documento, creare una classe DataViewRowCursor
usando il metodo GetRowCursor
e passare la classe DataViewSchema di IDataView
come parametro. Quindi, per scorrere le righe, usare il metodo MoveNext
del cursore insieme ai delegati ValueGetter
per estrarre i rispettivi valori da ognuna delle colonne.
Importante
Ai fini delle prestazioni, i vettori in ML.NET usano VBuffer
anziché i tipi di raccolta nativi, ovvero Vector
e float[]
.
// Get DataViewSchema of IDataView
DataViewSchema columns = data.Schema;
// Create DataViewCursor
using (DataViewRowCursor cursor = data.GetRowCursor(columns))
{
// Define variables where extracted values will be stored to
float size = default;
VBuffer<float> historicalPrices = default;
float currentPrice = default;
// Define delegates for extracting values from columns
ValueGetter<float> sizeDelegate = cursor.GetGetter<float>(columns[0]);
ValueGetter<VBuffer<float>> historicalPriceDelegate = cursor.GetGetter<VBuffer<float>>(columns[1]);
ValueGetter<float> currentPriceDelegate = cursor.GetGetter<float>(columns[2]);
// Iterate over each row
while (cursor.MoveNext())
{
//Get values from respective columns
sizeDelegate.Invoke(ref size);
historicalPriceDelegate.Invoke(ref historicalPrices);
currentPriceDelegate.Invoke(ref currentPrice);
}
}
Visualizzare in anteprima il risultato della pre-elaborazione o dell'addestramento su un sottoinsieme dei dati
Avviso
Non usare Preview
nel codice da usare in ambienti di produzione perché è destinato al debug e può ridurre le prestazioni.
Il processo di creazione dei modelli è sperimentale e iterativo. Per visualizzare in anteprima l'aspetto dei dati dopo la pre-elaborazione o il training di un modello di Machine Learning in un subset dei dati, usare il metodo Preview
, che restituisce un DataDebuggerPreview
. Il risultato è un oggetto con proprietà ColumnView
e RowView
che sono entrambe un IEnumerable
e contengono i valori in una determinata colonna o riga. Specificare il numero di righe a cui applicare la trasformazione con il parametro maxRows
.
Il risultato dell'ispezione di un IDataView
è simile all'immagine seguente: