سناریوی طبقه بندی چند کلاسه برای دسته بندی کردن GitHub issues ها(قسمت سوم سری ml.net)

این آموزش نمونه ای از استفاده ML.NET برای ایجاد یک طبقه بندی GitHub issue (موضوعی GitHub) برای آموزش یک مدل است که دسته بندی و پیش بینی برچسب منطقه (Area label) برای یکGitHub issue از طریق یک برنامه .NET Core console application با استفاده از C# در ویژوال استودیو را نشان می دهد.

در این آموزش، شما یاد می گیرید که چگونه:

  • داده های خود را آماده کنید
  • داده ها را تبدیل کنید
  • مدل را آموزش دهید
  • مدل را ارزیابی دهید
  • پیش بینی با مدل آموزش دیده
  • استقرار و پیش بینی با یک مدل لود شده(بارگذاری شده)


شما می توانید کد منبع این آموزش را در مخزن dotnet/samples پیدا کنید.

پیش نیازها

ویژوال استودیو 2017 15.6 و یا بعد از آن با ".NET Core cross platform development" نصب شده .

دانلود فایل Github issues tab separated file (issues_train.tsv).

دانلود فایل Github issues test tab separated file (issues_test.tsv).

یک برنامه کنسول از نوع .NET Core ایجاد کنید و نام آن را GitHubIssueClassification قرار دهید. روی Solution Explorer کلیک راست کنید و دو پوشه با نام های Data و Models ایجاد کنید. پکیج Microsoft.ML NuGet Package را نصب کنید.

داده های خود را آماده کنید

1- پس از دانلود (data sets) مجموعه داده های issues_train.tsv و issues_test.tsv (که در پیش نیاز آمده است) آنها را پوشه Data که قبل تر ایجاد کرده ایم ذخیره کنید. اولین مجموعه داده، مدل یادگیری ماشین را آموزش می دهد و دوم می تواند برای ارزیابی دقت مدل شما استفاده شود.

2- در Solution Explorer روی فایلها با پسوند *.tsv کلیک راست کرده و Properties را انتخاب کنید. در زیر Advanced مقدار Copy to Output Directory به Copy if newer تغییر دهید.

ایجاد کلاس ها و تعریف مسیرها

در بالای فایل Program.cs کد using های زیر را اضافه کنید:

using System;
using System.IO;
using System.Linq;
using Microsoft.ML;

ایجاد سه global fields برای نگه داشتن مسیرها به فایل های اخیرا دانلود شده و global variables برای MLContext، DataView و PredictionEngine:

  • (مسیر داده آموزشی)_trainDataPath مسیر به مجموعه داده مورد استفاده برای آموزش مدل است.
  • (مسیر داده آزمایشی)_testDataPath مسیری را به مجموعه داده مورد استفاده برای ارزیابی مدل دارد.
  • (مسیر مدل)_modelPath دارای مسیری است که مدل آموزش یافته ذخیره شده است.
  • (زمینهmlر) _mlContext یک MLContext که زمینه پردازش را فراهم می کند.
  • (نمای داده آموزشی)_trainingDataView یک IDataView مورد استفاده برای پردازش مجموعه داده آموزشی است.
  • (موتور پیشبینی) _predEngine یک PredictionEngine<TSrc,TDst> برای پیش بینی های تکی استفاده می شود.

کد های زیر را در بالای متد Main برای مشخص کردن مسیرها و سایر متغیرها بنویسید:

private static string _appPath => Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
private static string _trainDataPath => Path.Combine(_appPath, "..", "..", "..", "Data", "issues_train.tsv");
private static string _testDataPath => Path.Combine(_appPath, "..", "..", "..", "Data", "issues_test.tsv");
private static string _modelPath => Path.Combine(_appPath, "..", "..", "..", "Models", "model.zip");

private static MLContext _mlContext;
private static PredictionEngine<GitHubIssue, IssuePrediction> _predEngine;
private static ITransformer _trainedModel;
static IDataView _trainingDataView;

تعدادی کلاس برای داده های ورودی و پیش بینی های خود ایجاد کنید.

1- یک کلاس با نام GitHubIssueData.cs ایجاد و using زیر را به آن اضافه کنید:

using Microsoft.ML.Data;

2- محتویات کلاس را پاک کنید و کد زیر را که حاوی دو کلاس GitHubIssue و IssuePrediction است را به آن اضافه کنید:

