Novembre 2018
Volume 33 Numero 11
Esecuzione di test - Introduzione alla libreria a ML.NET
Dal James McCaffrey
La libreria a ML.NET è un insieme di open source di machine learning (ML) codice che può essere utilizzato direttamente nelle applicazioni .NET. La maggior parte delle librerie di Machine Learning, ad esempio TensorFlow, Keras, CNTK e PyTorch, sono scritti in Python e chiamare in routine di C++ di basso livello. Tuttavia, se si usa una libreria basata su Python, non è in modo facile per un'applicazione .NET per accedere a un modello di Machine Learning sottoposto a training. Fortunatamente, la libreria a ML.NET si integra perfettamente nelle applicazioni .NET.
Il modo migliore per vedere quale ha inizio in questo articolo è esaminiamo il programma di dimostrazione figura 1. La demo crea un modello di Machine Learning che consente di stimare se un incontro del paziente morire o sopravvivere basato su età, sesso e punteggio in un test medici kidney i pazienti. Poiché esistono solo due possibili risultati, morire o sopravvivere, si tratta di un problema di classificazione binaria.
Figura 1 a ML.NET Demo programma in azione
Dietro le quinte, il programma demo utilizza la libreria a ML.NET per creare e addestrare un modello di regressione logistica. Poiché sto scrivendo questo articolo, la libreria a ML.NET è ancora in modalità di anteprima, alcune delle informazioni qui presentate sia stato modificato nel momento in cui che si sta leggendo questo articolo.
La demo Usa un set di dati di training con 30 elementi. Dopo che il modello è stato eseguito il training, è stata applicata all'origine dati e ottenere precisione 66,67% (20 10 e con correzione errata). La demo è terminata usando il modello con training per prevedere il risultato di un uomo di 50 anni con un punteggio di test kidney di 4.80, ovvero la stima sia che sarà mantenute in seguito al paziente.
Questo articolo si presuppone intermedio o programmazione meglio la capacità di utilizzare C#, ma non si conosce la libreria a ML.NET. Il codice completo e i dati per il programma demo vengono presentati in questo articolo e sono anche disponibili nel download del file associato.
Il programma Demo
Per creare il programma di dimostrazione, avviato Visual Studio 2017. La libreria a ML.NET funzionerà con l'edizione Community gratuita o una delle edizioni commerciali di Visual Studio 2017. La documentazione relativa a ML.NET non dichiarare in modo esplicito che Visual Studio 2017 è obbligatoria, ma non ha funzionato il programma demo per lavorare con Visual Studio 2015. È stato creato un nuovo oggetto C# progetto di applicazione console e di averlo denominato Kidney. La libreria a ML.NET funzionerà con .NET classica o il tipo di un'applicazione .NET Core.
Dopo aver caricato il codice del modello, pulsante destro del mouse sul file Program.cs nella finestra Esplora soluzioni e rinominato il file come KidneyProgram.cs e consentite Visual Studio di ridenominazione automatica della classe Program per l'utente corrente. Successivamente, nella finestra Esplora soluzioni, pulsante destro del mouse sul progetto Kidney e selezionato l'opzione Gestisci pacchetti NuGet. Nella finestra di NuGet, selezionato la scheda Sfoglia e quindi immettere "A ML.NET" nel campo di ricerca. La libreria a ML.NET si trova nel pacchetto Microsoft.ML. Selezionato che il pacchetto e fatto clic sul pulsante di installazione. Dopo pochi secondi Visual Studio ha risposto con un messaggio "Installazione completata Microsoft.ML 0.3.0 di rene".
A questo punto ha una compilazione | Ricompila soluzione e ha ricevuto un messaggio di errore "architetture supporta solo x64". Nella finestra Esplora soluzioni, pulsante destro del mouse sul progetto Kidney e seleziona la voce di proprietà. Nella finestra Proprietà, è stata selezionata la scheda Build a sinistra e quindi modificare la voce di destinazione della piattaforma da "Any CPU" a "x64". Ho anche apportato che stavo come destinazione la versione di .NET Framework 4.7. Con le versioni precedenti è stato visualizzato un errore correlato a una delle dipendenze della libreria matematica ed era necessario modificare manualmente il file con estensione csproj globale. Ugh. Quindi ho fatto una compilazione | Ricompila soluzione e ha avuto esito positivo. Quando si usano le librerie di modalità di anteprima, ad esempio a ML.NET, bisogna anomalie simile alla seguente regola anziché l'eccezione.
I dati Demo
Dopo aver creato la struttura del programma dimostrativo, il passaggio successivo è creare il file di dati di training. I dati vengono presentati nelle figura 2. Nella finestra Esplora soluzioni, pulsante destro del mouse sul progetto Kidney e selezionare Aggiungi | Nuovo elemento. Dal nuovo elemento finestra di dialogo è possibile selezionare il tipo di File di testo e denominato KidneyData.txt. Se state procedendo, copiare i dati dal figura 2 e incollarlo nella finestra dell'editor, prestando attenzione a non avere tutte le righe vuote finale aggiuntiva.
Figura 2 Kidney dati
48, +1, 4.40, survive
60, -1, 7.89, die
51, -1, 3.48, survive
66, -1, 8.41, die
40, +1, 3.05, survive
44, +1, 4.56, survive
80, -1, 6.91, die
52, -1, 5.69, survive
56, -1, 4.01, survive
55, -1, 4.48, survive
72, +1, 5.97, survive
57, -1, 6.71, die
50, -1, 6.40, survive
80, -1, 6.67, die
69, +1, 5.79, survive
39, -1, 5.42, survive
68, -1, 7.61, die
47, +1, 3.24, survive
45, +1, 4.29, survive
79, +1, 7.44, die
44, -1, 2.55, survive
52, +1, 3.71, survive
55, +1, 5.56, die
76, -1, 7.80, die
51, -1, 5.94, survive
46, +1, 5.52, survive
48, -1, 3.25, survive
58, +1, 4.71, survive
44, +1, 2.52, survive
68, -1, 8.38, die
Il set di dati di 30-item è artificiali e deve essere facilmente comprensibile per la maggior parte. Il campo sesso viene codificato come maschio = -1 e female = + 1. Poiché i dati hanno tre dimensioni (età, sesso, test di punteggio), non è possibile per visualizzarlo in un grafico bidimensionale. Ma è possibile ottenere una buona idea della struttura dei dati esaminando il grafico degli appena età e il relativo punteggio del test in figura 3. Il grafico suggerisce che i dati potrebbero essere linearmente separabili.
Figura 3 Kidney dati
Il codice del programma
Il codice dimostrativo completo, con alcune modifiche di lieve entità per risparmiare spazio, viene visualizzato nella figura 4. Nella parte superiore della finestra dell'Editor, rimosso tutti i riferimenti di spazio dei nomi e sostituendoli con quelli illustrati nel listato di codice. I vari spazi dei nomi Microsoft.ML ospitare tutte le funzionalità a ML.NET. Lo spazio dei nomi Tasks è necessaria per salvare o caricare un modello con training a ML.NET al file.
Figura 4 programma di esempio a ML.NET
using System;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Runtime.Api;
using Microsoft.ML.Trainers;
using Microsoft.ML.Transforms;
using Microsoft.ML.Models;
using System.Threading.Tasks;
namespace Kidney
{
class KidneyProgram
{
public class KidneyData
{
[Column(ordinal: "0", name: "Age")]
public float Age;
[Column(ordinal: "1", name: "Sex")]
public float Sex;
[Column(ordinal: "2", name: "Kidney")]
public float Kidney;
[Column(ordinal: "3", name: "Label")]
public string Label;
}
public class KidneyPrediction
{
[ColumnName("PredictedLabel")]
public string PredictedLabels;
}
static void Main(string[] args)
{
Console.WriteLine("ML.NET (v0.3.0 preview) demo run");
Console.WriteLine("Survival based on age, sex, kidney");
var pipeline = new LearningPipeline();
string dataPath = "..\\..\\KidneyData.txt";
pipeline.Add(new TextLoader(dataPath).
CreateFrom<KidneyData>(separator: ','));
pipeline.Add(new Dictionarizer("Label"));
pipeline.Add(new ColumnConcatenator("Features", "Age",
"Sex", "Kidney"));
pipeline.Add(new LogisticRegressionBinaryClassifier());
pipeline.Add(new
PredictedLabelColumnOriginalValueConverter()
{ PredictedLabelColumn = "PredictedLabel" });
Console.WriteLine("\nStarting training \n");
var model = pipeline.Train<KidneyData,
KidneyPrediction>();
Console.WriteLine("\nTraining complete \n");
string ModelPath = "..\\..\\KidneyModel.zip";
Task.Run(async () =>
{
await model.WriteAsync(ModelPath);
}).GetAwaiter().GetResult();
var testData = new TextLoader(dataPath).
CreateFrom<KidneyData>(separator: ',');
var evaluator = new BinaryClassificationEvaluator();
var metrics = evaluator.Evaluate(model, testData);
double acc = metrics.Accuracy * 100;
Console.WriteLine("Model accuracy = " +
acc.ToString("F2") + "%");
Console.WriteLine("Predict 50-year male, kidney 4.80:");
KidneyData newPatient = new KidneyData()
{ Age = 50f, Sex = -1f, Kidney = 4.80f };
KidneyPrediction prediction = model.Predict(newPatient);
string result = prediction.PredictedLabels;
Console.WriteLine("Prediction = " + result);
Console.WriteLine("\nEnd ML.NET demo");
Console.ReadLine();
} // Main
} // Program
} // ns
Il programma demo definisce una classe denominata KidneyData, annidata nella classe di programma principale, che definisce la struttura interna dei dati di training. Ad esempio, la prima colonna è:
[Column(ordinal: "0", name: "Age")]
public float Age;
Si noti che il campo age viene dichiarato tipo float anziché di tipo double. In Machine Learning, tipo float è il tipo numerico predefinito perché l'aumento di precisione che offerti dall'uso di tipo double è quasi mai vale la pena la memoria risulta e riduzione delle prestazioni. Il valore da prevedere devono usare il nome "Label", ma i nomi dei campi di predittore può essere qualsiasi.
Il programma demo definisce una classe annidata denominata KidneyPrediction per contenere le stime del modello:
public class KidneyPrediction
{
[ColumnName("PredictedLabel")]
public string PredictedLabels;
}
Il nome di colonna "PredictedLabel" è obbligatorio ma, come illustrato, l'identificatore di stringa associata non deve necessariamente corrispondere.
Creazione e Training del modello
Il programma demo crea un modello di Machine Learning usando queste sette istruzioni:
var pipeline = new LearningPipeline();
string dataPath = "..\\..\\KidneyData.txt";
pipeline.Add(new TextLoader(dataPath).
CreateFrom<KidneyData>(separator: ','));
pipeline.Add(new Dictionarizer("Label"));
pipeline.Add(new ColumnConcatenator("Features", "Age", "Sex", "Kidney"));
pipeline.Add(new LogisticRegressionBinaryClassifier());
pipeline.Add(new PredictedLabelColumnOriginalValueConverter()
{ PredictedLabelColumn = "PredictedLabel" });
È possibile considerare l'oggetto pipeline come un modello senza training di Machine Learning e i dati necessari per il training del modello. È importante ricordare che i valori da prevedere nel file di dati sono "sopravvivere" o "rimetterci la vita". Dato che i modelli di Machine Learning supportano solo valori numerici, la classe Dictionarizer weirdly denominata viene utilizzata per codificare le due stringhe su 0 o 1. Il costruttore ColumnConcatenator combina le tre variabili di predittore in una funzione di aggregazione; utilizzo di un parametro della stringa risultato con il nome del "Funzionalità" è obbligatorio.
Esistono molte diverse tecniche di Machine Learning che è possibile usare per un problema di classificazione binaria. Usare la regressione logistica nel programma demo per mantenere le idee principali più chiare possibili, perché è senza dubbio la forma più semplice e più semplice di Machine Learning. Altri algoritmi di classificazione binaria supportati da a ML.NET includono AveragedPerceptronBinaryClassifier, FastForestBinaryClassifier e LightGbmClassifier.
Il programma demo esegue il training e Salva il modello usando queste istruzioni:
var model = pipeline.Train<KidneyData, KidneyPrediction>();
string ModelPath = "..\\..\\KidneyModel.zip";
Task.Run(async () =>
{
await model.WriteAsync(ModelPath);
}).GetAwaiter().GetResult();
La libreria a ML.NET metodo Train è molto complesso. Se si fa riferimento tornare alla schermata illustrata nella figura 1, noterete che Train esegue la normalizzazione automatica delle variabili di predittore, che li ridimensiona in modo che i valori di predittore di grandi dimensioni, ad esempio reddito annuale di una persona, non sommergere small valori, ad esempio il numero di una persona di elementi figlio. Il metodo Train Usa anche la regolarizzazione, che è una tecnica avanzata per migliorare l'accuratezza di un modello. In breve, a ML.NET esegue tutti i tipi di elaborazione avanzata, senza che sia necessario configurare in modo esplicito i valori dei parametri.
Salvataggio e valutare il modello
Dopo il training del modello, viene salvato su disco come segue:
string ModelPath = "..\\..\\KidneyModel.zip";
Task.Run(async () =>
{
await model.WriteAsync(ModelPath);
}).GetAwaiter().GetResult();
Poiché il metodo WriteAsync è asincrono, non è così facile per chiamarlo. L'approccio che è preferibile è la tecnica di wrapper illustrata. La mancanza di un metodo non asincrone per salvare un modello a ML.NET è un po' sorprendente, anche per una libreria che si trova in modalità di anteprima.
Il programma demo rende sul presupposto che il programma eseguibile due directory sotto la directory radice del progetto. In un sistema di produzione si desidera verificare che sia presente la directory di destinazione. In genere, in un progetto a ML.NET, desidero creare una sottodirectory di dati e una sottodirectory di modelli disattivata la cartella radice del progetto (Kidney in questo esempio) e salvare i dati e modelli in tali directory.
Il modello viene valutato con queste istruzioni:
var testData = new TextLoader(dataPath).
CreateFrom<KidneyData>(separator: ',');
var evaluator = new BinaryClassificationEvaluator();
var metrics = evaluator.Evaluate(model, testData);
double acc = metrics.Accuracy * 100;
Console.WriteLine("Model accuracy = " +
acc.ToString("F2") + "%");
Nella maggior parte degli scenari di Machine Learning devi due file di dati, ovvero uno impostato usato esclusivamente per il training e un secondo set di dati di test usato solo per la valutazione del modello. Per semplicità, il programma demo riutilizza singolo elemento di 30 file di dati per la valutazione del modello.
Il metodo Evaluate restituisce un oggetto che contiene numerose metriche, tra cui perdita logaritmica, precisione, richiamo, punteggio F1 e così via. L'oggetto restituito presenta anche un oggetto ConfusionMatrix eccezionale che può essere utilizzato per visualizzare i conteggi, ad esempio il numero di pazienti ai quali sono stati previsti per sopravvivere ma in realtà è stata interrotta.
Usando il modello con training
Il programma demo viene illustrato come utilizzare il modello con training per eseguire una stima:
Console.WriteLine("Predict 50-year male kidney = 4.80:");
KidneyData newPatient = new KidneyData()
{ Age = 50f, Sex = -1f, Kidney = 4.80f };
KidneyPrediction prediction = model.Predict(newPatient);
string result = prediction.PredictedLabels;
Console.WriteLine("Prediction = " + result);
Si noti che i valori letterali numerici per età, sesso e kidney punteggio usano il modificatore "f" poiché il modello prevede che i valori di tipo float. In questo esempio, il modello con training era disponibile perché il programma appena completata la formazione. Se si desidera eseguire una stima da un altro programma, è necessario caricare il modello sottoposto a training usando il metodo ReadAsync lungo le righe di:
PredictionModel<KidneyData,
KidneyPrediction> model = null;
Task.Run(async () =>
{
model2 = await PredictionModel.ReadAsync
<KidneyData, KidneyPrediction>(ModelPath);
}).GetAwaiter().GetResult();
Conclusioni
Anche se la raccolta a ML.NET è nuovo, nato torna molti anni. Poco dopo l'introduzione di Microsoft .NET Framework nel 2002, Microsoft Research ha iniziato a un progetto denominato "ricerca di text mining e spostamento", o TMSN, per consentire agli sviluppatori di software includere codice di Machine Learning nei prodotti e tecnologie Microsoft. Il progetto ha avuto esito positivo molto e nel corso degli anni sono aumentate le dimensioni e uso internamente presso Microsoft. In qualche punto intorno 2011 la libreria è stata rinominata in "il codice learning" (TLC). TLC è ampiamente usato all'interno di Microsoft ed è attualmente in versione 3.9. La libreria a ML.NET è un offshoot diretto di TLC, con funzionalità specifiche di Microsoft rimosse.
Dr. James McCaffreylavora per Microsoft Research Redmond, WA Ha lavorato su diversi prodotti Microsoft, tra cui Internet Explorer e Bing. Dr. È possibile contattarlo McCaffrey jamccaff@microsoft.com.
Grazie per i seguenti esperti tecnici Microsoft che ha esaminato in questo articolo: Lee Chris e Ricky Loynd