教程:使用 ML.NET 模型生成器在 Web 应用程序中分析网站评论的情绪
了解如何在 Web 应用程序中实时分析评论中的情绪。
本教程演示如何创建 ASP.NET Core Razor Pages 应用程序,该应用程序实时对网站评论情绪进行分类并采取适当的措施。
在本教程中,你将了解:
- 创建 ASP.NET Core Razor Pages 应用程序
- 准备和了解数据
- 选择方案
- 加载数据
- 定型模型
- 评估模型
- 使用预测模型
可以在 dotnet/machinelearning-samples 存储库中找到本教程的源代码。
先决条件
请访问模型生成器安装指南,查看先决条件和安装说明的列表。
创建 Razor Pages 应用程序
创建“ASP.NET Core Razor Pages 应用程序”。
- 在 Visual Studio 中,打开“创建新项目”对话框。
- 在“创建新项目”对话框中,选择 ASP.NET Core Web 应用项目模板。
- 在“名称”文本框中,键入“SentimentRazor”,然后选择“下一步”按钮。
- 在“其他信息”对话框中,将所有默认值保留原样,然后选择“创建”按钮。
准备和了解数据
下载维基百科 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 中所执行的所有操作,以允许你重新打开会话。
- 在“解决方案资源管理器”中,右键单击“SentimentRazor”项目,然后选择“添加”>“机器学习模型...”。
- 在对话框中,将 Model Builder 项目命名为 SentimentAnalysis.mbconfig,然后选择“添加”。
选择方案
为了训练模型,需要从模型生成器提供的可用机器学习方案列表中进行选择。
本示例的任务是文本分类。 在 Model Builder 工具的“方案”扩展中,选择“文本分类”方案。
选择环境
Model Builder 可以根据所选方案在不同的环境中训练。
选择“本地 (GPU)”作为环境,然后单击“下一步”按钮。
注意
此方案使用在 GPU 环境中最适用的深度学习技术。 如果没有 GPU,请选择“本地 (CPU)”环境,但请注意,预期的训练时间要长得多。 有关将 GPU 与 Model Builder 配合使用的详细信息,请参阅 Model Builder 中的 GPU 支持指南。
加载数据
模型生成器接受来自两个源的数据:SQL Server 数据库或者 csv
或 tsv
格式的本地文件。
- 在 Model Builder 工具的数据步骤中,选择数据源选项中的“文件”。
- 选择“选择文件”文本框旁边的按钮,并使用文件资源管理器浏览到 wikipedia-detox-250-line-data.tsv 文件,然后选择该文件 。
- 从“要预测的列(标签)”下拉列表中选择“情绪”。
- 从“文本列”下拉列表中选择“SentimentText”。
- 选择“下一步”按钮以移至 Model Builder 中的下一步。
定型模型
在本教程中,用于训练情绪分析模型的机器学习任务是文本分类。 在模型训练过程中,Model Builder 使用 NAS-BERT 神经网络体系结构为数据集训练文本分类模型。
选择“开始训练” 。
训练完成后,训练过程的结果将显示在“训练”屏幕的“训练结果”部分中。 除了提供训练结果外,还会在 SentimentAnalysis.mbconfig 文件下创建三个代码隐藏文件。
- SentimentAnalysis.consumption.cs - 此文件包含
ModelInput
和ModelOutput
架构,以及为使用模型生成的Predict
函数。 - SentimentAnalysis.training.cs - 此文件包含 Model Builder 选择的训练管道(数据转换、训练器、训练器超参数)以训练模型。 你可以使用此管道重新训练模型。
- *SentimentAnalysis.zip - 这是一个已序列化的 zip 文件,它表示经过训练的 ML.NET 模型。
- SentimentAnalysis.consumption.cs - 此文件包含
选择“下一步”按钮以移至下一步。
评估模型
训练步骤的成果将是一个模型,该模型具备最佳的性能。 在 Model Builder 工具的评估步骤中,输出部分将包含性能最佳模型使用的训练器以及评估指标。
如果对评估指标不满意,尝试提高模型性能的一个简单方法是使用更多数据。
否则,请选择“下一步”按钮,以转到 Model Builder 中的“使用”步骤。
添加使用项目模板(可选)
在“使用”步骤中,Model Builder 提供可用于使用模型的项目模板。 此步骤是可选的,你可以选择最适合你使用模型需求的方法。
- 控制台应用程序
- Web API
添加代码进行预测
配置 PredictionEngine 池
若要进行单一预测,必须创建 PredictionEngine<TSrc,TDst>。 PredictionEngine<TSrc,TDst> 不是线程安全。 此外,必须在应用程序中的每一处所需位置创建它的实例。 随着应用程序的增长,此过程可能会变得难以管理。 为了提高性能和线程安全,请结合使用依赖项注入和 PredictionEnginePool
服务,这将创建一个在整个应用程序中使用的 PredictionEngine<TSrc,TDst> 对象的 ObjectPool<T>。
安装 Microsoft.Extensions.ML NuGet 包 :
- 在“解决方案资源管理器”中,右键单击项目,然后选择“管理 NuGet 包” 。
- 选择“nuget.org”作为“包源”。
- 选择“浏览” 选项卡,搜索“Microsoft.Extensions.ML” 。
- 在列表中选择包,然后选择“安装” 按钮。
- 选择“预览更改” 对话框中的“确定” 按钮
- 如果同意所列包的许可条款,请选择“接受许可” 对话框中的“我接受” 按钮。
打开“SentimentRazor”项目中的“Program.cs”文件。
添加以下 using 语句以引用 Microsoft.Extensions.ML NuGet 包和 SentimentRazorML.Model 项目:
using Microsoft.Extensions.ML; using static SentimentRazor.SentimentAnalysis;
在 Program.cs 文件中为应用程序配置 PredictionEnginePool<TData,TPrediction>:
builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>() .FromFile("SentimentAnalysis.zip");
创建情绪分析处理程序
预测将在应用程序的主页内进行。 因此,需要添加一个采用用户输入并使用 PredictionEnginePool<TData,TPrediction> 来返回预测的方法。
打开位于 Pages 目录中的 Index.cshtml.cs 文件,并添加以下 using 语句:
using Microsoft.Extensions.ML; using static SentimentRazor.SentimentAnalysis;
要使用 Program.cs 文件中已配置的 PredictionEnginePool<TData,TPrediction>,必须将它注入到要在其中使用它的模型的构造函数中。
添加一个变量,以引用 Pages/Index.cshtml.cs 文件内的
IndexModel
类内的 PredictionEnginePool<TData,TPrediction>。private readonly PredictionEnginePool<ModelInput, ModelOutput> _predictionEnginePool;
修改
IndexModel
类中的构造函数,并将 PredictionEnginePool<TData,TPrediction> 服务注入到其中。public IndexModel(ILogger<IndexModel> logger, PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool) { _logger = logger; _predictionEnginePool = predictionEnginePool; }
创建一个方法处理程序,该处理程序使用
PredictionEnginePool
来对从网页接收的用户输入进行预测。在
OnGet
方法下面,创建一个名为OnGetAnalyzeSentiment
的新方法public IActionResult OnGetAnalyzeSentiment([FromQuery] string text) { }
在
OnGetAnalyzeSentiment
方法中,如果用户输入为空或为 null,则返回“中性”情绪 。if (String.IsNullOrEmpty(text)) return Content("Neutral");
给定有效的输入,创建新的
ModelInput
实例。var input = new ModelInput { SentimentText = text };
使用 PredictionEnginePool<TData,TPrediction> 预测情绪。
var prediction = _predictionEnginePool.Predict(input);
使用以下代码将预测的
bool
值转换为“toxic”或“not toxic”。var sentiment = Convert.ToBoolean(prediction.PredictedLabel) ? "Toxic" : "Not Toxic";
最后,将情绪返回到网页上。
return Content(sentiment);
配置网页
OnGetAnalyzeSentiment
返回的结果将在 Index
网页上动态显示。
在“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>
接下来,将 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; }
然后,添加代码,将源自网页的输入发送到
OnGetAnalyzeSentiment
处理程序。在 wwwroot\js 目录中的 site.js 文件中,创建名为
getSentiment
的函数,以便向OnGetAnalyzeSentiment
处理程序的用户输入发出 GET HTTP 请求。function getSentiment(userInput) { return fetch(`Index?handler=AnalyzeSentiment&text=${userInput}`) .then((response) => { return response.text(); }) }
在它的下面,添加另一个名为
updateMarker
的函数,以便在预测情绪时,动态更新网页上标记的位置。function updateMarker(markerPosition, sentiment) { $("#markerPosition").attr("style", `left:${markerPosition}%`); $("#markerValue").text(sentiment); }
创建一个名为
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"); } }); }
最后,注册事件处理程序并将其绑定到具有
id=Message
特性的textarea
元素。$("#Message").on('change input paste', updateSentiment)
运行此应用程序
设置应用程序之后,接下来即可运行应在浏览器中启动的应用程序。
应用程序启动时,在文本区域中输入“此模型没有足够的数据!”。 显示的预测情绪应为“正面”。
注意
PredictionEnginePool<TData,TPrediction> 创建 PredictionEngine<TSrc,TDst> 的多个实例。 由于模型的大小,首次使用它进行预测可能需要几秒钟时间。 后续预测应该是即时的。
后续步骤
在本教程中,你将了解:
- 创建 ASP.NET Core Razor Pages 应用程序
- 准备和了解数据
- 选择方案
- 加载数据
- 定型模型
- 评估模型
- 使用预测模型
其他资源
若要详细了解本教程中所述的主题,请访问以下资源: