训练和评估模型
了解如何使用 ML.NET 生成机器学习模型、收集指标和度量性能。 虽然此示例训练回归模型,但概念在整个其他大多数算法中都适用。
拆分用于训练和测试的数据
机器学习模型的目标是识别训练数据中的模式。 这些模式用于使用新数据进行预测。
数据可由类(如 HousingData
)建模。
public class HousingData
{
[LoadColumn(0)]
public float Size { get; set; }
[LoadColumn(1, 3)]
[VectorType(3)]
public float[] HistoricalPrices { get; set; }
[LoadColumn(4)]
[ColumnName("Label")]
public float CurrentPrice { get; set; }
}
提供加载到 IDataView
中的以下数据。
HousingData[] housingData = new HousingData[]
{
new HousingData
{
Size = 600f,
HistoricalPrices = new float[] { 100000f ,125000f ,122000f },
CurrentPrice = 170000f
},
new HousingData
{
Size = 1000f,
HistoricalPrices = new float[] { 200000f, 250000f, 230000f },
CurrentPrice = 225000f
},
new HousingData
{
Size = 1000f,
HistoricalPrices = new float[] { 126000f, 130000f, 200000f },
CurrentPrice = 195000f
},
new HousingData
{
Size = 850f,
HistoricalPrices = new float[] { 150000f,175000f,210000f },
CurrentPrice = 205000f
},
new HousingData
{
Size = 900f,
HistoricalPrices = new float[] { 155000f, 190000f, 220000f },
CurrentPrice = 210000f
},
new HousingData
{
Size = 550f,
HistoricalPrices = new float[] { 99000f, 98000f, 130000f },
CurrentPrice = 180000f
}
};
使用 TrainTestSplit
方法将数据拆分为训练集和测试集。 结果是一个 TrainTestData
对象,其中包含两个 IDataView
成员,一个用于训练集,另一个用于测试集。 数据拆分百分比由 testFraction
参数确定。 以下代码片段保留测试集的 20% 的原始数据。
DataOperationsCatalog.TrainTestData dataSplit = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);
IDataView trainData = dataSplit.TrainSet;
IDataView testData = dataSplit.TestSet;
准备数据
在训练机器学习模型之前,需要预处理数据。 有关数据准备的详细信息,请参阅 数据准备操作方法文章 和 transforms page
。
ML.NET 算法对输入列类型具有约束。 此外,如果未指定任何值,则默认值用于输入和输出列名称。
使用预期的列类型
ML.NET 中的机器学习算法需要一个已知大小的浮点向量作为输入。 当所有数据都已采用数字格式且旨在同时处理(即图像像素)时,请将 VectorType
属性应用于数据模型。
如果数据不是所有数值,并且你想要单独对每个列应用不同的数据转换,则在处理完所有列后,请使用 Concatenate
方法将所有单独的列合并到输出到新列的单个特征向量中。
以下代码片段将 Size
列和 HistoricalPrices
列合并为单个特征向量,该向量输出到名为 Features
的新列。 由于缩放比例的不同,因此将 NormalizeMinMax
应用于 Features
列,以实现数据的标准化。
// Define Data Prep Estimator
// 1. Concatenate Size and Historical into a single feature vector output to a new column called Features
// 2. Normalize Features vector
IEstimator<ITransformer> dataPrepEstimator =
mlContext.Transforms.Concatenate("Features", "Size", "HistoricalPrices")
.Append(mlContext.Transforms.NormalizeMinMax("Features"));
// Create data prep transformer
ITransformer dataPrepTransformer = dataPrepEstimator.Fit(trainData);
// Apply transforms to training data
IDataView transformedTrainingData = dataPrepTransformer.Transform(trainData);
使用默认列名
ML.NET 算法在未指定列名时使用默认列名。 所有训练程序都有一个用于算法输入的参数,称为 featureColumnName
;如果适用,它们也有一个用于预期值的参数,称为 labelColumnName
。 默认情况下,这些值分别 Features
和 Label
。
通过在预处理过程中使用 Concatenate
方法创建名为 Features
的新列,无需在算法的参数中指定特征列名称,因为它已存在于预处理 IDataView
中。 标签列 CurrentPrice
,但由于数据模型中使用了 ColumnName
属性,ML.NET 将 CurrentPrice
列重命名为 Label
,这样就不需要向机器学习算法估算器提供 labelColumnName
参数。
如果不想使用默认列名,可以在定义机器学习估算器时,将特征和标签列的名称作为参数传入,如后续代码片段所示:
var UserDefinedColumnSdcaEstimator = mlContext.Regression.Trainers.Sdca(labelColumnName: "MyLabelColumnName", featureColumnName: "MyFeatureColumnName");
缓存数据
默认情况下,处理数据时,数据会延迟加载或流式传输,这意味着训练器可能会从磁盘加载数据,并在训练期间多次循环访问数据。 因此,对于适合内存的数据集,建议缓存以减少从磁盘加载数据的次数。 缓存使用 AppendCacheCheckpoint
作为 EstimatorChain
的一部分来完成。
建议在任何训练程序处于管道中之前,使用 AppendCacheCheckpoint
。
使用以下 EstimatorChain
,在 训练程序之前添加 StochasticDualCoordinateAscent
AppendCacheCheckpoint
可缓存以前估算器的结果以供训练程序以后使用。
// 1. Concatenate Size and Historical into a single feature vector output to a new column called Features
// 2. Normalize Features vector
// 3. Cache prepared data
// 4. Use Sdca trainer to train the model
IEstimator<ITransformer> dataPrepEstimator =
mlContext.Transforms.Concatenate("Features", "Size", "HistoricalPrices")
.Append(mlContext.Transforms.NormalizeMinMax("Features"))
.AppendCacheCheckpoint(mlContext);
.Append(mlContext.Regression.Trainers.Sdca());
训练机器学习模型
预处理数据后,使用 Fit
方法通过 StochasticDualCoordinateAscent
回归算法训练机器学习模型。
// Define StochasticDualCoordinateAscent regression algorithm estimator
var sdcaEstimator = mlContext.Regression.Trainers.Sdca();
// Build machine learning model
var trainedModel = sdcaEstimator.Fit(transformedTrainingData);
提取模型参数
训练模型后,提取已学习的 ModelParameters
用于检查或重新训练。 LinearRegressionModelParameters
提供经过训练的模型的偏差和已学习的系数或权重。
var trainedModelParameters = trainedModel.Model as LinearRegressionModelParameters;
注意
其他模型具有特定于其任务的参数。 例如,K-Means 算法 基于质心将数据放入聚类中,KMeansModelParameters
是一个包含存储这些学习到的质心属性的对象。 若要了解详细信息,请访问 Microsoft.ML.Trainers
API 文档 并查找名称中包含 ModelParameters
的类。
评估模型质量
为了帮助选择性能最佳的模型,必须评估其测试数据的性能。 使用 Evaluate
方法测量训练模型的各种指标。
注意
Evaluate
方法根据执行了哪些机器学习任务生成不同的指标。 有关更多详细信息,请访问 Microsoft.ML.Data
API 文档,并查找名称中包含 Metrics
的类。
// Measure trained model performance
// Apply data prep transformer to test data
IDataView transformedTestData = dataPrepTransformer.Transform(testData);
// Use trained model to make inferences on test data
IDataView testDataPredictions = trainedModel.Transform(transformedTestData);
// Extract model metrics and get RSquared
RegressionMetrics trainedModelMetrics = mlContext.Regression.Evaluate(testDataPredictions);
double rSquared = trainedModelMetrics.RSquared;
在前面的代码示例中:
- 在使用以前定义的数据准备转换,对测试数据集进行预处理。
- 训练的机器学习模型用于对测试数据进行预测。
- 在
Evaluate
方法中,测试数据集CurrentPrice
列中的值与新输出预测Score
列进行比较,以计算回归模型的指标,其中一个值 R-Squared 存储在rSquared
变量中。
注意
在此小型示例中,R-Squared 不是 0-1 范围内的数字,因为数据的大小有限。 在实际方案中,应会看到介于 0 和 1 之间的值。