将时间序列模型与 PredictionEnginePool 一起使用时 PredictionEngineBase 出现异常 (ML.NET)
Exception in PredictionEngineBase when using Time Series model with PredictionEnginePool (ML.NET)
我使用 here 中描述的方法创建了时间序列模型,生成了以下代码:
var data = items.ToArray();
var trainData = mlContext.Data.LoadFromEnumerable(data);
var estimator = mlContext.Forecasting.ForecastBySsa(
nameof(FooPrediction.BarPrediction),
nameof(FooInput.Bar),
12,
data.Length,
data.Length,
2,
confidenceLowerBoundColumn: nameof(FooPrediction.ConfidenceLowerBound),
confidenceUpperBoundColumn: nameof(FooPrediction.ConfidenceUpperBound));
var transformer = estimator.Fit(trainData);
using var engine = transformer.CreateTimeSeriesEngine<FooInput, FooPrediction>(mlContext);
engine.CheckPoint(mlContext, "model.zip");
其中 items
是 IEnumerable<FooInput>
。这些是我的模型 类:
public class FooPrediction
{
public float[] BarPrediction { get; set; }
public float[] ConfidenceLowerBound { get; set; }
public float[] ConfidenceUpperBound { get; set; }
}
public class FooInput
{
public float Bar { get; set; }
public float Baz { get; set; }
}
在我的 Startup
中,我添加了一个 PredictionEnginePool
这样:
services.AddPredictionEnginePool<FooInput, FooPrediction>().FromFile(String.Empty, "model.zip", true);
在我的中间件服务中,我注入 PredictionEnginePool
然后调用:
var prediction = items.Select(i => predictionEnginePool.Predict(i));
其中 items
是 IEnumerable<FooInput>
。
这导致 ArgumentOutOfRangeException
被抛出 PredictionEngineBase.TransformerChecker
:
Must be a row to row mapper (Parameter 'transformer')
调试代码,我可以看到检查 ITransformer
对象上的 IsRowToRowMapper
是否为真。但是,在创建模型时,会创建一个 SsaForecastingTransformer
,其中 属性 设置为 false。
是我做错了什么,还是 PredictionEnginePool
不支持时间序列模型?
我也用 AddPredictionEnginePool<IEnumerable<FooInput>, FooPrediction>
尝试过,然后调用 predictionEnginePool.Predict(items)
,但这也会导致相同的异常。
这段代码是我的时间后添加的,所以我没有第一手知识。
但是,据我所知ML.NET,答案是肯定的:很可能,PredictionEnginePool
不支持时间序列预测。
原因是,时间序列预测引擎实际上是一个'state machine'。您需要将 所有 数据 以正确的顺序 提供给 one 预测引擎,以便它对此做出正确反应 'time series'.
预测引擎池正在解决一个完全不同的场景:如果你有真正的无状态模型,你可以实例化一些预测引擎的可互换实例(一个池),并且预测将由当前空闲的任何引擎处理.
这些 'stateless' 模型在代码库中由 'row to row mapper' 概念表示。基本上,这个模型的预测是排他性的,而且是唯一地根据 一行数据 确定的。
我使用 here 中描述的方法创建了时间序列模型,生成了以下代码:
var data = items.ToArray();
var trainData = mlContext.Data.LoadFromEnumerable(data);
var estimator = mlContext.Forecasting.ForecastBySsa(
nameof(FooPrediction.BarPrediction),
nameof(FooInput.Bar),
12,
data.Length,
data.Length,
2,
confidenceLowerBoundColumn: nameof(FooPrediction.ConfidenceLowerBound),
confidenceUpperBoundColumn: nameof(FooPrediction.ConfidenceUpperBound));
var transformer = estimator.Fit(trainData);
using var engine = transformer.CreateTimeSeriesEngine<FooInput, FooPrediction>(mlContext);
engine.CheckPoint(mlContext, "model.zip");
其中 items
是 IEnumerable<FooInput>
。这些是我的模型 类:
public class FooPrediction
{
public float[] BarPrediction { get; set; }
public float[] ConfidenceLowerBound { get; set; }
public float[] ConfidenceUpperBound { get; set; }
}
public class FooInput
{
public float Bar { get; set; }
public float Baz { get; set; }
}
在我的 Startup
中,我添加了一个 PredictionEnginePool
这样:
services.AddPredictionEnginePool<FooInput, FooPrediction>().FromFile(String.Empty, "model.zip", true);
在我的中间件服务中,我注入 PredictionEnginePool
然后调用:
var prediction = items.Select(i => predictionEnginePool.Predict(i));
其中 items
是 IEnumerable<FooInput>
。
这导致 ArgumentOutOfRangeException
被抛出 PredictionEngineBase.TransformerChecker
:
Must be a row to row mapper (Parameter 'transformer')
调试代码,我可以看到检查 ITransformer
对象上的 IsRowToRowMapper
是否为真。但是,在创建模型时,会创建一个 SsaForecastingTransformer
,其中 属性 设置为 false。
是我做错了什么,还是 PredictionEnginePool
不支持时间序列模型?
我也用 AddPredictionEnginePool<IEnumerable<FooInput>, FooPrediction>
尝试过,然后调用 predictionEnginePool.Predict(items)
,但这也会导致相同的异常。
这段代码是我的时间后添加的,所以我没有第一手知识。
但是,据我所知ML.NET,答案是肯定的:很可能,PredictionEnginePool
不支持时间序列预测。
原因是,时间序列预测引擎实际上是一个'state machine'。您需要将 所有 数据 以正确的顺序 提供给 one 预测引擎,以便它对此做出正确反应 'time series'.
预测引擎池正在解决一个完全不同的场景:如果你有真正的无状态模型,你可以实例化一些预测引擎的可互换实例(一个池),并且预测将由当前空闲的任何引擎处理.
这些 'stateless' 模型在代码库中由 'row to row mapper' 概念表示。基本上,这个模型的预测是排他性的,而且是唯一地根据 一行数据 确定的。