public class GitHubIssue
{
    [LoadColumn(0)]
    public string ID { get; set; }
    [LoadColumn(1)]
    public string Area { get; set; }
    [LoadColumn(2)]
    public string Title { get; set; }
    [LoadColumn(3)]
    public string Description { get; set; }
  }
  
 public class IssuePrediction
 {
     [ColumnName("PredictedLabel")]
     public string Area;
 }

(برچسب) label ستونی است که میخواهید پیشبینی کنید. (ویژگی ها) Features شناخته شده ورودی هایی هستند که شما برای مدل پیش بینی برچسب را ارائه می دهید.

از LoadColumnAttribute برای مشخص نمودن فهرست های ستون های منبع در مجموعه داده استفاده کنید.

کلاس GitHubIssue کلاس مجموعه داده ورودی است (input dataset class) و دارای فیلدهای رشته (String fields) زیر است:

  • اولین ستون ID (درواقع GitHub Issue ID میباشد)
  • ستون دوم Area (پیش بینی برای آموزش)
  • ستون سوم Title (درواقع GitHub issue title ) اولین feature مورد استفاده برای پیش بینی Area است
  • ستون چهارم Description دومین feature مورد استفاده برای پیش بینی Area است

کلاس IssuePrediction کلاس مورد استفاده برای پیش بینی پس از مدل آموزش دیده است.که دارای یک رشته (Area) و صفت ColumnName با مقدار PredictedLabel است. PredictedLabel در پیش بینی و ارزیابی استفاده می شود. برای ارزیابی، یک ورودی با داده آموزشی، مقادیر پیش بینی شده و مدل مورد استفاده قرار می گیرد.

تمام عملیات ML.NET از کلاس MLContext شروع می شود. ابتدا mlContext یک محیط جدید ML.NET ایجاد می کند که می تواند در سراسر اشیاء گردش کار ایجاد مدل ایجاد شود. این، مفهومی، به DBContext در Entity Framework است.


مقداردهی اولیه متغییر ها در Main متد Initialize variables in Main

ابتدا متغیر _mlContext را با یک نمونه جدید از MLContext با یک seed تصادفی (seed: 0) برای نتایج تکرارپذیر/قطعی (repeatable/deterministic) در آموزش های چندگانه آغاز کنید. خط Console.WriteLine ("Hello World!") را با کد زیر در متد Main جایگزین کنید:

_mlContext = new MLContext(seed: 0);


بارگیری داده Load the data

اینML.NET از کلاس IDataView به عنوان یک روش انعطاف پذیر و کارآمد برای توصیف داده های جدولی یا متن استفاده می کند. IDataView می تواند هر فایل متنی و یا در زمان واقعی (به عنوان مثال، پایگاه داده SQL و یا فایل های log) بارگیری کند.


برای مقداردهی اولیه و بارگذاری (global variable) متغیرجهانی _trainingDataView ،به منظور استفاده از آن برای خط لوله، پس از مقدار دهی اولیه mlContext، کد زیر را اضافه کنید:

_trainingDataView = _mlContext.Data.LoadFromTextFile<GitHubIssue>(_trainDataPath,hasHeader: true);

لود کردن از فایل متنی LoadFromTextFile() شکل داده را تعریف می کند و در فایل می خواند. متغیر مسیر داده میگیرد و یک IDataView را برمی گرداند.

در خط بعتی متد Main کد زیر را قرار دهید:

var pipeline = ProcessData();

متد ProcessData() وظایف زیر را اجرا میکند:

  • استخراج و تغییر شکل(تبدیل) داده
  • خط لوله پردازش را بازمی گرداند

متد ProcessData بعد از متد Main بنویسید

public static IEstimator<ITransformer> ProcessData()
{

}


استخراج Features (ویژگی ها) و تبدیل داده

همانطور که پیشبینی برچسب Area GitHub برای یک GitHubIssue می خواهید، از متد MapValueToKey() برای تبدیل ستون Area به یک ستون عددی Key Type Label (یک فرمت پذیرفته شده توسط الگوریتم های طبقه بندی-classification) استفاده کنید و آن را به عنوان یک ستون مجموعه داده(dataset) جدید اضافه کنید:

var pipeline = _mlContext.Transforms.Conversion.MapValueToKey(inputColumnName: "Area", outputColumnName: "Label")

