因为任何ML.NET模型都是一个转换器,所以您当然可以使用model.Transform
将该模型应用于“数据视图”并以这种方式获得预测。
不过,更典型的情况是,没有我们想要预测的“数据集”,而是一次只接收一个样本。例如,我们将模型作为ASP.NET网站的一部分运行,并且需要对传入的HTTP请求进行预测。
对于这种情况,ML.NET提供了一个方便的PredictionEngine
组件,它基本上是通过预测管道一次运行一个样本。
下面是完整的例子。假设我们为著名的Iris预测数据集建立了一个模型:
// 第一步:将数据加载为IDataView。// 检索训练数据。
var trainData = mlContext.Data.LoadFromTextFile<IrisInput>(irisDataPath,// 默认分隔符是tab,但数据集使用逗号。separatorChar: ','
);// 创建训练管道。
var pipeline =// 将所有特征串联到一列“Features”中。mlContext.Transforms.Concatenate("Features", "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")// 请注意,标签是文本,因此需要将其转换为键。.Append(mlContext.Transforms.Categorical.MapValueToKey("Label"), TransformerScope.TrainTest)// 在缓存检查点阶段之后的步骤中,将数据缓存在内存中。.AppendCacheCheckpoint(mlContext)// 使用多类SDCA模型预测标签。.Append(mlContext.MulticlassClassification.Trainers.SdcaMaximumEntropy())// 应用从“PredictedLabel”列到字符串值的逆转换。.Append(mlContext.Transforms.Conversion.MapKeyToValue("Data", "PredictedLabel"));// 训练模型。
var model = pipeline.Fit(trainData);
现在,为了使用模式理解[1]进行预测,我们定义了一对类,如下所示:
private class IrisInput
{// 不幸的是,我们仍然需要虚拟的“Label”列。[ColumnName("Label")]public string IgnoredLabel { get; set; }public float SepalLength { get; set; }public float SepalWidth { get; set; }public float PetalLength { get; set; }public float PetalWidth { get; set; }
}private class IrisPrediction
{[ColumnName("Data")]public string PredictedClass { get; set; }
}
预测代码如下所示:
// 使用该模型进行一次性预测。
// 使预测函数成为对象。请注意,平均而言,此调用所花费的时间比一个预测长200倍左右,因此您可能希望缓存和重用预测函数,而不是为每个预测创建一个。
var predictionFunc = mlContext.Model.CreatePredictionEngine<IrisInput, IrisPrediction>(model);// 获得预测。 请记住,“预测”不是可重入的。 如果要使用多个线程进行同时预测,请确保每个线程都使用自己的PredictionEngine。
var prediction = predictionFunc.Predict(new IrisInput
{SepalLength = 4.1f,SepalWidth = 0.1f,PetalLength = 3.2f,PetalWidth = 1.4f
});
欢迎关注我的个人公众号”My IO“参考资料
[1]
模式理解: https://github.com/dotnet/machinelearning/blob/main/docs/code/SchemaComprehension.md