Tento článek je součástí iniciativy The Fourth Annual C# Advent Calendar od Matthewa D. Grovese. Naleznete zde další užitečné články a návody, které denně publikují členové komunity a odborníci, takže si je každý den prohlédněte.
ML.NET je bezplatný, open-source a multiplatformní rámec strojového učení určený pro vývojáře .NET. ML.NET vám umožňuje znovu využít všechny znalosti, dovednosti, kód a knihovny, které již jako vývojář .NET máte, takže můžete snadno integrovat strojové učení do svých webových, mobilních, desktopových, her a aplikací IoT.
Můžete jej použít pro klasifikaci, regresi, časové řady a dokonce i scénáře počítačového vidění (hluboké učení, klasifikace obrázků) s více než 40 školiteli (algoritmy ML založené na úkolech), které máte k dispozici.
Od verze 1.4-preview je podporována třída DatabaseLoader, což znamená, že nyní můžeme trénovat a vytvářet modely přímo na relačních databázích, včetně SQL Server, Oracle, PostgreSQL, SQLite a dalších.
Pro tento příklad vytvořím model, který pomůže identifikovat, zda se u ženy může vyvinout diabetes na základě historických dat od jiných pacientů. Používám datovou sadu Kaggle, kterou si můžete stáhnout zde.
Poté vytvořte Pacienta tabulky pro uložení informací. Jediným požadavkem je použití skutečného datový typ pro číselná pole, protože ML.NET bude rozumět pouze tomuto typu. Další možností je provést operaci CAST při načítání dat a převodu polí na skutečná za běhu .
CREATE TABLE Patient(
Id int identity(1,1) primary key,
Pregnancies real not null,
Glucose real not null,
BloodPressure real not null,
SkinThickness real not null,
Insulin real not null,
BMI real not null,
DiabetesPedigreeFunction real not null,
Age real not null,
Output varchar(1) not null
)
A samozřejmě je potřeba vložit do tabulky všechna data ze souboru csv .
Nyní napíšeme nějaký kód!
Krok 1. Vytvořte nový projekt aplikace konzoly C#:
Krok 2. Přidejte do svého projektu následující balíčky Nuget:
- Microsoft.ML
- System.Data.SqlClient
- Microsoft.Extensions.Configuration
- Microsoft.Extensions.Configuration.Json
- Microsoft.Extensions.Configuration.FileExtensions
Krok 3. Přidejte do projektu soubor nastavení aplikace.
V tomto souboru přidejte ConnectionStrings kolekce s DbConnection živel. Hodnotou je samozřejmě připojovací řetězec k databázi, kde jsou uložena vaše data.
Například se připojím k databázi Azure SQL :
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"ConnectionStrings": {
"DbConnection": "Server=tcp:myserver.database.windows.net,1433;Initial Catalog=mydatabase;Persist Security Info=False;User ID=myadmin;Password=MYadm1n;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
}
}
POZNÁMKA:Nastavte Kopírovat do výstupního adresáře vlastnost pro tento soubor, jinak jej program později nepřečte.
Krok 4. Přidejte Modely složku do vašeho projektu. Uvnitř vytvořte novou třídu s názvem Pacient , který zahrnuje několik vlastností, které odpovídají struktuře tabulky. Každá vlastnost je také ozdobena LoadColumnAttribute s indexem založeným na nule, který představuje sloupec, který bude mapován z databázové tabulky.
using Microsoft.ML.Data;
namespace DiabetesPrediction.Models
{
public class Patient
{
[LoadColumn(0)]
public float Id { get; set; }
[LoadColumn(1)]
public float Pregnancies { get; set; }
[LoadColumn(2)]
public float Glucose { get; set; }
[LoadColumn(3)]
public float BloodPressure { get; set; }
[LoadColumn(4)]
public float SkinThickness { get; set; }
[LoadColumn(5)]
public float Insulin { get; set; }
[LoadColumn(6)]
public float BMI { get; set; }
[LoadColumn(7)]
public float DiabetesPedigreeFunction { get; set; }
[LoadColumn(8)]
public float Age { get; set; }
[LoadColumn(9)]
public float Output { get; set; }
}
}
Krok 5. Přidejte DiabetesMLPrediction třída, která dědí z Patient a zahrnuje další vlastnosti. To se použije po sestavení modelu strojového učení k zobrazení předpokládaných dat:
using Microsoft.ML.Data;
namespace DiabetesPrediction.Models
{
public class DiabetesMLPrediction : Patient
{
[ColumnName("PredictedLabel")]
public float Prediction { get; set; }
public float Probability { get; set; }
public float[] Score { get; set; }
}
}
Krok 6. V Program.cs soubor:
A. Přidejte tyto jmenné prostory:
using System;
using System.IO;
using System.Linq;
using System.Data.SqlClient;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.Extensions.Configuration;
using DiabetesPrediction.Models;
b. Do třídy přidejte GetDbConnection metoda, která extrahuje připojovací řetězec z appsettings.json soubor:
private static string GetDbConnection()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
return builder.Build().GetConnectionString("DbConnection");
}
C. V hlavní metodě:
- Vytvořte instanci MLContext
- Vytvořte instanci DatabaseLoader na základě třídy Patient
- Zavolejte metodu GetDbConnection
- Připravte příkaz SQL, který načte všechna data (a převede id na skutečné pole)
- Připravte instanci DatabaseSource, která používá připojovací řetězec a příkaz.
var context = new MLContext();
var loader = context.Data.CreateDatabaseLoader<Patient>();
var connectionString = GetDbConnection();
var sqlCommand = "Select CAST(Id as REAL) as Id, Pregnancies, Glucose, BloodPressure, SkinThickness, Insulin, BMI, DiabetesPedigreeFunction, Age, CAST(Output as REAL) as Output From Patient";
var dbSource = new DatabaseSource(SqlClientFactory.Instance, connectionString, sqlCommand);
- Načtěte data z tabulky do objektu IDataView a rozdělte je na dva další IDataView, jeden pro trénování a druhý pro vyhodnocení:
Console.WriteLine("Loading data from database...");
var data = loader.Load(dbSource);
var set = context.Data.TrainTestSplit(data, testFraction: 0.2);
var trainingData = set.TrainSet;
var testData = set.TestSet;
- Vytvořte ITransformer přípravou tréninkového kanálu, který vytvoří model strojového učení BinaryClassification. Zadejte sloupec, který bude předpovídán (výstup):
Console.WriteLine("Preparing training operations...");
var pipeline = context.Transforms
.Conversion.MapValueToKey(outputColumnName: "Label", inputColumnName: "Output")
.Append(context.Transforms.Concatenate("Features", "Pregnancies", "Glucose", "BloodPressure", "SkinThickness", "Insulin", "BMI", "DiabetesPedigreeFunction", "Age"))
.Append(context.MulticlassClassification.Trainers.OneVersusAll(context.BinaryClassification.Trainers.AveragedPerceptron("Label", "Features", numberOfIterations: 10))
.Append(context.Transforms.Conversion.MapKeyToValue("PredictedLabel")));
- Nyní rozdělte trénovací datovou sadu na 10 záhybů. Při tréninku se používá 9 záhybů a zbývající záhyb slouží k testování. Tento proces se opakuje 10krát a mění se datové sady vlaku a testu. Tento proces je známý jako 10násobné křížové ověření (samozřejmě můžete změnit číslo). Zobrazí se také metriky:
Console.WriteLine("=============== Starting 10 fold cross validation ===============");
var crossValResults = context.MulticlassClassification.CrossValidate(data: trainingData, estimator: pipeline, numberOfFolds: 10, labelColumnName: "Label");
var metricsInMultipleFolds = crossValResults.Select(r => r.Metrics);
var microAccuracyValues = metricsInMultipleFolds.Select(m => m.MicroAccuracy);
var microAccuracyAverage = microAccuracyValues.Average();
var macroAccuracyValues = metricsInMultipleFolds.Select(m => m.MacroAccuracy);
var macroAccuracyAverage = macroAccuracyValues.Average();
var logLossValues = metricsInMultipleFolds.Select(m => m.LogLoss);
var logLossAverage = logLossValues.Average();
var logLossReductionValues = metricsInMultipleFolds.Select(m => m.LogLossReduction);
var logLossReductionAverage = logLossReductionValues.Average(); Console.WriteLine($"*************************************************************************************************************");
Console.WriteLine($"* Metrics Multi-class Classification model ");
Console.WriteLine($"*------------------------------------------------------------------------------------------------------------");
Console.WriteLine($"* Average MicroAccuracy: {microAccuracyAverage:0.###} ");
Console.WriteLine($"* Average MacroAccuracy: {macroAccuracyAverage:0.###} ");
Console.WriteLine($"* Average LogLoss: {logLossAverage:#.###} ");
Console.WriteLine($"* Average LogLossReduction: {logLossReductionAverage:#.###} ");
Console.WriteLine($"*************************************************************************************************************");
- Dále můžete model trénovat voláním metody Fit:
Console.WriteLine($"Training process is starting. {DateTime.Now.ToLongTimeString()}");
var model = pipeline.Fit(trainingData);
Console.WriteLine($"Training process has finished. {DateTime.Now.ToLongTimeString()}");
Tento proces nějakou dobu trvá.
- Po vytvoření modelu můžete začít vytvářet předpovědi vytvořením PredictionEngine a předáním objektu Patient metodě Predict:
var predictionEngine = context.Model.CreatePredictionEngine<Patient, DiabetesMLPrediction>(model);
var patient = new Patient()
{
Age = 42,
BloodPressure = 81,
BMI = 30.1f,
DiabetesPedigreeFunction = 0.987f,
Glucose = 120,
Insulin = 100,
Pregnancies = 1,
SkinThickness = 26,
Id = 0,
Output = 0
};
var prediction = predictionEngine.Predict(patient);
Console.WriteLine($"Diabetes? {prediction.Output} | Prediction: {(Convert.ToBoolean(prediction.Prediction) ? "Yes" : "No")} | Probability: {prediction.Probability} ");
- Nakonec můžete model uložit a použít jej v jiných projektech (Web Api, Azure Functions atd.)
Console.WriteLine("Saving the model");
context.Model.Save(model, trainingData.Schema, "MLModel.zip");
Krok 7. Spusťte program, získáte výsledky a model ML připravený pro některé předpovědi:
Kód je dostupný na GitHubu.
Doufám, že tento blogový příspěvek byl pro vás zajímavý a užitečný. Zvu vás k návštěvě mého blogu, kde najdete další technické příspěvky o Xamarin, Azure a ekosystému .NET . Píšu ve španělštině =)
Děkujeme za váš čas a užijte si zbytek publikací adventního kalendáře C#!
Uvidíme se příště,
Luis