diff --git a/NotaionWebApp/Notaion.Domain/Models/ChatModelTrainer.cs b/NotaionWebApp/Notaion.Domain/Models/ChatModelTrainer.cs deleted file mode 100644 index c0a39aa..0000000 --- a/NotaionWebApp/Notaion.Domain/Models/ChatModelTrainer.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Microsoft.ML; - -namespace Notaion.Domain.Models -{ - public class ChatInput - { - public string Question { get; set; } - public string Response { get; set; } - } - - public class ChatPrediction - { - public string PredictedLabel { get; set; } - } - public class ChatModelTrainer - { - private const string ModelPath = "chatbot_model.zip"; - - public void TrainModel(string trainingDataPath) - { - var mlContext = new MLContext(); - - // Load dữ liệu huấn luyện - var data = mlContext.Data.LoadFromTextFile( - path: trainingDataPath, - hasHeader: true, - separatorChar: ','); - - // Xây dựng pipeline huấn luyện - var pipeline = mlContext.Transforms.Text.FeaturizeText("Features", nameof(ChatInput.Question)) - .Append(mlContext.Transforms.Conversion.MapValueToKey("Label", nameof(ChatInput.Response))) - .Append(mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy()) - .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "Label")); - - // Huấn luyện mô hình - var model = pipeline.Fit(data); - - // Lưu mô hình - mlContext.Model.Save(model, data.Schema, ModelPath); - Console.WriteLine($"Mô hình đã được lưu tại: {ModelPath}"); - } - } -} diff --git a/NotaionWebApp/Notaion.Infrastructure/DependencyInjection.cs b/NotaionWebApp/Notaion.Infrastructure/DependencyInjection.cs index 6292538..b4adf83 100644 --- a/NotaionWebApp/Notaion.Infrastructure/DependencyInjection.cs +++ b/NotaionWebApp/Notaion.Infrastructure/DependencyInjection.cs @@ -9,11 +9,6 @@ using Notaion.Infrastructure.Persistence; using Notaion.Infrastructure.Repositories; using Notaion.Infrastructure.Services; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Notaion.Infrastructure { @@ -47,6 +42,8 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi services.AddScoped(); + services.AddSingleton(); + return services; } } diff --git a/NotaionWebApp/Notaion.Infrastructure/Notaion.Infrastructure.csproj b/NotaionWebApp/Notaion.Infrastructure/Notaion.Infrastructure.csproj index 1b05e8c..abd3376 100644 --- a/NotaionWebApp/Notaion.Infrastructure/Notaion.Infrastructure.csproj +++ b/NotaionWebApp/Notaion.Infrastructure/Notaion.Infrastructure.csproj @@ -13,6 +13,7 @@ + diff --git a/NotaionWebApp/Notaion.Infrastructure/Repositories/ChatModelTrainer.cs b/NotaionWebApp/Notaion.Infrastructure/Repositories/ChatModelTrainer.cs new file mode 100644 index 0000000..3a70159 --- /dev/null +++ b/NotaionWebApp/Notaion.Infrastructure/Repositories/ChatModelTrainer.cs @@ -0,0 +1,122 @@ +using Microsoft.ML; +using Microsoft.ML.Data; + +namespace Notaion.Infrastructure.Repositories +{ + // Định nghĩa lớp chứa dữ liệu huấn luyện + public class ChatData + { + [LoadColumn(0)] + public string Question { get; set; } + + [LoadColumn(1)] + public string Response { get; set; } + } + + // Lớp huấn luyện mô hình + public class ChatModelTrainer + { + private readonly string ModelPath = Path.Combine(Directory.GetCurrentDirectory(), "chatbot_model.zip"); + + // Huấn luyện mô hình từ file CSV + public async Task TrainModelFromCsvAsync(string filePath) + { + try + { + var mlContext = new MLContext(); + + // Đọc dữ liệu từ tệp CSV + var data = mlContext.Data.LoadFromTextFile(filePath, separatorChar: ',', hasHeader: true); + + var preview = data.Preview(10); // Hiển thị 10 dòng đầu tiên của dữ liệu + foreach (var row in preview.RowView) + { + Console.WriteLine($"Question: {row.Values[0].Value}, Response: {row.Values[1].Value}"); + } + + // Xây dựng pipeline huấn luyện + var pipeline = mlContext.Transforms.Text.FeaturizeText("Features", nameof(ChatData.Question)) // Tính năng từ câu hỏi + .Append(mlContext.Transforms.Conversion.MapValueToKey("Label", nameof(ChatData.Response))) // Câu trả lời là nhãn + .Append(mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy("Label", "Features")) // Huấn luyện phân loại + .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabel", "PredictedLabel")); + + // Huấn luyện mô hình + var model = pipeline.Fit(data); + + // Kiểm tra kết quả trước khi lưu mô hình + var transformer = model.Transform(data); + var predictions = mlContext.Data.CreateEnumerable(transformer, reuseRowObject: false).ToList(); + + foreach (var prediction in predictions) + { + if (string.IsNullOrWhiteSpace(prediction.PredictedLabel)) + { + Console.WriteLine("Dự đoán bị thiếu cho câu hỏi: " + prediction.Question); + } + else + { + Console.WriteLine($"Câu hỏi: {prediction.Question}, Dự đoán câu trả lời: {prediction.PredictedLabel}"); + } + } + + // Lưu mô hình vào file + mlContext.Model.Save(model, data.Schema, ModelPath); + Console.WriteLine($"Mô hình đã được lưu tại: {ModelPath}"); + } + catch (Exception ex) + { + Console.WriteLine($"Lỗi khi huấn luyện mô hình: {ex.Message}"); + throw; + } + } + + // Dự đoán câu trả lời từ câu hỏi của người dùng + public async Task PredictResponseAsync(string userMessage) + { + try + { + var mlContext = new MLContext(); + + // Kiểm tra xem mô hình có tồn tại không + if (!File.Exists(ModelPath)) + { + throw new FileNotFoundException("Mô hình không tồn tại tại: " + ModelPath); + } + + // Load mô hình đã huấn luyện + var model = mlContext.Model.Load(ModelPath, out var modelInputSchema); + + // Tạo prediction engine + var predictionEngine = mlContext.Model.CreatePredictionEngine(model); + + // Sử dụng mô hình thực tế để dự đoán phản hồi + var prediction = predictionEngine.Predict(new ChatData { Question = userMessage }); + + // Kiểm tra kết quả dự đoán từ mô hình + if (string.IsNullOrWhiteSpace(prediction?.PredictedLabel)) + { + return "Xin lỗi, tôi không thể trả lời câu hỏi này."; + } + + // Trả về kết quả dự đoán + return prediction.PredictedLabel; + } + catch (FileNotFoundException ex) + { + return "Không tìm thấy mô hình: " + ex.Message; + } + catch (Exception ex) + { + return "Đã xảy ra lỗi khi dự đoán: " + ex.Message; + } + } + } + + + // Dự đoán phản hồi cho một câu hỏi + public class ChatPrediction + { + public string Question { get; set; } // Câu hỏi gốc + public string PredictedLabel { get; set; } // Câu trả lời dự đoán + } +} \ No newline at end of file diff --git a/NotaionWebApp/Notaion/Controllers/ChatController.cs b/NotaionWebApp/Notaion/Controllers/ChatController.cs index d5aacae..4bcbdc9 100644 --- a/NotaionWebApp/Notaion/Controllers/ChatController.cs +++ b/NotaionWebApp/Notaion/Controllers/ChatController.cs @@ -1,18 +1,12 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; -using Notaion.Infrastructure.Context; -using Notaion.Domain.Entities; -using Notaion.Hubs; using Microsoft.EntityFrameworkCore; -using Notaion.Domain.Models; using Notaion.Application.DTOs.Chats; -using Notaion.Application.Common.Helpers; -using AutoMapper; -using Notaion.Application.Services; using Notaion.Application.Interfaces.Services; -using Microsoft.AspNetCore.Authorization; -using System; -using Notaion.Domain.Interfaces; +using Notaion.Hubs; +using Notaion.Infrastructure.Context; +using Notaion.Infrastructure.Repositories; namespace Notaion.Controllers { @@ -23,11 +17,55 @@ public class ChatController : ControllerBase private readonly ApplicationDbContext _context; private readonly IHubContext _hubContext; private readonly IChatService chatService; - public ChatController(ApplicationDbContext context, IHubContext hubContext, IChatService chatService) + private readonly ChatModelTrainer _chatModelTrainer; + public ChatController(ApplicationDbContext context, IHubContext hubContext, IChatService chatService, ChatModelTrainer chatModelTrainer) { _context = context; this.chatService = chatService; _hubContext = hubContext; + _chatModelTrainer = chatModelTrainer; + } + + [HttpPost("train")] + public async Task TrainChatbotModel() + { + try + { + // Sử dụng đường dẫn cố định đến file responses.csv + string filePath = Path.Combine(Directory.GetCurrentDirectory(), "responses.csv"); + + // Kiểm tra xem file có tồn tại không + if (!System.IO.File.Exists(filePath)) + { + return BadRequest($"File không tồn tại tại đường dẫn: {filePath}"); + } + var modelTrainer = new ChatModelTrainer(); + // Huấn luyện mô hình từ file + await modelTrainer.TrainModelFromCsvAsync(filePath); + return Ok("Mô hình đã được huấn luyện thành công."); + } + catch (Exception ex) + { + return BadRequest($"Đã xảy ra lỗi khi huấn luyện mô hình: {ex.Message}"); + } + } + + + + // Dự đoán câu trả lời từ câu hỏi của người dùng + [HttpPost("predict")] + public async Task PredictResponse([FromBody] string userMessage) + { + try + { + // Gọi phương thức bất đồng bộ + var response = await _chatModelTrainer.PredictResponseAsync(userMessage); + return Ok(new { Response = response }); + } + catch (Exception ex) + { + return BadRequest($"Đã xảy ra lỗi trong quá trình dự đoán: {ex.Message}"); + } } //[HttpGet("test-genaric-repo")] diff --git a/NotaionWebApp/Notaion/Notaion.csproj b/NotaionWebApp/Notaion/Notaion.csproj index c595c1c..1ad81c0 100644 --- a/NotaionWebApp/Notaion/Notaion.csproj +++ b/NotaionWebApp/Notaion/Notaion.csproj @@ -32,6 +32,7 @@ + diff --git a/NotaionWebApp/Notaion/chatbot_model.zip b/NotaionWebApp/Notaion/chatbot_model.zip new file mode 100644 index 0000000..ef0be14 Binary files /dev/null and b/NotaionWebApp/Notaion/chatbot_model.zip differ diff --git a/NotaionWebApp/Notaion/responses.csv b/NotaionWebApp/Notaion/responses.csv index 338c3c2..7e01891 100644 --- a/NotaionWebApp/Notaion/responses.csv +++ b/NotaionWebApp/Notaion/responses.csv @@ -1,7 +1,5 @@ Question,Response -"Xin chào","Chào bạn, tôi có thể giúp gì?" +"hello","hi" "Thời tiết hôm nay thế nào?","Thời tiết hôm nay nắng đẹp." -"Bạn tên gì?","Tôi là Chatbot." -"Tôi muốn học lập trình","Hãy bắt đầu với những bài học cơ bản." -"Giá vàng hôm nay là bao nhiêu?","Hiện tại tôi chưa có thông tin về giá vàng." - \ No newline at end of file +"Bạn tên gì?","Tôi là một chatbot." +"Chào bạn!","Chào bạn!"