教程:使用 ML.NET 模型生成器在 Web 应用程序中分析网站评论的情绪

了解如何在 Web 应用程序中实时分析评论中的情绪。

本教程演示如何创建 ASP.NET Core Razor Pages 应用程序,该应用程序实时对网站评论情绪进行分类并采取适当的措施。

在本教程中,你将了解:

  • 创建 ASP.NET Core Razor Pages 应用程序
  • 准备和了解数据
  • 选择方案
  • 加载数据
  • 定型模型
  • 评估模型
  • 使用预测模型

可以在 dotnet/machinelearning-samples 存储库中找到本教程的源代码。

先决条件

请访问模型生成器安装指南,查看先决条件和安装说明的列表。

创建 Razor Pages 应用程序

创建“ASP.NET Core Razor Pages 应用程序”。

  1. 在 Visual Studio 中,打开“创建新项目”对话框。
  2. 在“创建新项目”对话框中,选择 ASP.NET Core Web 应用项目模板。
  3. 在“名称”文本框中,键入“SentimentRazor”,然后选择“下一步”按钮。
  4. 在“其他信息”对话框中,将所有默认值保留原样,然后选择“创建”按钮。

准备和了解数据

下载维基百科 detox 数据集。 打开网页时,右键单击页面,选择“另存为” ,将文件保存到计算机上的任何位置。

wikipedia-detox-250-line-data.tsv 数据集中的每一行都代表一个用户在维基百科上留下的不同评价。 第一列表示文本的情绪(0 表示 non-toxic (无害),1 表示 toxic (不良)),第二列表示用户留下的评论。 列由制表符分隔。 数据类似如下所示:

情绪 情绪文本
1 ==RUDE== Dude, you are rude upload that carl picture back, or else.
1 == OK! == IM GOING TO VANDALIZE WILD ONES WIKI THEN!!!
0 我希望这会有所帮助。

创建 Model Builder 配置文件

首次将机器学习模型添加到解决方案时,它会提示你创建一个 mbconfig 文件。 该 mbconfig 文件跟踪你在 Model Builder 中所执行的所有操作,以允许你重新打开会话。

  1. 在“解决方案资源管理器”中,右键单击“SentimentRazor”项目,然后选择“添加”>“机器学习模型...”。
  2. 在对话框中,将 Model Builder 项目命名为 SentimentAnalysis.mbconfig,然后选择“添加”。

选择方案

Model Builder 方案屏幕

为了训练模型,需要从模型生成器提供的可用机器学习方案列表中进行选择。

本示例的任务是文本分类。 在 Model Builder 工具的“方案”扩展中,选择“文本分类”方案。

选择环境

Model Builder 可以根据所选方案在不同的环境中训练。

选择“本地 (GPU)”作为环境,然后单击“下一步”按钮。

注意

此方案使用在 GPU 环境中最适用的深度学习技术。 如果没有 GPU,请选择“本地 (CPU)”环境,但请注意,预期的训练时间要长得多。 有关将 GPU 与 Model Builder 配合使用的详细信息,请参阅 Model Builder 中的 GPU 支持指南

加载数据

模型生成器接受来自两个源的数据:SQL Server 数据库或者 csvtsv 格式的本地文件。

  1. 在 Model Builder 工具的数据步骤中,选择数据源选项中的“文件”。
  2. 选择“选择文件”文本框旁边的按钮,并使用文件资源管理器浏览到 wikipedia-detox-250-line-data.tsv 文件,然后选择该文件 。
  3. 从“要预测的列(标签)”下拉列表中选择“情绪”。
  4. 从“文本列”下拉列表中选择“SentimentText”。
  5. 选择“下一步”按钮以移至 Model Builder 中的下一步。

定型模型

在本教程中,用于训练情绪分析模型的机器学习任务是文本分类。 在模型训练过程中,Model Builder 使用 NAS-BERT 神经网络体系结构为数据集训练文本分类模型。

  1. 选择“开始训练” 。

  2. 训练完成后,训练过程的结果将显示在“训练”屏幕的“训练结果”部分中。 除了提供训练结果外,还会在 SentimentAnalysis.mbconfig 文件下创建三个代码隐藏文件。

    • SentimentAnalysis.consumption.cs - 此文件包含 ModelInputModelOutput 架构,以及为使用模型生成的 Predict 函数。
    • SentimentAnalysis.training.cs - 此文件包含 Model Builder 选择的训练管道(数据转换、训练器、训练器超参数)以训练模型。 你可以使用此管道重新训练模型。
    • *SentimentAnalysis.zip - 这是一个已序列化的 zip 文件,它表示经过训练的 ML.NET 模型。
  3. 选择“下一步”按钮以移至下一步。

