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; }
}
}