Time Series Forecasting ML .Net

Viewed 1641

After 3/4 year into asp net, i'm trying since few weeks to learn ML.net but i'm having some trouble with forecasting time series.

Here is my main questions :

  • I would like to predict price over the 7 next days but my data is not evenly distributed, how can i force the horizon to predict over the 7 next day and not just 7 occurrences ?
  • Can i predict all 3 values ( unit price , price pack 10, price pack 100) in the same engine ?
  • Each items getting their own "life"( the price of one item may go down while the other goes up) do i need to create a model for each item ?
  • Even if my dataset is not big enough for now how can i get a beter prediction from these data ( result of the prediction at the end of post) ?

My final goal is to send to my ML core an item name with his current price ( unit, pack 10 ,pack 100) then the core predict an optimal sell price and date. Then with simple math i can choose to buy or not.

Here is all my process to build the model for times series prediction.

First, loading data.

        string queryThisWeek = "SELECT * from Ressource where ressource ='" + ressourceToHandle.Ressource + "' and Date >= '" + startCurrentWeek + "' order by Date desc";
        string queryBeforeThisWeek = "SELECT * from Ressource where ressource ='" + ressourceToHandle.Ressource + "' and Date < '" + startCurrentWeek + "' order by Date desc";
        var connection = new SqliteConnection(ConnectionString);
        var factory = DbProviderFactories.GetFactory(connection);
        DatabaseSource dbSourceThisWeek = new DatabaseSource(factory, ConnectionString, queryThisWeek);
        DatabaseSource dbSourceBeforeThisWeek = new DatabaseSource(factory, ConnectionString, queryBeforeThisWeek);
        IDataView dataViewThisWeek = loader.Load(dbSourceThisWeek);
        IDataView dataViewBeforeThisWeek = loader.Load(dbSourceBeforeThisWeek);

Maybe i should select more data from the past ? Yes my database is not big enough yet ( maybe 40-65 records per item from past 4 days) but each day i'm getting more data

Then i create 3 pipelines ( one for each type of Price ( Price of a unit , price of pack X10, price pack X100 )) :

                forecastPipeline = mlContext.Forecasting.ForecastBySsa(
                                                        outputColumnName: "PriceForecasted",
                                                        inputColumnName: "Prix1",
                                                        windowSize: 7,
                                                        seriesLength: 30,
                                                        trainSize: 365,
                                                        horizon: 7,
                                                        confidenceLevel: 0.95f,
                                                        confidenceLowerBoundColumn: "LowerBoundPrice",
                                                        confidenceUpperBoundColumn: "UpperBoundPrice");

Is my setting correct here for my needs ?

Evaluate my 3 prediction for each prices:

        actual = mlContext.Data.CreateEnumerable<Ressources>(testData, true)
                            .Select(observed => observed.Prix1);
        forecast = mlContext.Data.CreateEnumerable<RessourceLot1Prediction>(predictions, true)
                .Select(prediction => prediction.PriceForecasted[0]);

        // Calculate error (actual - forecast)
        var metrics = actual.Zip(forecast, (actualValue, forecastValue) => actualValue - forecastValue);

        // Get metric averages
        var MAE = metrics.Average(error => Math.Abs(error)); // Mean Absolute Error
        var RMSE = Math.Sqrt(metrics.Average(error => Math.Pow(error, 2))); // Root Mean Squared Error

Creating my 3 engines for each prices i want to predict :

  var forecastEngineLot1 = forecaster.CreateTimeSeriesEngine<Ressources, RessourceLot1Prediction>(core.mlContext);
  forecastEngineLot1.CheckPoint(core.mlContext, modelPath);

Finally i predict my 3 prices :

            IEnumerable<string> forecastOutput =
            mlContext.Data.CreateEnumerable<Ressources>(testData, reuseRowObject: false)
                .Take(horizon)
                .Select((Ressources ress, int index) =>
                {
                    string Date = ress.Date.ToString("dd-MM-yyyy hh:mm");
                    float actualPrice = ress.Prix1;
                    float lowerEstimate = Math.Max(0, forecast.LowerBoundPrice[index]);
                    float estimate = forecast.PriceForecasted[index];
                    float upperEstimate = forecast.UpperBoundPrice[index];
                    return $"Date: {Date}\n" +
                    $"Actual price: {actualPrice}\n" +
                    $"Lower Estimate: {lowerEstimate}\n" +
                    $"Forecast: {estimate}\n" +
                    $"Upper Estimate: {upperEstimate}\n";
                });

I have these data:

  • Item Name
  • Unit Price
  • Price of pack X10
  • Price of pack X100
  • Average Price
  • Datetime when price captured

Here is my result and my dataset : enter image description here

Class used :

public class Ressources
{
    [LoadColumn(0)]
    public string Ressource { get; set; }
    [LoadColumn(1)]
    public float Price1 { get; set; }
    [LoadColumn(2)]
    public float Price10 { get; set; }
    [LoadColumn(3)]
    public float Price100 { get; set; }
    [LoadColumn(4)]
    public float PriceAverage { get; set; }
    [LoadColumn(5)]
    public DateTime Date { get; set; }
}

public class RessourceLot1Prediction
{
    public float[] PriceForecasted { get; set; }

    public float[] LowerBoundPrice { get; set; }

    public float[] UpperBoundPrice { get; set; }
}

public class RessourceLot10Prediction
{
    public float[] PriceForecasted { get; set; }

    public float[] LowerBoundPrice { get; set; }

    public float[] UpperBoundPrice { get; set; }
}

public class RessourceLot100Prediction
{
    public float[] PriceForecasted { get; set; }

    public float[] LowerBoundPrice { get; set; }

    public float[] UpperBoundPrice { get; set; }
}
0 Answers
Related