0

Question: I have data that has light IDs and when a light of a particular ID is switched on the data is captured. Now the next step is to try and figure out which light will be on for a particular week in the future. Can anyone let me know how this can be done either using time series or regression? link to the data

All I need to predict is an On or Off like a boolean. Below is the key of the data: below is the code i used based on this ml github sample

Key
Light ID: this is a light represented ad an ID
LightDate: this is data captured once a week over the course of 2 n half years
OnOff: If the light for a particular ID was on on that time or off On being 1 and off Being 0
WeightByMonth: how many times the light was on for that month max can only be 4 since the data is captured once a week
WeightByYear: how many times the light was on for that year
TotalWeightOverTheYears: how many times the light was on for the entirety of the data being captured

public class LightSeriesModelHelper { /// /// Predicts future light when its turned On Or off using time series forecasting with SSA (single spectrum analysis). /// /// ML.NET context. /// where the predicted file (model file) for each light thats predicted. /// used to save the path of the file aganist each light. /// gotten from the database /// List of all the light stats for a particular light ID that will be used for forcastingon that light ID public static void PerformTimeSeriesForecasting(MLContext mlContext, string dataPath, ApplicationDbContext dbContext, int lightID, List LightsMLDataModelStats, string modelfolder) { Console.WriteLine("=============== Forecasting ==============="); ForecastProductUnits(mlContext, lightID, dataPath, dbContext, LightsMLDataModelStats, modelfolder); }

    /// <summary>
    /// Fit and save checkpoint of the model for predicting future LIGHT ONs
    /// </summary>
    /// <param name="mlContext">ML.NET context.</param>
    /// <param name="lightID">Id of the light series to forecast.</param>
    /// <param name="dataPath">Input data file path.</param>
    private static void ForecastProductUnits(MLContext mlContext, int lightID, string dataPath, ApplicationDbContext dbContext, List<LightsMLDataModel> LightsMLDataModelStats, string modelfolder)
    {
        //var productModelPath = $"product{player.id}_month_timeSeriesSSA.zip";
        string fileName = $"{lightID}_tPredictiveModel.zip";
        var productModelPath = $"{dataPath}/{fileName}";

        if (File.Exists(productModelPath))
        {
            File.Delete(productModelPath);
        }

        IDataView productDataView = LoadData(mlContext, lightID, dataPath, dbContext, LightsMLDataModelStats);
        var singleProductDataSeries = mlContext.Data.CreateEnumerable<LightsMLDataModel>(productDataView, false).OrderBy(p => p.LightDate);
        LightsMLDataModel lastMonthProductData = singleProductDataSeries.Last();
        FitAndSaveModel(mlContext, productDataView, productModelPath, fileName, dbContext, modelfolder);
        TestPrediction(mlContext, lastMonthProductData, productModelPath, dbContext, LightsMLDataModelStats);
    }

    /// <summary>
    /// Loads the monthly product data series for a product with the specified id.
    /// </summary>
    /// <param name="mlContext">ML.NET context.</param>
    /// <param name="lightID">light id.</param>
    /// <param name="dataPath">Input data file path.</param>
    private static IDataView LoadData(MLContext mlContext, float lightID, string dataPath, ApplicationDbContext dbContext, List<LightsMLDataModel> LightsMLDataModelStats)
    {

        IDataView allProductsDataView = mlContext.Data.LoadFromEnumerable<LightsMLDataModel>(LightsMLDataModelStats);


        IDataView productDataView = mlContext.Data.FilterRowsByColumn(allProductsDataView, "LightID", lightID, lightID + 1);

        return productDataView;
    }

