Bài viết này là một phần của sáng kiến Lịch mùa vọng C # Thường niên lần thứ tư của Matthew D. Groves. Bạn sẽ tìm thấy các bài báo và hướng dẫn hữu ích khác được các thành viên cộng đồng và các chuyên gia ở đó xuất bản hàng ngày, vì vậy hãy nhớ xem nó hàng ngày.
ML.NET là một khung học máy miễn phí, mã nguồn mở và đa nền tảng được thiết kế cho các nhà phát triển .NET. ML.NET cho phép bạn sử dụng lại tất cả kiến thức, kỹ năng, mã và thư viện mà bạn đã có với tư cách là nhà phát triển .NET để bạn có thể dễ dàng tích hợp học máy vào web, thiết bị di động, máy tính để bàn, trò chơi và ứng dụng IoT của mình.
Bạn có thể áp dụng nó cho các tình huống phân loại, hồi quy, chuỗi thời gian và thậm chí cả thị giác máy tính (học sâu, phân loại hình ảnh) với hơn 40 giảng viên (thuật toán ML dựa trên nhiệm vụ) theo ý của bạn.
Từ phiên bản 1.4-preview trở đi, lớp DatabaseLoader được hỗ trợ, có nghĩa là bây giờ chúng ta có thể đào tạo và xây dựng các mô hình trực tiếp dựa trên cơ sở dữ liệu quan hệ, bao gồm SQL Server, Oracle, PostgreSQL, SQLite và các loại khác.
Đối với ví dụ này, tôi sẽ xây dựng một mô hình giúp xác định xem một phụ nữ có thể phát triển bệnh tiểu đường hay không dựa trên dữ liệu lịch sử từ những bệnh nhân khác. Tôi đang sử dụng tập dữ liệu Kaggle mà bạn có thể tải xuống từ đây.
Sau đó, tạo Bệnh nhân bảng để lưu trữ thông tin. Yêu cầu duy nhất là sử dụng thực kiểu dữ liệu cho các trường số, vì ML.NET sẽ chỉ hiểu kiểu này. Một tùy chọn khác là thực hiện thao tác CAST khi bạn truy xuất dữ liệu và chuyển đổi các trường thành thực nhanh chóng .
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
)
Và tất nhiên, bạn cần chèn tất cả dữ liệu từ tệp csv vào bảng .
Bây giờ, hãy viết một số mã!
Bước 1. Tạo một dự án ứng dụng C # Console mới:
Bước 2. Thêm các gói Nuget sau vào dự án của bạn:
- Microsoft.ML
- System.Data.SqlClient
- Microsoft.Extensions.Configuration
- Microsoft.Extensions.Configuration.Json
- Microsoft.Extensions.Configuration.FileExtensions
Bước 3. Thêm tệp cài đặt ứng dụng vào dự án của bạn.
Trong tệp này, thêm một Chuỗi kết nối bộ sưu tập với DbConnection thành phần. Tất nhiên, giá trị là chuỗi kết nối với cơ sở dữ liệu nơi chứa dữ liệu của bạn.
Ví dụ:tôi sẽ kết nối với cơ sở dữ liệu 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;"
}
}
LƯU Ý:Đặt Thư mục Sao chép vào Đầu ra thuộc tính cho tệp này, nếu không, nó sẽ không được chương trình đọc sau này.
Bước 4. Thêm Mô hình thư mục cho dự án của bạn. Bên trong, tạo một lớp mới có tên Bệnh nhân , bao gồm một số thuộc tính phù hợp với cấu trúc Bảng. Ngoài ra, mỗi thuộc tính được trang trí bằng LoadColumnAttribute với chỉ mục dựa trên 0 đại diện cho cột sẽ được ánh xạ từ bảng cơ sở dữ liệu.
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; }
}
}
Bước 5. Thêm DiabetesMLPrediction lớp kế thừa từ Bệnh nhân và bao gồm các thuộc tính bổ sung. Điều này sẽ được sử dụng sau khi mô hình học máy được xây dựng, để hiển thị dữ liệu dự đoán:
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; }
}
}
Bước 6. Trong Program.cs tệp:
một. Thêm các không gian tên này:
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. Bên trong lớp, thêm GetDbConnection phương thức trích xuất chuỗi kết nối từ appsettings.json tập tin:
private static string GetDbConnection()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
return builder.Build().GetConnectionString("DbConnection");
}
c. Trong phương pháp Chính:
- Tạo một phiên bản MLContext
- Tạo một phiên bản DatabaseLoader dựa trên lớp Bệnh nhân
- Gọi phương thức GetDbConnection
- Chuẩn bị một câu lệnh SQL đọc tất cả dữ liệu (và chuyển đổi id thành một trường thực)
- Chuẩn bị một phiên bản DatabaseSource sử dụng chuỗi kết nối và câu lệnh.
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);
- Tải dữ liệu từ bảng vào một đối tượng IDataView và chia nó thành hai IDataView khác, một để đào tạo và một để đánh giá:
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;
- Tạo một ITransformer bằng cách chuẩn bị một đường dẫn đào tạo sẽ xây dựng một mô hình học máy Phân loại nhị phân. Chỉ định cột sẽ được dự đoán (Đầu ra):
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")));
- Bây giờ, hãy chia tập dữ liệu đào tạo thành 10 lần. 9 nếp gấp được sử dụng trong đào tạo và nếp gấp còn lại được sử dụng để thử nghiệm. Quá trình này được lặp lại 10 lần để thay đổi tập dữ liệu huấn luyện và thử nghiệm. Quá trình này được gọi là xác thực chéo 10 lần (tất nhiên, bạn có thể thay đổi số). Các chỉ số cũng được hiển thị:
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($"*************************************************************************************************************");
- Tiếp theo, bạn có thể đào tạo mô hình bằng cách gọi phương thức Fit:
Console.WriteLine($"Training process is starting. {DateTime.Now.ToLongTimeString()}");
var model = pipeline.Fit(trainingData);
Console.WriteLine($"Training process has finished. {DateTime.Now.ToLongTimeString()}");
Quá trình này mất một khoảng thời gian.
- Sau khi mô hình được tạo, bạn có thể bắt đầu đưa ra dự đoán bằng cách xây dựng PredictionEngine và chuyển đối tượng Bệnh nhân vào phương pháp Dự đoán:
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} ");
- Cuối cùng, bạn có thể lưu mô hình để sử dụng trong các dự án khác (Web Api, Azure Functions, v.v.)
Console.WriteLine("Saving the model");
context.Model.Save(model, trainingData.Schema, "MLModel.zip");
Bước 7. Chạy chương trình, bạn sẽ nhận được kết quả và Mô hình ML sẵn sàng cho một số dự đoán:
Mã có sẵn trên GitHub.
Tôi hy vọng rằng bài đăng trên blog này thú vị và hữu ích cho bạn. Tôi mời bạn truy cập blog của tôi để biết thêm các bài đăng kỹ thuật về Xamarin, Azure và hệ sinh thái .NET . Tôi viết bằng tiếng Tây Ban Nha =)
Cảm ơn bạn đã dành thời gian và thưởng thức phần còn lại của các ấn phẩm Lịch Advent C #!
Hẹn gặp lại các bạn lần sau,
Luis