ساخت یک سیستم توصیهگر هوشمند فیلم با ML.NET: از تئوری تا عمل
در این مقاله، ما به صورت گام به گام نحوه ساخت یک سیستم توصیهگر فیلم را با استفاده از ML.NET بررسی خواهیم کرد. ابتدا با مفاهیم کلیدی سیستمهای توصیهگر آشنا میشویم، سپس به مقایسه دو رویکرد اصلی یعنی فیلترینگ مبتنی بر همکاری (Collaborative Filtering) و فیلترینگ مبتنی بر محتوا (Content-Based Filtering) میپردازیم و در نهایت، یک سیستم کامل را با الگوریتم فاکتورسازی ماتریس (Matrix Factorization) پیادهسازی میکنیم.
درک انواع سیستمهای توصیهگر
سیستمهای توصیهگر عمدتاً به دو دسته اصلی تقسیم میشوند که هر کدام منطق و رویکرد متفاوتی برای ارائه پیشنهاد دارند.
1. فیلترینگ مبتنی بر همکاری (Collaborative Filtering)
این رویکرد، محبوبترین و رایجترین نوع سیستم توصیهگر است. ایده اصلی آن ساده است: "اگر کاربر A سلیقهای مشابه کاربر B داشته باشد، پس احتمالاً چیزهایی را که B دوست دارد، A نیز دوست خواهد داشت." این روش به دو زیرشاخه تقسیم میشود:
-
مبتنی بر کاربر (User-Based): این روش کاربرانی با سوابق امتیازدهی مشابه را پیدا کرده و آیتمهایی را که توسط این کاربران مشابه امتیاز بالایی گرفتهاند اما کاربر هدف هنوز آنها را ندیده است، پیشنهاد میدهد.
-
مبتنی بر آیتم (Item-Based): این روش به جای یافتن کاربران مشابه، آیتمهای مشابه را پیدا میکند. برای مثال، اگر کاربری فیلم "Inception" را دوست داشته، سیستم فیلمهایی را که کاربران دیگر نیز در کنار "Inception" به آنها امتیاز بالا دادهاند (مانند "The Dark Knight" یا "Interstellar")، به او پیشنهاد میدهد.
مزایا:
-
نیازی به اطلاعات در مورد خود آیتمها (مانند ژانر فیلم یا نام بازیگران) ندارد.
-
قادر به کشف پیشنهادهای غیرمنتظره و شگفتانگیز (Serendipity) است.
معایب:
-
با مشکل "شروع سرد" (Cold Start) مواجه است؛ یعنی برای کاربران یا آیتمهای جدید که هیچ دادهای از آنها وجود ندارد، نمیتواند توصیهای ارائه دهد.
-
به حجم زیادی از دادههای تعاملی کاربر-آیتم نیاز دارد.
2. فیلترینگ مبتنی بر محتوا (Content-Based Filtering)
این رویکرد بر اساس ویژگیهای آیتمها و پروفایل علاقهمندیهای کاربر کار میکند. سیستم، آیتمهایی را پیشنهاد میدهد که از نظر ویژگیها (محتوا) شبیه به آیتمهایی هستند که کاربر در گذشته دوست داشته است. برای مثال، اگر کاربری چندین فیلم در ژانر "علمی-تخیلی" به کارگردانی "کریستوفر نولان" را پسندیده باشد، سیستم فیلمهای دیگری با همین ژانر یا از همین کارگردان را به او پیشنهاد میدهد.
مزایا:
-
مشکل "شروع سرد" برای آیتمهای جدید را ندارد (تا زمانی که ویژگیهای آنها مشخص باشد).
-
توصیهها به راحتی قابل تفسیر هستند (مثلاً: "چون شما فیلم X را دوست داشتید، ما فیلم Y را پیشنهاد میدهیم").
معایب:
-
تنوع پیشنهادها محدود است و کمتر باعث کشف علاقهمندیهای جدید میشود.
-
نیاز به مهندسی ویژگیهای دقیق و استخراج اطلاعات از محتوای آیتمها دارد.
در این مقاله، ما بر روی فیلترینگ مبتنی بر همکاری با استفاده از الگوریتم فاکتورسازی ماتریس تمرکز خواهیم کرد، زیرا این یکی از قدرتمندترین و پرکاربردترین الگوریتمها در ML.NET برای این منظور است.
گام به گام ساخت سیستم توصیهگر فیلم با ML.NET
بیایید یک برنامه کنسول در داتنت بسازیم که بتواند بر اساس امتیازاتی که کاربران به فیلمها دادهاند، پیشبینی کند یک کاربر خاص به یک فیلم مشخص چه امتیازی خواهد داد.
گام 1: ایجاد پروژه و نصب ML.NET
ابتدا یک پروژه کنسول جدید در ویژوال استودیو یا با استفاده از .NET CLI ایجاد کنید:
dotnet new console -n MovieRecommender
cd MovieRecommender
سپس، پکیج Nuget مربوط به ML.NET را نصب کنید:
dotnet add package Microsoft.ML
گام 2: آمادهسازی دادهها
ما به یک مجموعه داده نیاز داریم که شامل تعاملات کاربران با فیلمها باشد. فرمت رایج برای این کار، فایلی با سه ستون است: userId, movieId, rating. میتوانید از مجموعه دادههای معروفی مانند MovieLens استفاده کنید. برای سادگی، فرض کنید یک فایل ratings.csv با محتوای زیر داریم:
userId,movieId,rating
1,10,5
1,12,4
2,10,4
2,15,5
3,12,5
3,18,3
این دادهها نشان میدهد که کاربر 1 به فیلم 10 امتیاز 5 و به فیلم 12 امتیاز 4 داده است.