评估模型

训练步骤的成果将是一个模型,该模型具备最佳的性能。 在 Model Builder 工具的评估步骤中,输出部分将包含性能最佳模型使用的训练器以及评估指标。

如果对评估指标不满意,尝试提高模型性能的一个简单方法是使用更多数据。

否则,请选择“下一步”按钮,以转到 Model Builder 中的“使用”步骤。

添加使用项目模板(可选)

在“使用”步骤中,Model Builder 提供可用于使用模型的项目模板。 此步骤是可选的,你可以选择最适合你使用模型需求的方法。

  • 控制台应用程序
  • Web API

添加代码进行预测

配置 PredictionEngine 池

若要进行单一预测,必须创建 PredictionEngine<TSrc,TDst>PredictionEngine<TSrc,TDst> 不是线程安全。 此外,必须在应用程序中的每一处所需位置创建它的实例。 随着应用程序的增长,此过程可能会变得难以管理。 为了提高性能和线程安全,请结合使用依赖项注入和 PredictionEnginePool 服务,这将创建一个在整个应用程序中使用的 PredictionEngine<TSrc,TDst> 对象的 ObjectPool<T>

  1. 安装 Microsoft.Extensions.ML NuGet 包 :

    1. 在“解决方案资源管理器”中,右键单击项目,然后选择“管理 NuGet 包” 。
    2. 选择“nuget.org”作为“包源”。
    3. 选择“浏览” 选项卡,搜索“Microsoft.Extensions.ML” 。
    4. 在列表中选择包,然后选择“安装” 按钮。
    5. 选择“预览更改” 对话框中的“确定” 按钮
    6. 如果同意所列包的许可条款,请选择“接受许可” 对话框中的“我接受” 按钮。
  2. 打开“SentimentRazor”项目中的“Program.cs”文件。

  3. 添加以下 using 语句以引用 Microsoft.Extensions.ML NuGet 包和 SentimentRazorML.Model 项目:

    using Microsoft.Extensions.ML;
    using static SentimentRazor.SentimentAnalysis;
    
  4. Program.cs 文件中为应用程序配置 PredictionEnginePool<TData,TPrediction>

    builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
        .FromFile("SentimentAnalysis.zip");
    

创建情绪分析处理程序

预测将在应用程序的主页内进行。 因此,需要添加一个采用用户输入并使用 PredictionEnginePool<TData,TPrediction> 来返回预测的方法。

  1. 打开位于 Pages 目录中的 Index.cshtml.cs 文件,并添加以下 using 语句:

    using Microsoft.Extensions.ML;
    using static SentimentRazor.SentimentAnalysis;
    

    要使用 Program.cs 文件中已配置的 PredictionEnginePool<TData,TPrediction>,必须将它注入到要在其中使用它的模型的构造函数中。

  2. 添加一个变量,以引用 Pages/Index.cshtml.cs 文件内的 IndexModel 类内的 PredictionEnginePool<TData,TPrediction>

    private readonly PredictionEnginePool<ModelInput, ModelOutput> _predictionEnginePool;
    
  3. 修改 IndexModel 类中的构造函数,并将 PredictionEnginePool<TData,TPrediction> 服务注入到其中。

    public IndexModel(ILogger<IndexModel> logger, PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool)
    {
        _logger = logger;
        _predictionEnginePool = predictionEnginePool;
    }
    
  4. 创建一个方法处理程序,该处理程序使用 PredictionEnginePool 来对从网页接收的用户输入进行预测。

    1. OnGet 方法下面,创建一个名为 OnGetAnalyzeSentiment 的新方法

      public IActionResult OnGetAnalyzeSentiment([FromQuery] string text)
      {
      
      }
      
    2. OnGetAnalyzeSentiment 方法中,如果用户输入为空或为 null,则返回“中性”情绪 。

      if (String.IsNullOrEmpty(text)) return Content("Neutral");
      
    3. 给定有效的输入,创建新的 ModelInput 实例。

      var input = new ModelInput { SentimentText = text };
      
    4. 使用 PredictionEnginePool<TData,TPrediction> 预测情绪。

      var prediction = _predictionEnginePool.Predict(input);
      
    5. 使用以下代码将预测的 bool 值转换为“toxic”或“not toxic”。

      var sentiment = Convert.ToBoolean(prediction.PredictedLabel) ? "Toxic" : "Not Toxic";
      
    6. 最后,将情绪返回到网页上。

      return Content(sentiment);
      

