static readonly string _dataPath = Path.Combine(Environment.CurrentDirectory, "Data", "yelp_labelled.txt");
public static TrainTestData LoadData(MLContext mlContext) { // 从文件加载训练数据 IDataView dataView = mlContext.Data.LoadFromTextFile<SentimentData>(_dataPath, hasHeader: false); // 将加载的数据集拆分为训练集和测试集 TrainTestData splitDataView = mlContext.Data.TrainTestSplit(dataView, testFraction: 0.2); // 返回拆分后的数据集 return splitDataView; }
将数据集 dataView 分割成训练集和测试集。在机器学习中,为了评估模型的性能和泛化能力,通常会将数据集分成训练集和测试集。训练集用于训练模型,而测试集用于评估模型在未见过的数据上的性能。TrainTestSplit 方法是 ML.NET 提供的一个便捷方法,用于将数据集分割成训练集和测试集。在这个方法中,dataView 是要分割的数据集,testFraction 是测试集所占的比例,通常是一个小于1的浮点数,表示测试集占整个数据集的比例。在这个例子中,testFraction 设置为 0.2,表示测试集占数据集的 20%。TrainTestData 是一个包含训练集和测试集的对象,通过 splitDataView 变量来接收。可以使用 splitDataView.TrainSet 获取训练集的 IDataView 对象,使用 splitDataView.TestSet 获取测试集的 IDataView 对象。通过将数据集分割成训练集和测试集,可以在训练模型时使用训练集进行参数优化和模型训练,然后使用测试集评估模型的性能和泛化能力,从而帮助选择最佳的模型和参数设置。构建和训练模型public static ITransformer BuildAndTrainModel(MLContext mlContext, IDataView splitTrainSet){ // 创建一个灵活的管道,用于创建/训练模型 // 这个管道由一系列的估计器组成,用于格式化和清理数据 // 将文本列转换为数值向量(Features列) var estimator = mlContext.Transforms.Text .FeaturizeText(outputColumnName: "Features", inputColumnName: nameof(SentimentData.SentimentText)) // 将机器学习任务添加到估计器中 .Append(mlContext.BinaryClassification .Trainers.SdcaLogisticRegression(labelColumnName: "Label", featureColumnName: "Features")); // 创建并训练基于加载和转换后的数据集的模型 Console.WriteLine("=============== Create and Train the Model ==============="); var model = estimator.Fit(splitTrainSet); Console.WriteLine("=============== End of training ==============="); Console.WriteLine(); // 返回训练好的模型 return model;}
使用mlContext.Transforms.Text.FeaturizeText方法来将文本数据转换为特征向量。这个方法将输入的文本列(SentimentData.SentimentText)转换为一个名为"Features"的新列,其中包含了表示文本特征的向量。接下来,使用.Append方法将二元分类任务添加到估计器中。这里使用的是mlContext.BinaryClassification.Trainers.SdcaLogisticRegression,它是一种基于随机坐标下降(Stochastic Dual Coordinate Ascent)的逻辑回归分类器。在这个分类器中,labelColumnName参数指定了用于训练的标签列,这里是"Label"列,用于表示情绪类别(正面或负面)。featureColumnName参数指定了用于训练的特征列,这里是之前生成的"Features"列,其中包含了文本的特征向量。通过这个估计器,可以训练一个二元情绪分类器模型,该模型可以将文本数据进行情绪分类预测。评估模型public static void Evaluate(MLContext mlContext, ITransformer model, IDataView splitTestSet){ // 对模型进行评估并显示准确性统计信息 Console.WriteLine("=============== Evaluating Model accuracy with Test data==============="); IDataView predictions = model.Transform(splitTestSet); // 使用BinaryClassificationContext.Evaluate方法计算模型的整体指标 CalibratedBinaryClassificationMetrics metrics = mlContext.BinaryClassification.Evaluate(predictions, "Label"); // Accuracy指标表示测试集中正确预测的比例 // AreaUnderROCCurve指标表示模型对于随机选择的正样本高于随机选择的负样本的概率(假设“正”高于“负”) // F1Score指标表示模型的F1分数,F1分数是精确度和召回率的调和平均值 Console.WriteLine(); Console.WriteLine("Model quality metrics evaluation"); Console.WriteLine("--------------------------------"); Console.WriteLine($"Accuracy: {metrics.Accuracy:P2}"); Console.WriteLine($"Auc: {metrics.AreaUnderRocCurve:P2}"); Console.WriteLine($"F1Score: {metrics.F1Score:P2}"); Console.WriteLine("=============== End of model evaluation ===============");}
mlContext.BinaryClassification.Evaluate方法用于评估模型的性能。它接受两个参数:predictions和"Label"。predictions是一个包含模型对测试集进行预测的结果的IDataView对象。这些预测结果包括预测的情绪类别以及模型对每个样本的置信度。"Label"是测试集中用于评估的真实情绪类别的列名。这个参数告诉评估器在哪个列中查找真实的情绪类别。评估结果被存储在CalibratedBinaryClassificationMetrics对象中,通过metrics变量进行接收。这个对象包含了许多用于评估二元分类模型性能的指标,例如准确率、召回率、F1分数、AUC等。可以使用这些指标来判断模型的性能和泛化能力。通过这行代码,可以计算出模型在测试集上的性能指标,并将结果存储在metrics对象中,以便进一步分析和比较不同模型的性能。使用单个项进行预测private static void UseModelWithSingleItem(MLContext mlContext, ITransformer model){ // 创建一个预测引擎,用于进行情感预测 PredictionEngine<SentimentData, SentimentPrediction> predictionFunction = mlContext.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(model); // 创建一个用于测试的样本数据 SentimentData sampleStatement = new SentimentData { SentimentText = "This was a very bad steak" }; // 使用预测引擎对样本进行情感预测 var resultPrediction = predictionFunction.Predict(sampleStatement); // 打印预测结果 Console.WriteLine(); Console.WriteLine("=============== Prediction Test of model with a single sample and test dataset ==============="); Console.WriteLine(); Console.WriteLine($"Sentiment: {resultPrediction.SentimentText} | Prediction: {(Convert.ToBoolean(resultPrediction.Prediction) ? "Positive" : "Negative")} | Probability: {resultPrediction.Probability} "); Console.WriteLine("=============== End of Predictions ==============="); Console.WriteLine();}
mlContext.Model.CreatePredictionEngine方法用于创建一个预测引擎,它接受两个参数:SentimentData和SentimentPrediction。SentimentData是输入数据的类型,用于表示待预测的情绪文本数据。SentimentPrediction是输出数据的类型,用于表示预测结果,即情绪分类的预测。model是经过训练的情绪分类模型。这个模型将用于进行预测。通过这行代码,可以创建一个预测引擎,该引擎可以接受SentimentData类型的输入数据,并返回SentimentPrediction类型的预测结果。预测引擎可以使用训练好的模型对新的情绪文本数据进行预测,并返回预测的情绪分类结果。使用批量项进行预测public static void UseModelWithBatchItems(MLContext mlContext, ITransformer model){ // 创建一组用于测试的样本数据 IEnumerable<SentimentData> sentiments = new[] { new SentimentData { SentimentText = "This was a horrible meal" }, new SentimentData { SentimentText = "I love this spaghetti." } }; // 加载刚刚创建的批量评论数据 IDataView batchComments = mlContext.Data.LoadFromEnumerable(sentiments); // 使用模型对评论数据进行预测 IDataView predictions = model.Transform(batchComments); // 将预测结果转换为可枚举集合 IEnumerable<SentimentPrediction> predictedResults = mlContext.Data.CreateEnumerable<SentimentPrediction>(predictions, reuseRowObject: false); // 打印预测结果 Console.WriteLine(); Console.WriteLine("=============== Prediction Test of loaded model with multiple samples ==============="); Console.WriteLine(); foreach (SentimentPrediction prediction in predictedResults) { Console.WriteLine($"Sentiment: {prediction.SentimentText} | Prediction: {(Convert.ToBoolean(prediction.Prediction) ? "Positive" : "Negative")} | Probability: {prediction.Probability} "); } Console.WriteLine("=============== End of predictions ===============");}
主程序入口static void Main(string[] args){ // 创建ML.NET上下文/本地环境 - 允许您添加步骤以保持所有内容的完整性 // 当您发现ML.NET的训练器和转换时 MLContext mlContext = new MLContext(); // 加载数据 TrainTestData splitDataView = LoadData(mlContext); // 构建和训练模型 ITransformer model = BuildAndTrainModel(mlContext, splitDataView.TrainSet); // 评估模型 Evaluate(mlContext, model, splitDataView.TestSet); // 使用单个项进行预测 UseModelWithSingleItem(mlContext, model); // 使用批量项进行预测 UseModelWithBatchItems(mlContext, model); Console.WriteLine(); Console.WriteLine("=============== End of process ===============");}
(图片来源网络,侵删)
0 评论