sql >> Database teknologi >  >> RDS >> Sqlserver

Opbygning af en maskinlæringsmodel med SQL Server, ML.NET og C#

Denne artikel er en del af The Fourth Annual C# Advent Calendar-initiativ af Matthew D. Groves. Du finder andre nyttige artikler og selvstudier, der udgives dagligt af fællesskabsmedlemmer og eksperter der, så sørg for at tjekke det ud hver dag.

ML.NET er en gratis open source-ramme for maskinlæring på tværs af platforme designet til .NET-udviklere. ML.NET lader dig genbruge al den viden, færdigheder, kode og biblioteker, du allerede har som .NET-udvikler, så du nemt kan integrere maskinlæring i dine web-, mobil-, desktop-, spil- og IoT-apps.

Du kan anvende det til klassificering, regression, tidsserier og endda computersyn (deep learning, billedklassificering) scenarier med mere end 40 trænere (opgavebaserede ML-algoritmer) til din rådighed.

Fra version 1.4-preview og fremefter understøttes DatabaseLoader-klassen, hvilket betyder, at vi nu kan træne og bygge modeller direkte mod relationelle databaser, herunder SQL Server, Oracle, PostgreSQL, SQLite og andre.

Til dette eksempel vil jeg bygge en model, der hjælper med at identificere, om en kvinde kan udvikle diabetes baseret på historiske data fra andre patienter. Jeg bruger et Kaggle-datasæt, som du kan downloade herfra.

Derefter skal du oprette en patient tabel for at gemme oplysningerne. Det eneste krav er at bruge en rigtig datatype for numeriske felter, da ML.NET kun vil forstå denne type. En anden mulighed er at udføre en CAST-operation, når du henter dataene og konverterer felterne til rigtige on the fly .

OPRET TABEL Patient( Id int identitet(1,1) primærnøgle, Graviditeter reelt ikke null, Glucose reelt ikke null, Blodtryk reelt ikke null, SkinThickness real ikke null, Insulin reelt ikke null, BMI reelt ikke null , DiabetesPedigreeFunction real not null, Alder real not null, Output varchar(1) not null) 

Og selvfølgelig skal du indsætte alle data fra csv-filen i tabellen .

Lad os nu skrive noget kode!

Trin 1. Opret et nyt C# Console-applikationsprojekt:

Trin 2. Tilføj følgende Nuget-pakker til dit projekt:

  • Microsoft.ML
  • System.Data.SqlClient
  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Json
  • Microsoft.Extensions.Configuration.FileExtensions

Trin 3. Tilføj en appindstillingsfil til dit projekt.

Tilføj en ConnectionStrings i denne fil samling med en DbConnection element. Værdien er selvfølgelig forbindelsesstrengen til databasen, hvor dine data ligger.

For eksempel vil jeg oprette forbindelse til en Azure SQL-database :

{ "Logging":{ "LogLevel":{ "Default":"Warning" } }, "ConnectionStrings":{ "DbConnection":"Server=tcp:myserver.database.windows.net,1433;Initial Catalog=mindatabase;Persist Security Info=False;Bruger ID=myadmin;Password=MYadm1n;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Forbindelsestimeout=30;" }} 

BEMÆRK:Indstil Kopiér til output-mappen egenskab for denne fil, ellers vil den ikke blive læst af programmet senere.

Trin 4. Tilføj en Modeller mappe til dit projekt. Indeni skal du oprette en ny klasse med navnet Patient , som omfatter flere egenskaber, der matcher tabelstrukturen. Desuden er hver ejendom dekoreret med LoadColumnAttribute med et nul-baseret indeks, der repræsenterer den kolonne, der vil blive kortlagt fra databasetabellen.

brug af Microsoft.ML.Data;namespace DiabetesPrediction.Models{ public class Patient { [LoadColumn(0)] public float Id { get; sæt; } [LoadColumn(1)] public float Pregnancies { get; sæt; } [LoadColumn(2)] public float Glucose { get; sæt; } [LoadColumn(3)] public float BloodPressure { get; sæt; } [LoadColumn(4)] public float SkinThickness { get; sæt; } [LoadColumn(5)] public float Insulin { get; sæt; } [LoadColumn(6)] public float BMI { get; sæt; } [LoadColumn(7)] public float DiabetesPedigreeFunction { get; sæt; } [LoadColumn(8)] public float Alder { get; sæt; } [LoadColumn(9)] public float Output { get; sæt; } }} 

Trin 5. Tilføj en DiabetesMLPrediction klasse, der arver fra Patient og inkluderer yderligere egenskaber. Dette vil blive brugt, efter at maskinlæringsmodellen er bygget, til at vise forudsagte data:

brug af Microsoft.ML.Data;namespace DiabetesPrediction.Models{ public class DiabetesMLPrediction :Patient { [ColumnName("PredictedLabel")] public float Prediction { get; sæt; } public float Sandsynlighed { få; sæt; } public float[] Score { get; sæt; } }} 

Trin 6. I Program.cs fil:

en. Tilføj disse navnerum:

bruger System;bruger System.IO;bruger System.Linq;bruger System.Data.SqlClient;bruger Microsoft.ML;bruger Microsoft.ML.Data;bruger Microsoft.Extensions.Configuration;bruger DiabetesPrediction.Models;  

b. Tilføj en GetDbConnection inde i klassen metode, der udtrækker forbindelsesstrengen fra appsettings.json fil:

privat statisk streng GetDbConnection(){ var builder =new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", valgfrit:true, reloadOnChange:true); returner builder.Build().GetConnectionString("DbConnection");} 

c. I hovedmetoden:

  • Opret en MLContext-instans
  • Opret en DatabaseLoader-instans baseret på patientklassen
  • Kald GetDbConnection-metoden
  • Forbered en SQL-sætning, der læser alle data (og konverterer id'et til et rigtigt felt)
  • Forbered en DatabaseSource-instans, der bruger forbindelsesstrengen og sætningen.
var context =new MLContext();var loader =context.Data.CreateDatabaseLoader();var connectionString =GetDbConnection();var sqlCommand ="Vælg CAST(Id som REAL) som Id, Graviditeter , Glucose, Blodtryk, Hudtykkelse, Insulin, BMI, DiabetesPedigreeFunction, Alder, CAST(Output som REAL) som output fra patient";var dbSource =new DatabaseSource(SqlClientFactory.Instance, connectionString, sqlCommand); 
  • Indlæs dataene fra tabellen i et IDataView-objekt, og opdel dem i to andre IDataViews, en til træning og en anden til evaluering:
Console.WriteLine("Indlæser data fra database...");var data =loader.Load(dbSource);var set =context.Data.TrainTestSplit(data, testFraction:0.2);var trainingData =set.TrainSet;var testData =set.TestSet; 
  • Opret en ITransformer ved at forberede en træningspipeline, der vil bygge en BinaryClassification-maskineindlæringsmodel. Angiv den kolonne, der vil blive forudsagt (Output):
Console.WriteLine("Forbereder træningsoperationer...");var pipeline =context.Transforms .Conversion.MapValueToKey(outputColumnName:"Label", inputColumnName:"Output") .Append(context.Transforms. Concatenate("Funktioner", "Graviditeter", "Glucose", "Blodtryk", "Hudtykkelse", "Insulin", "BMI", "DiabetesPedigreeFunction", "Alder")) .Append(context.MulticlassClassification.Trainers.OneVersusAll( context.BinaryClassification.Trainers.AveragedPerceptron("Label", "Features", numberOfIterations:10)) .Append(context.Transforms.Conversion.MapKeyToValue("PredictedLabel"))); 
  • Opdel nu træningsdatasættet i 10 gange. 9 fold bruges til træning og den resterende fold bruges til test. Denne proces gentages 10 gange ved at ændre tog- og testdatasættene. Denne proces er kendt som 10-fold krydsvalidering (du kan selvfølgelig ændre tallet). Metrics vises også:
Console.WriteLine("================Starter 10 gange krydsvalidering ================");var crossValResults =context.MulticlassClassification.CrossValidate(data:trainingData, estimator:pipeline, numberOfFolds:10, labelColumnName:"Etiket");var metricsInMultipleFolds =crossValResults.Select(r => r.Metrics);Invar microAccuracyFaluesmetricFalues ​​metricFoldsMolds => m.MicroAccuracy);var microAccuracyAverage =microAccuracyValues.Average();var macroAccuracyValues ​​=metricsInMultipleFolds.Select(m => m.MacroAccuracy);var macroAccuracyAverage =macroAccuracyValues.Average(); 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($"**** ************************************************** ************************************************** *****"); 
  • Dernæst kan du træne modellen ved at kalde Tilpasningsmetoden:
Console.WriteLine($"Uddannelsesprocessen starter. {DateTime.Now.ToLongTimeString()}");var model =pipeline.Fit(trainingData);Console.WriteLine($"Uddannelsesprocessen er afsluttet. {DateTime.Now.ToLongTimeString()}"); 

Denne proces tager noget tid.

  • Når modellen er oprettet, kan du begynde at lave forudsigelser ved at bygge en PredictionEngine og videregive et patientobjekt til Predict-metoden:
(model);var patient =new Patient(){ Alder =42, Blodtryk =81, BMI =30,1f, DiabetesPedigreeFunction =0,987f, GlucoseFunction =0,987f =120, Insulin =100, Graviditeter =1, Hudtykkelse =26, Id =0, Output =0};var prediction =predictionEngine.Predict(patient);Console.WriteLine($"Diabetes? {prediction.Output} | Forudsigelse:{(Convert.ToBoolean(prediction.Prediction) ? "Yes" :"No")} | Sandsynlighed:{prediction.Probability} ");
  • Til sidst kan du gemme modellen for at bruge den i andre projekter (Web Api, Azure-funktioner osv.)
Console.WriteLine("Gemmer modellen");context.Model.Save(model, trainingData.Schema, "MLModel.zip"); 

Trin 7. Kør programmet, du får resultaterne og en ML-model klar til nogle forudsigelser:

Koden er tilgængelig på GitHub.

Jeg håber, at dette blogindlæg var interessant og nyttigt for dig. Jeg inviterer dig til at besøge min blog for flere tekniske indlæg om Xamarin, Azure og .NET-økosystemet . Jeg skriver på spansk =)

Tak for din tid, og nyd resten af ​​C# Advent Calendar-publikationerne!

Vi ses næste gang,
Luis


  1. Hvad er brugen af ​​SQL GROUP BY-erklæring?

  2. MySQL:ALTER IGNORE TABLE giver en overtrædelse af integritetsbegrænsningen

  3. Er der ANY_VALUE-kapacitet til mysql 5.6?

  4. Den glemte opgaveoperatør =og det almindelige :=