تجزیه و تحلیل احساس: نشان می دهد که چگونه یک وظیفه دسته بندی باینری با استفاده از ML.NET اعمال کند.
این آموزش به شما نشان می دهد که چگونه یک برنامه کنسول Core .NET ایجاد کنید که احساسات را از نظرات وب سایت دسته بندی کند و اقدام مناسب را انجام دهد. طبقه بندی احساسات باینری از C# در ویژوال استودیو 2017 استفاده می کند.
در این آموزش، شما یاد می گیرید که چگونه:
ویژوال استودیو 2017 15.6 و یا بعد از آن با ".NET Core cross platform development" بارگذاری و نصب شده باشد.
دادها: UCI Sentiment Labeled Sentences dataset (فایلZIP)
1- یک برنامه کنسول .NET Core را به نام "SentimentAnalysis" (تحلیل احساسات) ایجاد کنید.
2- برای ذخیره فایل های داده ای خود، یک پوشه به نام Data را در پروژه خود ایجاد کنید.
3- پکیج Package Microsoft.ML NuGet را نصب کنید:
در Solution Explorer، بر روی پروژه خود راست کلیک کرده و مدیریت NuGet Packages را انتخاب کنید. "nuget.org" را به عنوان منبع بسته انتخاب کنید و سپس برگه Browse را انتخاب کنید. جستجو برای Microsoft.ML، بسته ای را که میخواهید انتخاب کنید، سپس دکمه Install را انتخاب کنید. با نصب با موافقت با شرایط مجوز بسته ای که انتخاب می کنید، نصب را ادامه دهید. برای Packet Microsoft.ML.FastTree NuGet همین کار را انجام دهید.
1- فایل zip که در پیش نیاز معرفی شد را دانلود و فایل yelp_labelled.txt در پوشه Data پروژه کپی کنید.
2- در Solution Explorer، فایل yelp_labeled.txt راست کلیک کرده و Properties را انتخاب کنید. در زیر Advanced ، مقدار Copy to Output Directory را به Copy if newer تغییر دهید.
ایجاد کلاس ها و تعریف مسیرها
1- دستورالعملهای (using) اضافی زیر را به بالای فایل Program.cs اضافه کنید:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.ML; using Microsoft.ML.Data; using static Microsoft.ML.DataOperationsCatalog; using Microsoft.ML.Trainers; using Microsoft.ML.Transforms.Text;
2- ایجاد دو global fields برای نگه داشتن مسیر فایل مجموعه داده اخیرا دانلود شده و مسیر فایل ذخیره شده مدل:
3- برای مشخص کردن مسیر، کد زیر را به خط بالای متد Main اضافه کنید:
static readonly string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "yelp_labelled.txt"); static readonly string _modelPath = Path.Combine(Environment.CurrentDirectory, "Data", "Model.zip");
4- بعد، کلاس های داده های ورودی و پیش بینی ها را ایجاد کنید. یک کلاس جدید برای پروژه خود اضافه کنید:
5- فایل SentimentData.cs در ویرایشگر کد باز می شود. using زیر به بالای SentimentData.cs اضافه کنید:
using Microsoft.ML.Data;
6- تعریف کلاس موجود را حذف کنید و کد زیر را که دارای دو کلاس SentimentData و SentimentPrediction است به فایل SentimentData.cs اضافه کنید:
public class SentimentData { [LoadColumn(0)] public string SentimentText; [LoadColumn(1), ColumnName("Label")] public bool Sentiment; } public class SentimentPrediction : SentimentData { [ColumnName("PredictedLabel")] public bool Prediction { get; set; } public float Probability { get; set; } public float Score { get; set; } }
چگونه اطلاعات آماده شد
کلاس dataset ورودی ، SentimentData، یک رشته(string) برای نظرات کاربر (SentimentText) و یک مقدار bool (احساسات-Sentiment) از 1 (مثبت) یا 0 (منفی) برای احساسات دارد.هر دو فیلد دارای صفت LoadColumn هستند که به آنها متصل است، که ترتیب هر فیلد فایل داده را مشخص می کند. علاوه بر این، خصوصیت احساسات ( Property Sentiment) دارای صفت ColumnName است تا آن را به عنوان فیلد Label تعیین کند.فایل مثال زیر ردیف هدر ندارد ولی اینگونه به نظر می رسد:
پیش بینی احساسات- SentimentPrediction کلاس پیش بینی است که پس از آموزش مدل مورد استفاده قرار می گیرد.کلاس SentimentPrediction از SentimentData برای نشان دادن SentimentText (متن احساسات) با پیش بینی ها ارثبری می کند.پیشبینی احساسات-SentimentPrediction یک Property بولین (Prediction) و یک Property بولین (Sentiment - ارثبری شده است) با صفت ColumnName دارد .برچسب-Label برای ایجاد و آموزش مدل مورد استفاده قرار می گیرد و همچنین مجموعه داده های تست را از ارزیابی مدل جدا میکند.برچسب پیشبینی-PredictedLabel در پیش بینی و ارزیابی استفاده می شود. برای ارزیابی، داده های آموزشی، مقادیر پیش بینی شده و مدل مورد استفاده قرار می گیرد.
کلاس MLContext نقطه شروع برای تمام عملیات ML.NET است.ابتدا mlContext یک محیط جدید ML.NET ایجاد می کند که می تواند در سراسر اشیاء گردش کار ایجاد مدل (model creation workflow objects) به اشتراک گذاشته شود. مفهومی مانند DBContext در Entity Framework است.
داده ها در ML.NET به عنوان یک کلاس IDataView نمایش داده می شوند. IDataView یک روش انعطاف پذیر و کارآمد برای توصیف داده های جدولی (عددی و متن) است. داده ها را می توان از یک فایل متنی یا در زمان واقعی (به عنوان مثال پایگاه داده SQL یا فایل های log) به یک شی IDataView بارگذاری کرد.
برنامه را آماده می کنید و سپس داده ها را بارگیری می کنید:
1- خط Console.WriteLine ("Hello World!") در متد Main با کد زیر جایگزین کنید تا متغیر mlContext را اعلام و مقداردهی کنید:
MLContext mlContext = new MLContext();
2- به عنوان خط بعدی در متد Main() کد زیر را اضافه کنید:
TrainTestData splitDataView = LoadData(mlContext);
3- متد LoadData() درست بعد از متد Main() با استفاده از کد زیر بسازید:
public static TrainTestData LoadData(MLContext mlContext) { }
متد LoadData() وظایف زیر را انجام می دهد:
4- کد زیر را به عنوان خط اول متد LoadData() اضافه کنید:
IDataView dataView = mlContext.Data.LoadFromTextFile<SentimentData>(_dataPath, hasHeader: false);
متد LoadFromTextFile() شکل(schema) داده را مشخص می کند و از فایل می خواند. متغیر مسیر داده را میگیرد و یک IDataView را برمی گرداند.
جدا کردن مجموعه داده ها برای آموزش و آزمایش مدل
هنگام آماده سازی یک مدل، بخشی از مجموعه داده ها برای آموزش آن و بخشی از مجموعه داده ها برای آزمایش دقت مدل استفاده می کنید.
1- برای جدا کردن داده های بارگذاری شده به مجموعه داده های مورد نیاز، کد زیر را به عنوان خط بعدی در متد LoadData() اضافه کنید:
TrainTestData splitDataView = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2);
کد قبلی از متد TrainTestSplit() برای جدا کردن مجموعه داده های بارگذاری شده به مجموعه داده های آموزشی (train) و آزمایش (test) وبرگرداندن آن ها در کلاس TrainTestData استفاده می کند. تعیین درصد آزمایش داده ها با پارامتر testFraction. پیش فرض 10٪ است، در این مورد از 20٪ برای ارزیابی داده های بیشتر استفاده می کنید.
2- نهایتا splitDataView در انتهای متد LoadData() بازگردانید:
return splitDataView;
1- متد BuildAndTrainModel به عنوان خط بعدی کد در متد Main() اضافه کنید:
ITransformer model = BuildAndTrainModel(mlContext, splitDataView.TrainSet);
متد BuildAndTrainModel() وظایف زیر را انجام می دهد:
2- متد BuildAndTrainModel() درست بعد از متد Main() با استفاده از کد زیر:
public static ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet) { }
استخراج و تبدیل داده ها
1-فراخوانی FeaturizeText به عنوان خط بعدی کد:
var estimator = mlContext.Transforms.Text.FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentData.SentimentText))
متد FeaturizeText() در کد قبلی، ستون متن (SentimentText) را به یک نوع کلید عددی ستون Features تبدیل می کند مورد استفاده توسط الگوریتم یادگیری ماشین و آن را به عنوان یک ستون مجموعه داده جدید اضافه می کند:
اضافه کردن یک الگوریتم یادگیری
این برنامه از یک الگوریتم طبقه بندی(classification) استفاده می کند که اقلام(items) یا ردیف(row) داده را دسته بندی می کند. این برنامه نظرات وب سایت را به عنوان مثبت یا منفی طبقه بندی می کند، بنابراین از وظیفه طبقه بندی باینری(binary classification task) استفاده کنید.
با اضافه کردن موارد زیر به خط بعدی کد در BuildAndTrainModel()، وظیفه یادگیری ماشین را به تعریفات تبدیل داده اضافه کنید:
.Append(mlContext.BinaryClassification.Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features"));
این SdcaLogisticRegressionBinaryTrainer الگوریتم آموزش طبقه بندی شما است.این(منظور الگوریتم آموزش) به estimator اضافه شده است و SentimentText (که ستون Features هست) و Label پارامترهای ورودی را برای یادگیری از داده های تاریخی (historic data) پذیرفته است.
آموزش مدل
مدل را به داده های splitTrainSet به fit بسپارید و مدل آموزش دیده را با اضافه کردن موارد زیر به عنوان خط بعدی کد در متد BuildAndTrainModel() برگردانید:
Console.WriteLine("=============== Create and Train the Model ==============="); var model = estimator.Fit(splitTrainSet); Console.WriteLine("=============== End of training ==============="); Console.WriteLine();
متد Fit() با تبدیل کردن مجموعه داده ها (dataset) و استفاده از آموزش مدل خود را آموزش می دهد.
برگرداندن مدل آموزش دیده برای استفاده ارزیابی
آخر متد BuildAndTrainModel() مدل را بازگردانید:
return model;
پس از اینکه مدل شما آموزش دید، از داده های تست(آزمایش) استفاده کنید تا عملکرد مدل را تأیید کنید.
1- بعد از BuildAndTrainModel() ، متد Evaluate() ایجاد کنید:
public static void Evaluate(MLContext mlContext, ITransformer model, IDataView splitTestSet) { }
متد Evaluate() وظایف زیر را اجرا میکند:
2- متد را در متد Main() درست زیر فراخوانی متد BuildAndTrainModel() ،فراخوانی کنید:
Evaluate(mlContext, model, splitDataView.TestSet);
3- داده های splitTestSet را با اضافه کردن کد زیر بهEvaluate() تبدیل(Transform) کنید:
Console.WriteLine("=============== Evaluating Model accuracy with Test data==============="); IDataView predictions = model.Transform(splitTestSet);
کد بالا از متد Transform() برای پیش بینی چند ردیف ورودی آماده شده از یک مجموعه داده های آزمایش استفاده می کند.
4- مدل را با اضافه کردن کد زیر به عنوان خط بعدی در متد Evaluate()، ارزیابی کنید:
CalibratedBinaryClassificationMetrics metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label");
هنگامی که پیش بینی (predictions) را دارید، متد Evaluate() ارزیابی مدل، مقادیر پیش بینی شده را با Labels (برچسب ها)ی واقعی در مجموعه داده های آزمایش(test dataset) مقایسه می کند و یک شی CalibratedBinaryClassificationMetrics را بر اساس نحوه عملکرد مدل باز می کند.
از کد زیر برای نمایش معیارها (metrics) استفاده کنید:
Console.WriteLine(); Console.WriteLine("Model quality metrics evaluation"); Console.WriteLine("--------------------------------"); Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}"); Console.WriteLine($"Auc: {metrics.AreaUnderRocCurve:P2}"); Console.WriteLine($"F1Score: {metrics.F1Score:P2}"); Console.WriteLine("=============== End of model evaluation ===============");
پیش بینی خروجی داده آزمایش Predict the test data outcome
1- ایجاد متد UseModelWithSingleItem() بعد از متد Evaluate() با کد:
private static void UseModelWithSingleItem(MLContext mlContext, ITransformer model) { }
متد UseModelWithSingleItem() وظایف زیر را اجرا میکند:
2- در متد Main() در زیر فراخوانی متد Evaluate() متد جدید را اضافه کنید:
UseModelWithSingleItem(mlContext, model);
3- کد زیر را به عنوان اولین خط متد Predict() بنویسید:
PredictionEngine<SentimentData, SentimentPrediction> predictionFunction = mlContext.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(model);
موتور پیشبینی PredictionEngine یک API راحتی است که به شما اجازه می دهد یک نمونه از داده ها را وارد و سپس پیش بینی کنید.
4- یک نظر برای تست پیش بینی مدل آموزش یافته در متد Predict() با ایجاد یک نمونه از SentimentData اضافه کنید:
SentimentData sampleStatement = new SentimentData { SentimentText = "This was a very bad steak" };
5- داده نظر آزمایش را به موتور پیش بینی با اضافه کردن موارد زیر در خطوط بعدی کد به متد UseModelWithSingleItem() ارسال کنید:
var resultprediction = predictionFunction.Predict(sampleStatement);
تابع Predict() یک ردیف داده را پیش بینی می کند( prediction on a single row of data ).
6- نمایش SentimentText و پیش بینی مربوط به احساسات با استفاده از کد زیر:
Console.WriteLine(); Console.WriteLine("=============== Prediction Test of model with a single sample and test dataset ==============="); Console.WriteLine(); Console.WriteLine($"Sentiment: {resultprediction.SentimentText} | Prediction: {(Convert.ToBoolean(resultprediction.Prediction) ? "Positive" : "Negative")} | Probability: {resultprediction.Probability} "); Console.WriteLine("=============== End of Predictions ==============="); Console.WriteLine();
استقرار و پیش بینی ایتم های دسته ای(batch items)
1- ایجاد متد UseModelWithBatchItems() بعد از متد UseModelWithSingleItem() :
public static void UseModelWithBatchItems(MLContext mlContext, ITransformer model) { }
متد UseModelWithBatchItems() وظایف زیر را انجام میدهد:
2- صدا زدن متد بالا در متد Main() در زیر متد UseModelWithSingleItem() :
UseModelWithBatchItems(mlContext, model);
3-برای آزمایش پیش بینی مدل آموزش داده شده در متد UseModelWithBatchItems()، برخی از نظرات را اضافه کنید:
IEnumerable<SentimentData> sentiments = new[] { new SentimentData { SentimentText = "This was a horrible meal" }, new SentimentData { SentimentText = "I love this spaghetti." } };
پیش بینی احساس نظر
از مدل برای پیش بینی کردن داده احساس نظر با استفاده از متد Transform() استفاده کنید:
IDataView batchComments = mlContext.Data.LoadFromEnumerable(sentiments); IDataView predictions = model.Transform(batchComments); // Use model to predict whether comment data is Positive (1) or Negative (0). IEnumerable<SentimentPrediction> predictedResults = mlContext.Data.CreateEnumerable<SentimentPrediction>(predictions, reuseRowObject: false);
ترکیب و نمایش پیش بینی ها
یک هدر برای پیش بینی ها با استفاده از کد زیر ایجاد کنید:
Console.WriteLine(); Console.WriteLine("=============== Prediction Test of loaded model with multiple samples ===============");
از آنجا که SentimentPrediction از SentimentData به ارثبری کرده است، متدTransform() (متن احساسات)SentimentText را با فیلد های پیش بینی شده پر کرده است. همانطور که فرایند ML.NET پردازش می شود، هر مولفه ستون ها را اضافه می کند، و این باعث می شود که نمایش نتایج آسان شود:
foreach (SentimentPrediction prediction in predictedResults) { Console.WriteLine($"Sentiment: {prediction.SentimentText} | Prediction: {(Convert.ToBoolean(prediction.Prediction) ? "Positive" : "Negative")} | Probability: {prediction.Probability} "); } Console.WriteLine("=============== End of predictions ===============");
نتایج شما باید مشابه موارد زیر باشد. در حین پردازش پیام ها نمایش داده می شوند. ممکن است هشدارها یا پردازش پیام ها را مشاهده کنید. این ها از نتایج زیر برای وضوح حذف شده اند.
Model quality metrics evaluation
--------------------------------
Accuracy: 83.96%
Auc: 90.51%
F1Score: 84.04%
=============== End of model evaluation ===============
=============== Prediction Test of model with a single sample and test dataset ===============
Sentiment: This was a very bad steak | Prediction: Negative | Probability: 0.1027377
=============== End of Predictions ===============
=============== Prediction Test of loaded model with a multiple samples ===============
Sentiment: This was a horrible meal | Prediction: Negative | Probability: 0.1369192
Sentiment: I love this spaghetti. | Prediction: Positive | Probability: 0.9960636
=============== End of predictions ===============
=============== End of process ===============
Press any key to continue . . .
تبریک می گویم! شما اکنون موفق به ساخت یک مدل یادگیری ماشین برای طبقه بندی و پیش بینی نظرات شده اید.
ساختن مدل های موفق یک روند تکراری است. این مدل دارای کیفیت اولیه پاینی است زیرا آموزش از مجموعه داده های کوچک برای ارائه آموزش سریع مدل استفاده می کند. اگر شما با کیفیت مدل راضی نیستید، می توانید آن را با ارائه مجموعه های آموزشی بزرگ تر و یا با انتخاب الگوریتم های آموزشی مختلف با پارامترهای مختلف( hyper-parameters) برای هر الگوریتم، امتحان کنید.
شما می توانید کد منبع این آموزش را در مخزن dotnet/samples پیدا کنید.
در این آموزش، شما یاد گرفتید که چگونه:
برای یادگیری بیشتر به آموزش بعدی بروید