گام 3: تعریف مدلهای داده (Data Models)
در پروژه خود دو کلاس برای تعریف ساختار ورودی و خروجی مدل ایجاد کنید.
// کلاس برای نگهداری دادههای ورودی از فایل CSV
public class MovieRating
{
[LoadColumn(0)]
public float UserId { get; set; }
[LoadColumn(1)]
public float MovieId { get; set; }
[LoadColumn(2)]
public float Label { get; set; } // امتیاز کاربر به عنوان "برچسب" در نظر گرفته میشود
}
// کلاس برای نگهداری نتیجه پیشبینی
public class MovieRatingPrediction
{
public float Label { get; set; } // امتیاز اصلی
public float Score { get; set; } // امتیاز پیشبینی شده توسط مدل
}
ویژگی [LoadColumn] به ML.NET میگوید که هر ستون از فایل CSV باید به کدام ویژگی در کلاس نگاشت شود. ستون rating را به عنوان Label در نظر میگیریم، زیرا این همان مقداری است که میخواهیم مدل یاد بگیرد آن را پیشبینی کند.
گام 4: بارگذاری و آمادهسازی دادهها
در فایل Program.cs، ابتدا MLContext را که نقطه شروع تمام عملیات ML.NET است، ایجاد میکنیم. سپس دادهها را از فایل ratings.csv بارگذاری کرده و آنها را به دو مجموعه آموزش (Training) و آزمایش (Testing) تقسیم میکنیم.
using Microsoft.ML;
using MovieRecommender;
// 1. ایجاد MLContext
var mlContext = new MLContext();
// 2. بارگذاری دادهها از فایل
var data = mlContext.Data.LoadFromTextFile<MovieRating>("./ratings.csv", hasHeader: true, separatorChar: ',');
// 3. تقسیم دادهها به مجموعه آموزش (80%) و آزمایش (20%)
var trainTestSplit = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);
var trainingData = trainTestSplit.TrainSet;
var testData = trainTestSplit.TestSet;
گام 5: ساخت و آموزش مدل (Pipeline)
اکنون زمان ساخت پایپلاین (Pipeline) یادگیری ماشین است. برای سیستم توصیهگر، از الگوریتم MatrixFactorization استفاده میکنیم. این الگوریتم در پشت صحنه یک ماتریس بزرگ از تعاملات کاربر-فیلم را به دو ماتریس کوچکتر (یکی برای ویژگیهای کاربران و دیگری برای ویژگیهای فیلمها) تجزیه میکند. این ویژگیهای پنهان (Latent Features) به مدل اجازه میدهند تا سلیقه کاربران و خصوصیات فیلمها را یاد بگیرد.
// 4. تعریف پایپلاین آموزش
var options = new Microsoft.ML.Trainers.MatrixFactorizationTrainer.Options
{
MatrixColumnIndexColumnName = "UserId", // ستون شناسه کاربر
MatrixRowIndexColumnName = "MovieId", // ستون شناسه آیتم (فیلم)
LabelColumnName = "Label", // ستون امتیاز
NumberOfIterations = 20, // تعداد تکرار برای بهینهسازی
ApproximationRank = 100 // تعداد ویژگیهای پنهان
};
var pipeline = mlContext.Transforms.Conversion.MapValueToKey(inputColumnName: "UserId", outputColumnName: "UserIdEncoded")
.Append(mlContext.Transforms.Conversion.MapValueToKey(inputColumnName: "MovieId", outputColumnName: "MovieIdEncoded"))
.Append(mlContext.Recommendation().Trainers.MatrixFactorization(options));
// 5. آموزش مدل
Console.WriteLine("Training the model...");
var model = pipeline.Fit(trainingData);
Console.WriteLine("Model training complete.");
در این پایپلاین:
-
MapValueToKey: الگوریتم فاکتورسازی ماتریس با مقادیر کلیدی عددی (index) کار میکند نه شناسههای خام. این تبدیلگر، شناسههای UserId و MovieId را به ایندکسهای عددی تبدیل میکند.
-
MatrixFactorization: این همان تخمینگر (Estimator) اصلی است که مدل توصیهگر را با گزینههایی که تعریف کردهایم، آموزش میدهد.
گام 6: ارزیابی مدل
پس از آموزش، باید عملکرد مدل را بسنجیم. این کار را با استفاده از مجموعه داده آزمایش (testData) که کنار گذاشته بودیم، انجام میدهیم. معیارهای رایجی مانند خطای مطلق میانگین (MAE) و ریشه میانگین مربعات خطا (RMSE) به ما نشان میدهند که پیشبینیهای مدل به طور متوسط چقدر با امتیازات واقعی فاصله دارند. هرچه این مقادیر کمتر باشند، مدل دقیقتر است.
// 6. ارزیابی مدل
Console.WriteLine("Evaluating the model...");
var predictions = model.Transform(testData);
var metrics = mlContext.Regression.Evaluate(predictions, labelColumnName: "Label", scoreColumnName: "Score");
Console.WriteLine($"Root Mean Squared Error (RMSE): {metrics.RootMeanSquaredError}");
Console.WriteLine($"Mean Absolute Error (MAE): {metrics.MeanAbsoluteError}");
گام 7: استفاده از مدل برای پیشبینی
حالا که مدل آموزش دیده و ارزیابی شده است، میتوانیم از آن برای پیشبینی امتیاز یک فیلم برای یک کاربر خاص استفاده کنیم. برای این کار از PredictionEngine استفاده میکنیم
// 7. ایجاد موتور پیشبینی و انجام یک پیشبینی تکی
var predictionEngine = mlContext.Model.CreatePredictionEngine<MovieRating, MovieRatingPrediction>(model);
// یک نمونه برای پیشبینی: آیا کاربر 1 فیلم 15 را دوست خواهد داشت؟
var testInput = new MovieRating { UserId = 1, MovieId = 15 };
var movieRatingPrediction = predictionEngine.Predict(testInput);
Console.WriteLine($"Prediction for UserId: {testInput.UserId}, MovieId: {testInput.MovieId}");
Console.WriteLine($"Predicted Rating: {Math.Round(movieRatingPrediction.Score, 1)}");
اگر امتیاز پیشبینی شده بالا باشد (مثلاً نزدیک به 5)، میتوانیم این فیلم را به کاربر پیشنهاد دهیم.
مقایسه عملی: چه زمانی از فیلترینگ مبتنی بر محتوا استفاده کنیم؟
اگرچه فیلترینگ مبتنی بر همکاری قدرتمند است، اما در سناریوی "شروع سرد" با مشکل مواجه میشود. فرض کنید یک فیلم جدید به پلتفرم اضافه شده و هیچ کاربری هنوز به آن امتیاز نداده است. مدل ما قادر به توصیه آن نخواهد بود.
در چنین شرایطی، فیلترینگ مبتنی بر محتوا به کمک میآید. اگر ما ویژگیهای فیلم (مانند ژانر، بازیگران، کارگردان) را در اختیار داشته باشیم، میتوانیم با ML.NET یک مدل رگرسیون یا طبقهبندی بسازیم که بر اساس این ویژگیها، شباهت آن را به فیلمهای مورد علاقه کاربر بسنجد. پیادهسازی این رویکرد نیازمند مهندسی ویژگی و استفاده از الگوریتمهایی مانند LightGbm یا Sdca در ML.NET است.
یک رویکرد ترکیبی (Hybrid) که هر دو روش را با هم ادغام میکند، معمولاً بهترین نتایج را به همراه دارد و میتواند هم دقت بالایی داشته باشد و هم مشکل شروع سرد را برطرف کند.
نتیجهگیری
کتابخانه ML.NET به توسعهدهندگان داتنت این قدرت را میدهد که به راحتی و با نوشتن کدهای C#، سیستمهای پیچیده یادگیری ماشین مانند سیستمهای توصیهگر را بسازند. ما در این مقاله دیدیم که چگونه با استفاده از الگوریتم فاکتورسازی ماتریس، میتوان یک سیستم توصیهگر مبتنی بر همکاری را پیادهسازی کرد. این فرآیند شامل آمادهسازی دادهها، ساخت پایپلاین، آموزش، ارزیابی و در نهایت استفاده از مدل برای پیشبینی بود.
سیستمهای توصیهگر تنها یکی از قابلیتهای بیشمار ML.NET هستند. با کاوش بیشتر در این فریمورک، میتوان به دنیای وسیعتری از تحلیل احساسات، تشخیص تصویر، و پیشبینیهای تجاری قدم گذاشت و برنامههای کاربردی داتنت را هوشمندتر از همیشه ساخت.
0 نظر
هنوز نظری برای این مقاله ثبت نشده است.