Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Membangun model pembelajaran mesin dengan SQL Server, ML.NET dan C#

Artikel ini adalah bagian dari inisiatif The Fourth Annual C# Advent Calendar oleh Matthew D. Groves. Anda akan menemukan artikel dan tutorial bermanfaat lainnya yang diterbitkan setiap hari oleh anggota komunitas dan pakar di sana, jadi pastikan untuk membacanya setiap hari.

ML.NET adalah kerangka kerja pembelajaran mesin gratis, sumber terbuka, dan lintas platform yang dirancang untuk pengembang .NET. ML.NET memungkinkan Anda menggunakan kembali semua pengetahuan, keterampilan, kode, dan pustaka yang sudah Anda miliki sebagai pengembang .NET sehingga Anda dapat dengan mudah mengintegrasikan pembelajaran mesin ke dalam aplikasi web, seluler, desktop, game, dan IoT Anda.

Anda dapat menerapkannya untuk skenario klasifikasi, regresi, deret waktu, dan bahkan visi komputer (pembelajaran mendalam, klasifikasi gambar) dengan lebih dari 40 pelatih (algoritme ML berbasis tugas) yang Anda inginkan.

Dari versi 1.4-preview dan seterusnya, kelas DatabaseLoader didukung, yang berarti bahwa sekarang kita dapat melatih dan membangun model secara langsung terhadap database relasional, termasuk SQL Server, Oracle, PostgreSQL, SQLite, dan lainnya.

Untuk contoh ini, saya akan membuat model yang membantu mengidentifikasi apakah seorang wanita dapat mengembangkan diabetes berdasarkan data historis dari pasien lain. Saya menggunakan kumpulan data Kaggle yang dapat Anda unduh dari sini.

Setelah itu, buat Pasien tabel untuk menyimpan informasi. Satu-satunya persyaratan adalah menggunakan nyata tipe data untuk bidang numerik, karena ML.NET hanya akan memahami tipe ini. Opsi lainnya adalah melakukan operasi CAST saat Anda mengambil data dan mengonversi bidang menjadi nyata dengan cepat .

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
)

Dan tentu saja, Anda perlu menyisipkan semua data dari file csv ke dalam tabel .

Sekarang, mari kita menulis beberapa kode!

Langkah 1. Buat proyek aplikasi Konsol C# baru:

Langkah 2. Tambahkan paket Nuget berikut ke proyek Anda:

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

Langkah 3. Tambahkan File Pengaturan Aplikasi ke proyek Anda.

Dalam file ini, tambahkan ConnectionStrings koleksi dengan DbConnection elemen. Nilainya, tentu saja, adalah string koneksi ke database tempat data Anda berada.

Misalnya, saya akan terhubung ke database 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;"
  }
}

CATATAN:Setel Salin ke direktori Output properti untuk file ini, jika tidak maka tidak akan dibaca oleh program nanti.

Langkah 4. Tambahkan Model folder ke proyek Anda. Di dalam, buat kelas baru bernama Pasien , yang mencakup beberapa properti yang cocok dengan struktur Tabel. Selain itu, setiap properti didekorasi dengan LoadColumnAttribute dengan indeks berbasis nol yang mewakili kolom yang akan dipetakan dari tabel database.

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; }
    }
}

Langkah 5. Tambahkan DiabetesMLPrediction kelas yang mewarisi dari Pasien dan termasuk properti tambahan. Ini akan digunakan setelah model pembelajaran mesin dibuat, untuk menampilkan data yang diprediksi:

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; }
    }
}

Langkah 6. Di Program.cs berkas:

sebuah. Tambahkan ruang nama ini:

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. Di dalam kelas, tambahkan GetDbConnection metode yang mengekstrak string koneksi dari appsettings.json mengajukan:

private static string GetDbConnection()
{
   var builder = new ConfigurationBuilder()
      .SetBasePath(Directory.GetCurrentDirectory())
      .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

   return builder.Build().GetConnectionString("DbConnection");
}

c. Dalam metode Utama:

  • Buat instance MLContext
  • Buat instance DatabaseLoader berdasarkan kelas Pasien
  • Panggil metode GetDbConnection
  • Siapkan pernyataan SQL yang membaca semua data (dan mengubah id menjadi bidang nyata)
  • Siapkan instance DatabaseSource yang menggunakan string koneksi dan pernyataan.
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);
  • Muat data dari tabel ke dalam objek IDataView dan pisahkan menjadi dua IDataViews lainnya, satu untuk pelatihan dan satu lagi untuk evaluasi:
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;
  • Buat ITransformer dengan menyiapkan alur pelatihan yang akan membangun model pembelajaran mesin BinaryClassification. Tentukan kolom yang akan diprediksi (Output):
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")));
  • Sekarang, bagi dataset pelatihan menjadi 10 kali lipat. 9 lipatan digunakan dalam pelatihan dan lipatan yang tersisa digunakan untuk pengujian. Proses ini diulang 10 kali mengubah dataset kereta dan pengujian. Proses ini dikenal sebagai validasi silang 10 kali lipat (tentu saja, Anda dapat mengubah nomornya). Metrik juga ditampilkan:
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($"*************************************************************************************************************");

  • Selanjutnya, Anda dapat melatih model dengan memanggil metode Fit:
Console.WriteLine($"Training process is starting. {DateTime.Now.ToLongTimeString()}");
var model = pipeline.Fit(trainingData);
Console.WriteLine($"Training process has finished. {DateTime.Now.ToLongTimeString()}");

Proses ini membutuhkan waktu.

  • Setelah model dibuat, Anda dapat mulai membuat prediksi dengan membuat PredictionEngine dan meneruskan objek Patient ke metode 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} ");

  • Akhirnya, Anda dapat menyimpan model untuk digunakan di proyek lain (Web Api, Azure Functions, dll.)
Console.WriteLine("Saving the model");
context.Model.Save(model, trainingData.Schema, "MLModel.zip");

Langkah 7. Jalankan program, Anda akan mendapatkan hasil dan Model ML siap untuk beberapa prediksi:

Kode tersedia di GitHub.

Saya harap posting blog ini menarik dan bermanfaat bagi Anda. Saya mengundang Anda untuk mengunjungi blog saya untuk posting teknis lebih lanjut tentang Xamarin, Azure, dan ekosistem .NET . Saya menulis dalam bahasa Spanyol =)

Terima kasih atas waktu Anda, dan nikmati sisa publikasi Kalender Advent C#!

Sampai jumpa lain waktu,
Luis


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana menjalankan Prosedur Tersimpan dari Laravel

  2. penggabungan nvarchar / indeks / nvarchar (maks) perilaku yang tidak dapat dijelaskan

  3. mengonversi stempel waktu Epoch ke server sql (format yang dapat dibaca manusia)

  4. Bagaimana cara memeriksa apakah string adalah pengidentifikasi unik?

  5. Mengapa menggunakan klausa INCLUDE saat membuat indeks?