بعد، فراخوانی mlContext.Transforms.Text.FeaturizeText که تبدیل متن ( Title و Description) ستون ها به یک بردار عددی برای هر کدام نام TitleFeaturized و DescriptionFeaturized قرار دهید. آماده سازی ویژگی های(featurization) مربوط به هر دو ستون را به خط لوله اضافه کنید:

.Append(_mlContext.Transforms.Text.FeaturizeText(inputColumnName: "Title", outputColumnName: "TitleFeaturized"))
.Append(_mlContext.Transforms.Text.FeaturizeText(inputColumnName: "Description", outputColumnName: "DescriptionFeaturized"))

آخرین مرحله در آماده سازی داده ها، تمام ستون های feature را به ستون Features با استفاده از متد Concatenate() متصل کنید. به طور پیشفرض یک الگوریتم یادگیری فقط ویژگی های ستون Features را پردازش می کند. این تغییر را به خط لوله اضافه کنید:

.Append(_mlContext.Transforms.Concatenate("Features", "TitleFeaturized", "DescriptionFeaturized"))

سپس، AppendCacheCheckpoint را اضافه کنید تا DataView را cache کنید، بنابراین وقتی چندین مرتبه بر روی داده ها تکرار می شوید، با استفاده از حافظه پنهان(cache)، عملکرد بهتری خواهیم داشت، مانند کد زیر:

.AppendCacheCheckpoint(_mlContext);

اخطار

استفاده از AppendCacheCheckpoint برای مجموعه داده های کوچک / متوسط برای کاهش زمان آموزش است. هنگام استفاده از مجموعه داده های بسیار بزرگ، از آن استفاده نکنید ( .AppendCacheCheckpoint () حذف کنید).

خط لوله را در انتهای متد ProcessData بازگردانید.

return pipeline;

این مرحله پیش پردازش / آماده سازی ویژگی (preprocessing/featurization) را مدیریت می کند. با استفاده از component های اضافی موجود در ML.NET می توانید نتایج بهتر را با مدل خود داشته باشید.

ساخت و آموزش مدل

فراخوانی (صدا زدن) متد BuildAndTrainModel در خط بعدی متد Main

var trainingPipeline = BuildAndTrainModel(_trainingDataView, pipeline);

متد BuildAndTrainModel وظایف زیر را اجرا میکند:

  • کلاس الگوریتم آموزش را ایجاد می کند.
  • مدل را آموزش میدهد.
  • پیش بینی منطقه (Predicts area) بر اساس داده های آموزشی.
  • مدل را برمی گرداند.


متد BuildAndTrainModel بعد از متد Main ایجاد کنید:

public static IEstimator<ITransformer> BuildAndTrainModel(IDataView trainingDataView, IEstimator<ITransformer> pipeline)
{

}

درباره وظیفه طبقه بندی(classification)

طبقه بندی (Classification) وظیفه یادگیری ماشین است که از داده ها برای مشخص کردن طبقه بندی (category)، نوع (type) یا کلاس (class) یک آیتم یا ردیف داده (row of data) استفاده می کند و اغلب یکی از انواع زیر است:

  • دودویی (Binary): یا A یا B
  • چندکلاسه(Multiclass): طبقه بندی چندگانه (multiple categories) که می توانند با استفاده از یک مدل واحد پیش بینی شوند.

برای این نوع مشکل، از یک الگوریتم یادگیری طبقه بندی چند کلاسه (Multiclass classification) استفاده کنید، زیرا پیش بینی گروه طبقه موضوع (issue category prediction) شما می تواند یکی از چندین طبقه باشد (چند طبقه) و نه فقط دو طبقه (باینری).

الگوریتم یادگیری ماشین را به تعریف های تبدیل داده (data transformation definitions) اضافه کنید با اضافه کردن زیر به عنوان خط اول کد در BuildAndTrainModel ():

