将时序模型与PredictionEnginePool(ML.NET)配合使用时,PredictionEngineBase中的异常

时间:2019-11-06 02:13:54

标签: c# machine-learning 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");

其中itemsIEnumerable<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));

其中itemsIEnumerable<FooInput>

这将导致ArgumentOutOfRangeException被抛出到PredictionEngineBase.TransformerChecker中:

  

必须是行到行映射器(参数'transformer')

调试代码,我可以看到IsRowToRowMapper对象上的ITransformer是否为真。但是,在创建模型时,会创建一个SsaForecastingTransformer并将此属性设置为false。

我做错什么了吗?还是PredictionEnginePool不支持时间序列模型?

我也尝试过使用AddPredictionEnginePool<IEnumerable<FooInput>, FooPrediction>,然后调用predictionEnginePool.Predict(items),但这也会导致相同的异常。

1 个答案:

答案 0 :(得分:2)

此代码是在我的时间之后添加的,因此我没有第一手知识。

但是,据我所知,ML.NET的答案是肯定的:PredictionEnginePool很可能不支持时间序列预测。

原因是,时间序列预测引擎实际上是一个“状态机”。您需要将 all 数据(以正确的顺序 )馈送到一个预测引擎,以使其正确响应此“时间序列”

预测引擎池正在解决一个完全不同的场景:如果您具有真正的无状态模型,则可以实例化少数几个可互换的预测引擎实例(一个池),并且将使用当前免费的任何引擎来处理预测。< / p>

这些“无状态”模型由代码库中的“行到行映射器”概念表示。基本上,该模型的预测是完全根据一行数据确定的。