配置网页

OnGetAnalyzeSentiment 返回的结果将在 Index 网页上动态显示。

  1. 在“Pages” 目录中打开 Index.cshtml 文件,并将其内容替换为以下代码:

    @page
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div class="text-center">
        <h2>Live Sentiment</h2>
    
        <p><textarea id="Message" cols="45" placeholder="Type any text like a short review"></textarea></p>
    
        <div class="sentiment">
            <h4>Your sentiment is...</h4>
            <p>😡 😐 😍</p>
    
            <div class="marker">
                <div id="markerPosition" style="left: 45%;">
                    <div>▲</div>
                    <label id="markerValue">Neutral</label>
                </div>
            </div>
        </div>
    </div>    
    
  2. 接下来,将 css 样式代码添加到 wwwroot\css 目录中的 site.css 页面的末尾:

    /* Style for sentiment display */
    
    .sentiment {
        background-color: #eee;
        position: relative;
        display: inline-block;
        padding: 1rem;
        padding-bottom: 0;
        border-radius: 1rem;
    }
    
    .sentiment h4 {
        font-size: 16px;
        text-align: center;
        margin: 0;
        padding: 0;
    }
    
    .sentiment p {
        font-size: 50px;
    }
    
    .sentiment .marker {
        position: relative;
        left: 22px;
        width: calc(100% - 68px);
    }
    
    .sentiment .marker > div {
        transition: 0.3s ease-in-out;
        position: absolute;
        margin-left: -30px;
        text-align: center;
    }
    
    .sentiment .marker > div > div {
        font-size: 50px;
        line-height: 20px;
        color: green;
    }
    
    .sentiment .marker > div label {
        font-size: 30px;
        color: gray;
    }
    
  3. 然后,添加代码,将源自网页的输入发送到 OnGetAnalyzeSentiment 处理程序。

    1. 在 wwwroot\js 目录中的 site.js 文件中,创建名为 getSentiment 的函数,以便向 OnGetAnalyzeSentiment 处理程序的用户输入发出 GET HTTP 请求。

      function getSentiment(userInput) {
          return fetch(`Index?handler=AnalyzeSentiment&text=${userInput}`)
              .then((response) => {
                  return response.text();
              })
      }
      
    2. 在它的下面,添加另一个名为 updateMarker 的函数,以便在预测情绪时,动态更新网页上标记的位置。

      function updateMarker(markerPosition, sentiment) {
          $("#markerPosition").attr("style", `left:${markerPosition}%`);
          $("#markerValue").text(sentiment);
      }
      
    3. 创建一个名为 updateSentiment 的事件处理程序函数以获取用户的输入,使用 getSentiment 函数将其发送到 OnGetAnalyzeSentiment 函数,并使用 updateMarker 函数更新标记。

      function updateSentiment() {
      
          var userInput = $("#Message").val();
      
          getSentiment(userInput)
              .then((sentiment) => {
                  switch (sentiment) {
                      case "Not Toxic":
                          updateMarker(100.0, sentiment);
                          break;
                      case "Toxic":
                          updateMarker(0.0, sentiment);
                          break;
                      default:
                          updateMarker(45.0, "Neutral");
                  }    
              });
      }        
      
    4. 最后,注册事件处理程序并将其绑定到具有 id=Message 特性的 textarea 元素。

      $("#Message").on('change input paste', updateSentiment)        
      

运行此应用程序

设置应用程序之后,接下来即可运行应在浏览器中启动的应用程序。

应用程序启动时,在文本区域中输入“此模型没有足够的数据!”。 显示的预测情绪应为“正面”。

正在运行的窗口(包含预测情绪窗口)

注意

PredictionEnginePool<TData,TPrediction> 创建 PredictionEngine<TSrc,TDst> 的多个实例。 由于模型的大小,首次使用它进行预测可能需要几秒钟时间。 后续预测应该是即时的。

后续步骤

在本教程中,你将了解:

  • 创建 ASP.NET Core Razor Pages 应用程序
  • 准备和了解数据
  • 选择方案
  • 加载数据
  • 定型模型
  • 评估模型
  • 使用预测模型

其他资源

若要详细了解本教程中所述的主题,请访问以下资源: