折腾笔记[37]-使用ML.NET进行文本情感分类
摘要
使用.NET框架的ML.NET深度学习框架训练数据集并进行文本情感分类.
关键信息
- .net8
原理简介
ML.NET简介
[https://www.nuget.org/packages?page=2&q=Microsoft.ML&sortBy=relevance]
[https://learn.microsoft.com/zh-cn/dotnet/machine-learning/]
[https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.ml.torchsharp?view=ml-dotnet]
[https://github.com/dotnet/TorchSharp]
ML.NET is a cross-platform open-source machine learning framework which makes machine learning accessible to .NET developers.
ML.NET 是面向 .NET 开发人员的开源跨平台机器学习框架,支持将自定义机器学习模型集成到 .NET 应用程序中。 它包含一个 API,其中包含不同的 NuGet 包、名为 模型生成器的 Visual Studio 扩展,以及作为 .NET 工具安装的 命令行接口。
- ML.NET 包:
- Microsoft.ML
- Microsoft.ML.AutoML
- Microsoft.ML.Probabilistic
- Microsoft.ML.Tokenizers
- 许多其他包
- Visual Studio 扩展:
- 适用于 Visual Studio 的 Model Builder 扩展
ML.NET CLI 自动为 .NET 开发人员生成模型。
若要单独使用 ML.NET API(无需 ML.NET AutoML CLI),需要选择训练器(针对特定任务的机器学习算法实现),以及应用于数据的数据转换(特征工程)集。 每个数据集的最佳管道将有所不同,并从所有选项中选择最佳算法会增加复杂性。 更进一步,每个算法都有一组要优化的超参数。 因此,你可以花费数周和有时几个月的时间进行机器学习模型优化,试图找到特征工程、学习算法和超参数的最佳组合。
sentiment数据集简介
[https://huggingface.co/datasets/dejanseo/sentiment]
本数据集包含13,650个文本样本,每个样本由llama-3-8b-Instruct-bnb-4bit模型生成,并关联一个从'非常积极'到'非常消极'的情感标签。数据存储在CSV文件中,包含'文本'和'情感标签'两个列,情感标签从0到6,分别代表不同的情感级别。
文本情感分类简介
[https://zh.gluon.ai/chapter_natural-language-processing/sentiment-analysis-rnn.html]
文本分类是自然语言处理的一个常见任务,它把一段不定长的文本序列变换为文本的类别。本节关注它的一个子问题:使用文本情感分类来分析文本作者的情绪。这个问题也叫情感分析(sentiment analysis),并有着广泛的应用。例如,我们可以分析用户对产品的评论并统计用户的满意度,或者分析用户对市场行情的情绪并用以预测接下来的行情。
同求近义词和类比词一样,文本分类也属于词嵌入的下游应用。应用预训练的词向量和含多个隐藏层的双向循环神经网络,来判断一段不定长的文本序列中包含的是正面还是负面的情绪。
实现
1. 获取数据集
[https://huggingface.co/datasets/dejanseo/sentiment/blob/main/data.csv]
csv文件容易解析错误
使用sentiment.xml文件(WPS打开csv文件->另存为->导出为xml文件)
转换完成的数据集: [https://bafybeifvlr3kkxkodmlieise4hlsbubuwo6isyfabvbttpxbna7ogkvmpa.pinme.dev/sentiment.xml]
2. 构建工程
命令:
dotnet new console
cd ./
dotnet add package Microsoft.ML
dotnet add package Microsoft.ML.FastTree
# 添加 sentiment.xml 文件到工程目录
dotnet run
// 文件: Program.cs
// 功能: 7-class 情感分类,数据源改为 sentiment.xml
#nullable disable
using Microsoft.ML;
using Microsoft.ML.Data;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
public class SentimentData
{
public int Label { get; set; } // 0-6
public string Text { get; set; } // 原文本
}
public class SentimentPrediction
{
[ColumnName("PredictedLabel")]
public int PredictedLabel { get; set; }
public float[] Score { get; set; }
}
class Program
{
static void Main()
{
const string xmlFile = "sentiment.xml";
var ml = new MLContext();
// 1. 从 XML 中解析出 List<SentimentData>
var samples = ParseXml(xmlFile);
// 2. List -> IDataView
var data = ml.Data.LoadFromEnumerable(samples);
// 3. 训练 / 评估拆分
var split = ml.Data.TrainTestSplit(data, testFraction: 0.2);
var trainData = split.TrainSet;
var testData = split.TestSet;
// 4. 管道:文本→特征→One-vs-Rest(FastTree)
var pipeline =
ml.Transforms.Text.FeaturizeText("Features", nameof(SentimentData.Text))
.Append(ml.Transforms.Conversion.MapValueToKey("Label"))
.Append(ml.MulticlassClassification.Trainers
.OneVersusAll(ml.BinaryClassification.Trainers.FastTree()))
.Append(ml.Transforms.Conversion.MapKeyToValue("PredictedLabel"));
// 5. 训练
var model = pipeline.Fit(trainData);
// 6. 评估
var metrics = ml.MulticlassClassification.Evaluate(model.Transform(testData));
Console.WriteLine($"MacroAcc: {metrics.MacroAccuracy:P2}");
// 7. 单次预测
var predEngine = ml.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(model);
var sample = new SentimentData { Text = "Today is a great day!" };
var pred = predEngine.Predict(sample);
Console.WriteLine($"Text: {sample.Text}");
Console.WriteLine($"Predicted label: {pred.PredictedLabel}");
}
// 解析 XML 的核心函数
private static List<SentimentData> ParseXml(string path)
{
XNamespace ns = "urn:schemas-microsoft-com:office:spreadsheet";
return XDocument.Load(path)
.Descendants(ns + "Worksheet")
.Where(ws => (string)ws.Attribute(ns + "Name") == "sentiment")
.Descendants(ns + "Row")
.Skip(1) // 跳过表头
.Select(row => row.Elements(ns + "Cell").ToArray())
.Where(cells => cells.Length >= 2) // 至少两列
.Select(cells =>
{
var text = cells[0].Elements(ns + "Data")
.FirstOrDefault()?.Value;
var rawLabel = cells[1].Elements(ns + "Data")
.FirstOrDefault()?.Value;
bool ok = int.TryParse(rawLabel, out int label);
return (ok, label, text);
})
.Where(x => x.ok && !string.IsNullOrWhiteSpace(x.text))
.Select(x => new SentimentData
{
Label = x.label,
Text = x.text
})
.ToList();
}
}
3. 运行效果
MacroAcc: 57.62%
Text: Today is a great day!
Predicted label: 2

使用.NET框架的ML.NET深度学习框架训练数据集并进行文本情感分类.
浙公网安备 33010602011771号