var trainingPipeline = pipeline.Append(_mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy("Label", "Features"))                
               .Append(_mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"));

الگوریتم SdcaMaximumEntropy الگوریتم آموزش طبقه بندی چند کلاسه است(multiclass classification training).این به pipeline الحاق شده و Title و Description (ویژگی ها-Features) و پارامترهای ورودی Label را برای یادگیری از داده های مبتنی بر تاریخی (historic data) پذیرش می کند.


آموزش مدل

مدل را به داده های splitTrainSet بخورانید (fit کنید) و مدل آموزش دیده را برگردانید با اضافه کردن موارد زیر به عنوان خط بعدی کد در متد BuildAndTrainModel () :

_trainedModel = trainingPipeline.Fit(trainingDataView);

متد Fit() مدل شما را با تبدیل مجموعه داده ها و استفاده از آموزش، آموزش می دهد.

موتور پیشبینی PredictionEngine یک API راحتی است که به شما اجازه می دهد یک نمونه از داده ها را وارد کنید و سپس پیش بینی کنید.(allows you to pass in and then perform a prediction on a single instance of data.) کد زیر را در خط بعدی BuildAndTrainModel() اضافه کنید.

_predEngine = _mlContext.Model.CreatePredictionEngine<GitHubIssue, IssuePrediction>(_trainedModel);

پیش بینی با مدل آموزش دیده

یک GitHub issue را برای تست پیش بینی مدل آموزش یافته در متد Predict با ایجاد یک نمونه از GitHubIssue اضافه کنید:

GitHubIssue issue = new GitHubIssue() {
    Title = "WebSockets communication is slow in my machine",
    Description = "The WebSockets communication used under the covers by SignalR looks like is going slow in my development machine.."
    };

استفاده از تابع Predict() پیش بینی یک ردیف داده را پیش بینی می کند(prediction on a single row of data):

var prediction = _predEngine.Predict(issue);

با استفاده از مدل: نتایج پیش بینی Using the model: prediction results

نمایش GitHubIssue و پیش بینی برچسب متناظر مربوط به Area به منظور به اشتراک گذاشتن نتایج و عمل بر روی آنها به ترتیب. یک نمایش برای نتایج با استفاده از Console.WriteLine() ایجاد کنید:

Console.WriteLine($"=============== Single Prediction just-trained-model - Result: {prediction.Area} ===============");

برگرداندن مدل آموزش دیده برای استفاده ارزیابی

مدل را در آخر متد BuildAndTrainModel برگردانید.

return trainingPipeline;

ارزیابی مدل Evaluate the model

اکنون که مدل را ایجاد و آموزش داده اید، باید آن را با مجموعه داده های مختلف برای تضمین کیفیت و اعتبار سنجی ارزیابی کنید.در متد Evaluate، مدل ایجاد شده در BuildAndTrainModel منتقل می شود تا ارزیابی شود.متد Evaluate بعد از متد BuildAndTrainModel ایجاد کنید:

public static void Evaluate(DataViewSchema trainingDataViewSchema)
{


}

متد Evaluate وظایف زیر را بر عهده دارد:

  • داده های آزمایشی (تستی) را بارگیری می کند.
  • ارزیابی کننده چندکلاسه را ایجاد می کند.
  • مدل را ارزیابی و معیارها را ایجاد می کند.
  • نمایش معیار ها(metrics).

متد Evaluate را در متد Main و زیر متد BuildAndTrainModel فراخوانی کنید:

Evaluate(_trainingDataView.Schema);

همانطور که قبلا با مجموعه داده های آموزشی تمرین کرده اید، مجموعه داده های آزمون را با اضافه کردن کد زیر به متد Evaluate بارگذاری کنید:

var testMetrics = _mlContext.MulticlassClassification.Evaluate(_trainedModel.Transform(testDataView));

معیارهای زیر برای طبقه بندی چند کلاسه ارزیابی می شوند ( metrics are evaluated for multiclass classification ):

  • دقت میکرو Micro Accuracy - هر جفت نمونه کلاس ( sample-class pair )، به طور مساوی با معیار دقت همخوانی دارد. شما می خواهید دقت میکرو تا حد ممکن نزدیک به 1 باشد.
  • دقت میکرو Micro Accuracy - هر کلاس به طور مساوی با معیار دقت همکاری می کند. کلاس های اقلیت (Minority classes) با توجه به کلاس های بزرگتر وزن برابری دارند. شما می خواهید دقت ماکرو را تا حد ممکن نزدیک به 1 قرار دهید.
  • از دست دادن لاگ (Log-loss) - مشاهده Log Loss. شما می خواهید تا جای ممکن Log-loos به صفر برسد
  • کاهش تز دست دادن لاگ (Log-loss reduction) - محدوده از [-inf, 100] (منفی بینهایت تا 100) ، 100 پیش بینی کامل و 0 پیش بینی میانگین است.شما میخواهید تا جای ممکن Log-loss کاهش پیدا کرده و به صفر نزدیک شود.

نمایش معیارها برای اعتبار سنجی مدل

از کد زیر برای نمایش معیارها استفاده کنید، نتایج را به اشتراک بگذارید و سپس روی آنها عمل کنید:

Console.WriteLine($"*************************************************************************************************************");
Console.WriteLine($"*       Metrics for Multi-class Classification model - Test Data     ");
Console.WriteLine($"*------------------------------------------------------------------------------------------------------------");
Console.WriteLine($"*       MicroAccuracy:    {testMetrics.MicroAccuracy:0.###}");
Console.WriteLine($"*       MacroAccuracy:    {testMetrics.MacroAccuracy:0.###}");
Console.WriteLine($"*       LogLoss:          {testMetrics.LogLoss:#.###}");
Console.WriteLine($"*       LogLossReduction: {testMetrics.LogLossReduction:#.###}");
Console.WriteLine($"*************************************************************************************************************");

استقرار و پیش بینی با یک مدل

متد جدیدی را در متد Main زیر فراخوانی متد Evaluate ،فراخوانی کنید:

PredictIssue();

بعد از متد Evaluate (قبل از متد SaveModelAsFile)متد PredictIssue را ایجاد کنید:

private static void PredictIssue()
{


}

متد PredictIssue وظایف زیر را اجرا میکند:

  • یک issue واحد از داده تست را ایجاد می کند.
  • پیشبینی Area بر اساس داده های آزمایش.
  • داده های آزمایش و پیش بینی هایرا برای گزارش ترکیب می کند.
  • نتایج پیش بینی شده را نمایش می دهد.


یک GitHub issue را برای تست پیش بینی مدل آموزش دیده شده در متد Predict با ایجاد یک نمونه از GitHubIssue اضافه کنید:

GitHubIssue singleIssue = new GitHubIssue() { Title = "Entity Framework crashes", Description = "When connecting to the database, EF is crashing" };

همانطور که قبلا انجام دادید، یک نمونه PredictionEngine با کد زیر ایجاد کنید:

_predEngine = _mlContext.Model.CreatePredictionEngine<GitHubIssue, IssuePrediction>(loadedModel);

استفاده از PredictionEngine برای پیش بینی برچسب Area GitHub با اضافه کردن کد زیر به متد PredictIssue برای پیش بینی:

var prediction = _predEngine.Predict(singleIssue);

استفاده از مدل بارگذاری شده برای پیش بینی (Using the loaded model for prediction)

نمایش Area به منظور طبقه بندی issue و عمل بر روی آن بر این اساس. با استفاده از Console.WriteLine() یک نمایش برای نتایج ایجاد کنید:

Console.WriteLine($"=============== Single Prediction - Result: {prediction.Area} ===============");

نتایج

نتایج شما باید مشابه موارد زیر باشد. همانطور که خط لوله پردازش می شود، پیام ها را نمایش می دهد. ممکن است هشدارها یا پردازش پیام ها را مشاهده کنید. این پیام ها از نتایج زیر برای تمیز بودن حذف شده اند.

=============== Single Prediction just-trained-model - Result: area-System.Net ===============
*************************************************************************************************************
*       Metrics for Multi-class Classification model - Test Data
*------------------------------------------------------------------------------------------------------------
*       MicroAccuracy:    0.738
*       MacroAccuracy:    0.668
*       LogLoss:          .919
*       LogLossReduction: .643
*************************************************************************************************************
=============== Single Prediction - Result: area-System.Data ===============

تبریک می گویم! شما اکنون موفق به ساخت یک مدل یادگیری ماشین برای طبقه بندی و پیش بینی یک برچسب منطقه (Area) برای یک issue (مسئله) GitHub شده اید.شما می توانید کد منبع این آموزش را در مخزن dotnet/samples پیدا کنید.

در این آموزش، شما یاد گرفتید که چگونه:

  • داده های خود را آماده کنید
  • داده ها را تبدیل کنید
  • مدل را آموزش دهید
  • مدل را ارزیابی کنید
  • پیش بینی با مدل آموزش دیده
  • استقرار و پیش بینی با یک مدل لود شده


منبع