    /// <summary>
    /// Build model for predicting next month's product unit sales using time series forecasting.
    /// </summary>
    /// <param name="mlContext">ML.NET context.</param>
    /// <param name="productDataSeries">ML.NET IDataView representing the loaded product data series.</param>
    /// <param name="outputModelPath">Model path.</param>
    private static void FitAndSaveModel(MLContext mlContext, IDataView productDataSeries, string outputModelPath, string filename, ApplicationDbContext dbContext, string modelfolder)
    {
        ConsoleWriteHeader("Fitting product forecasting Time Series model");

        int numSeriesDataPoints = 138; //The underlying data has a total of 34 months worth of data for each product

        IEstimator<ITransformer> forecastEstimator = mlContext.Forecasting.ForecastBySsa(
              outputColumnName: nameof(LightsTimeSeriesPrediction.ForecastedLightOnOrOff),
              inputColumnName: nameof(LightsMLDataModel.OnOff), // This is the column being forecasted.
              windowSize: 2, 
              seriesLength: 52, // This parameter specifies the number of data points that are used when performing a forecast. is 52
              trainSize: numSeriesDataPoints, // This parameter specifies the total number of data points in the input time series, starting from the beginning.
              horizon: 2, // Indicates the number of values to forecast; 2 indicates that the next 2 months of product units will be forecasted.
              confidenceLevel: 0.95f, // Indicates the likelihood the real observed value will fall within the specified interval bounds.
              confidenceLowerBoundColumn: nameof(LightsTimeSeriesPrediction.ConfidenceLowerBound), //This is the name of the column that will be used to store the lower interval bound for each forecasted value.
              confidenceUpperBoundColumn: nameof(LightsTimeSeriesPrediction.ConfidenceUpperBound)); //This is the name of the column that will be used to store the upper interval bound for each forecasted value.

        // Fit the forecasting model to the specified product's data series.
        ITransformer forecastTransformer = forecastEstimator.Fit(productDataSeries);

        // Create the forecast engine used for creating predictions.
        TimeSeriesPredictionEngine<LightsMLDataModel, LightsTimeSeriesPrediction> forecastEngine = forecastTransformer.CreateTimeSeriesEngine<LightsMLDataModel, LightsTimeSeriesPrediction>(mlContext);

        // Save the forecasting model so that it can be loaded within an end-user app.
        forecastEngine.CheckPoint(mlContext, outputModelPath);
        string folderrr = $"{modelfolder}/";
    }

    /// <summary>
    /// Predict samples using saved model.
    /// </summary>
    /// <param name="mlContext">ML.NET context.</param>
    /// <param name="lastMonthProductData">The last month of product data in the monthly data series.</param>
    /// <param name="outputModelPath">Model file path</param>
    private static void TestPrediction(MLContext mlContext, LightsMLDataModel lastMonthWeeksData, string outputModelPath, ApplicationDbContext dbContext, List<LightsMLDataModel> LightsMLDataModelStats)
    {
        ConsoleWriteHeader("Testing product unit sales forecast Time Series model");

        // Load the forecast engine that has been previously saved.
        ITransformer forecaster;
        using (var file = File.OpenRead(outputModelPath))
        {
            forecaster = mlContext.Model.Load(file, out DataViewSchema schema);
        }

        // We must create a new prediction engine from the persisted model.
        TimeSeriesPredictionEngine<LightsMLDataModel, LightsTimeSeriesPrediction> forecastEngine = forecaster.CreateTimeSeriesEngine<LightsMLDataModel, LightsTimeSeriesPrediction>(mlContext);

       
        Console.WriteLine("\n** Original prediction **");
        LightsTimeSeriesPrediction originalPrediction = forecastEngine.Predict();

        Console.WriteLine($"Product: {lastMonthWeeksData.LightID}, Date {lastMonthWeeksData.LightDate} " +
            $"- Real Value outcome: {lastMonthWeeksData.NextOn}, Forecast Prediction : {originalPrediction.ForecastedLightOnOrOff[0]}");

        // Get the first forecasted month's confidence interval bounds.
        Console.WriteLine($"Confidence interval: [{originalPrediction.ConfidenceLowerBound[0]} - {originalPrediction.ConfidenceUpperBound[0]}]\n");

        // Get the units of the second forecasted week.
        Console.WriteLine($"Product: {lastMonthWeeksData.LightID},  Date {lastMonthWeeksData.LightDate.AddDays(7)} " +
            $"Forecast (units): {originalPrediction.ForecastedLightOnOrOff[1]}");

        // Get the second forecasted month's confidence interval bounds.
        Console.WriteLine($"Confidence interval: [{originalPrediction.ConfidenceLowerBound[1]} - {originalPrediction.ConfidenceUpperBound[1]}]\n");

        // Update the forecasting model with the next weeks's actual light data to get an updated prediction; this time, only forecast product sales for 1 week ahead.
        Console.WriteLine("** Updated prediction **");

        LightsTimeSeriesPrediction updatedPrediction = forecastEngine.Predict(LightsMLDataModelStats.LastOrDefault(), horizon: 1);
        // Save a checkpoint of the forecasting model.
        forecastEngine.CheckPoint(mlContext, outputModelPath);

        // Get the units of the updated forecast.
        Console.WriteLine($"Product: {lastMonthWeeksData.LightID}, Date {lastMonthWeeksData.LightDate.AddDays(7)} " +
            $"Forecast (units): {updatedPrediction.ForecastedLightOnOrOff[0]}");

        // Get the updated forecast's confidence interval bounds.
        Console.WriteLine($"Confidence interval: [{updatedPrediction.ConfidenceLowerBound[0]} - {updatedPrediction.ConfidenceUpperBound[0]}]\n");



    }



    public static double ConvertGivenMins(string[] mins)
    {
        List<double> dmins = new List<double>();
        foreach (var min in mins)
        {
            string fixedMins = min.Replace(":", ".");
            double mymin = double.TryParse(fixedMins, out double fixedmins) ? fixedmins : 0;
            dmins.Add(mymin);
        }

        var minsResult = Math.Round(dmins.Average(), 2);
        return minsResult;
    }

    public class LightsMLDataModel
    {
        public float LightID { get; set; }
        public float OnOff { get; set; }
        public float PrevOn { get; set; }
        public float NextOn { get; set; }
        public float WeightByMonth { get; set; }
        public float WeightByYear { get; set; }
        public float TotalWeightOverTheYears { get; set; }
        public DateTime LightDate { get; set; }
        public float WeekOfYear { get; set; }
    }

    public class LightsTimeSeriesPrediction
    {
        public float[] ForecastedLightOnOrOff { get; set; }

        public float[] ConfidenceLowerBound { get; set; }

        public float[] ConfidenceUpperBound { get; set; }
    }
}
Deeman
  • 1
  • 2
  • Hi @Deeman. While your question is clear, you have not given any indication of what you have tried so far. Have you tried up any ML.NET tutorials for time series or regression analysis before asking your question here? – swatsonpicken Sep 03 '20 at 09:52
  • 1
    Hi @swatsonpicken i have tried the time series samples and regression on samples on github and other tutorials. last week i experimented with regression and this week with time series let me edit the question to include sample code i have been running for the time series – Deeman Sep 03 '20 at 10:06
  • @swatsonpicken i have updated the question with the code i have been using, and also do i run 1 time series or multiple for each light ID – Deeman Sep 03 '20 at 10:51
  • What were the results of running your code? I am not clear what the problem is - are you having problems with the code not running or with the output that the code is producing? Or maybe some other problem? – swatsonpicken Sep 03 '20 at 11:58
  • @swatsonpicken when i run the program created individual models for each id and when i test those different models it just bring the same six - 8 lights from last week it doesnt matter if its a prediction or 1 week, 2, 3, 4, 5 it doesnt take into account the other lights and also is my window size correct and series length – Deeman Sep 03 '20 at 12:11
  • lets say i have 30 numbers i generate 30 models and this last weeks results where light id 1, light id 10, light id 11, light ID 15, the prediction only looks at those light IDS and does not predict any others for the next few weeks others just remain as zeroes so not sure its looking into the other numbers or the past records,i am not sure if i am doing something wrong and would be great to be guided i.e. i am new to time series not sure what i am doing wrong, a pointer would be good – Deeman Sep 03 '20 at 12:18

0 Answers0