/// <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, ProductData lastMonthProductData, string outputModelPath) { 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 <ProductData, ProductUnitTimeSeriesPrediction> forecastEngine = forecaster.CreateTimeSeriesEngine <ProductData, ProductUnitTimeSeriesPrediction>(mlContext); // Get the prediction; this will include the forecasted product units sold for the next 2 months since this the time period specified in the `horizon` parameter when the forecast estimator was originally created. Console.WriteLine("\n** Original prediction **"); ProductUnitTimeSeriesPrediction originalSalesPrediction = forecastEngine.Predict(); // Compare the units of the first forecasted month to the actual units sold for the next month. var predictionMonth = lastMonthProductData.month == 12 ? 1 : lastMonthProductData.month + 1; var predictionYear = predictionMonth < lastMonthProductData.month ? lastMonthProductData.year + 1 : lastMonthProductData.year; Console.WriteLine($"Product: {lastMonthProductData.productId}, Month: {predictionMonth}, Year: {predictionYear} " + $"- Real Value (units): {lastMonthProductData.next}, Forecasted (units): {originalSalesPrediction.ForecastedProductUnits[0]}"); // Get the first forecasted month's confidence interval bounds. Console.WriteLine($"Confidence interval: [{originalSalesPrediction.ConfidenceLowerBound[0]} - {originalSalesPrediction.ConfidenceUpperBound[0]}]\n"); // Get the units of the second forecasted month. Console.WriteLine($"Product: {lastMonthProductData.productId}, Month: {lastMonthProductData.month + 2}, Year: {lastMonthProductData.year}, " + $"Forecasted (units): {originalSalesPrediction.ForecastedProductUnits[1]}"); // Get the second forecasted month's confidence interval bounds. Console.WriteLine($"Confidence interval: [{originalSalesPrediction.ConfidenceLowerBound[1]} - {originalSalesPrediction.ConfidenceUpperBound[1]}]\n"); // Update the forecasting model with the next month's actual product data to get an updated prediction; this time, only forecast product sales for 1 month ahead. Console.WriteLine("** Updated prediction **"); ProductData newProductData = SampleProductData.MonthlyData.Where(p => p.productId == lastMonthProductData.productId).Single(); ProductUnitTimeSeriesPrediction updatedSalesPrediction = forecastEngine.Predict(newProductData, horizon: 1); // Save the updated forecasting model. forecastEngine.CheckPoint(mlContext, outputModelPath); // Get the units of the updated forecast. predictionMonth = lastMonthProductData.month >= 11 ? (lastMonthProductData.month + 2) % 12 : lastMonthProductData.month + 2; predictionYear = predictionMonth < lastMonthProductData.month ? lastMonthProductData.year + 1 : lastMonthProductData.year; Console.WriteLine($"Product: {lastMonthProductData.productId}, Month: {predictionMonth}, Year: {predictionYear}, " + $"Forecasted (units): {updatedSalesPrediction.ForecastedProductUnits[0]}"); // Get the updated forecast's confidence interval bounds. Console.WriteLine($"Confidence interval: [{updatedSalesPrediction.ConfidenceLowerBound[0]} - {updatedSalesPrediction.ConfidenceUpperBound[0]}]\n"); }
static void Forecast(IDataView data, int horizon, TimeSeriesPredictionEngine <InputModel, OutputModel> forecaster, MLContext context) { var originalData = context.Data.CreateEnumerable <InputModel>(data, false); var forecast = forecaster.Predict(); var forecastOutput = context .Data .CreateEnumerable <InputModel>(data, false) .Take(horizon) .Select((InputModel sell, int index) => { var pastYearsSells = originalData.Where(item => item.SellMonth.Equals(index + 1)).OrderBy(item => item.SellYear); var stringfiedPastYearsSells = pastYearsSells.Select(item => $"\t{item.SellYear} sells: {item.Value}\n"); var month = sell.SellMonth; float actualSells = sell.Value; float lowerEstimate = Math.Max(0, forecast.LowerBoundSells[index]); float estimate = forecast.ForecastedSells[index]; float upperEstimate = forecast.UpperBoundSells[index]; return($"Month: {month}\n" + $"Other Year Sells:\n{string.Concat(stringfiedPastYearsSells)}\n" + $"Lower Estimate: {lowerEstimate}\n" + $"Forecast: {estimate}\n" + $"Upper Estimate: {upperEstimate}\n"); }); foreach (var item in forecastOutput) { Console.WriteLine(item); } }
public async Task <IActionResult> GetProductUnitDemandEstimation(string productId) { // Get product history. var productHistory = await _queries.GetProductDataAsync(productId); // Supplement the history with synthetic data. var supplementedProductHistory = TimeSeriesDataGenerator.SupplementData(mlContext, productHistory); var supplementedProductHistoryLength = supplementedProductHistory.Count(); // 36 var supplementedProductDataView = mlContext.Data.LoadFromEnumerable(supplementedProductHistory); // Create and add the forecast estimator to the pipeline. IEstimator <ITransformer> forecastEstimator = mlContext.Forecasting.ForecastBySsa( outputColumnName: nameof(ProductUnitTimeSeriesPrediction.ForecastedProductUnits), inputColumnName: nameof(ProductData.units), // This is the column being forecasted. windowSize: 12, // Window size is set to the time period represented in the product data cycle; our product cycle is based on 12 months, so this is set to a factor of 12, e.g. 3. seriesLength: supplementedProductHistoryLength, // TODO: Need clarification on what this should be set to; assuming product series length for now. trainSize: supplementedProductHistoryLength, // TODO: Need clarification on what this should be set to; assuming product series length for now. horizon: 1, // Indicates the number of values to forecast; 1 indicates that the next month of product units will be forecasted. confidenceLevel: 0.95f, // TODO: Is this the same as prediction interval, where this indicates that we are 95% confidence that the forecasted value will fall within the interval range? confidenceLowerBoundColumn: nameof(ProductUnitTimeSeriesPrediction.ConfidenceLowerBound), // TODO: See above comment. confidenceUpperBoundColumn: nameof(ProductUnitTimeSeriesPrediction.ConfidenceUpperBound)); // TODO: See above comment. // Train the forecasting model for the specified product's data series. ITransformer forecastTransformer = forecastEstimator.Fit(supplementedProductDataView); // Create the forecast engine used for creating predictions. TimeSeriesPredictionEngine <ProductData, ProductUnitTimeSeriesPrediction> forecastEngine = forecastTransformer.CreateTimeSeriesEngine <ProductData, ProductUnitTimeSeriesPrediction>(mlContext); // Predict. var nextMonthUnitDemandEstimation = forecastEngine.Predict(); return(Ok(nextMonthUnitDemandEstimation.ForecastedProductUnits.First())); }
static void Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine <ModelInput, ModelOutput> forecaster, MLContext mlContext) { ModelOutput forecast = forecaster.Predict(); IEnumerable <string> forecastOutput = mlContext.Data.CreateEnumerable <ModelInput>(testData, reuseRowObject: false) .Take(horizon) .Select((ModelInput sale, int index) => { string SaleDate = sale.SalesDate.ToShortDateString(); float actualSale = sale.TotalSales; float lowerEstimate = Math.Max(0, forecast.LowerBoundSales[index]); float estimate = forecast.ForecastedSales[index]; float upperEstimate = forecast.UpperBoundSales[index]; return($"Date: {SaleDate}\n" + $"Actual Rentals: {actualSale}\n" + $"Lower Estimate: {lowerEstimate}\n" + $"Forecast: {estimate}\n" + $"Upper Estimate: {upperEstimate}\n"); }); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); } }
public async Task <IActionResult> GetProductUnitDemandEstimation(string productId) { // Get product history for the selected product var productHistory = await _queries.GetProductDataAsync(productId); var productDataView = mlContext.Data.LoadFromEnumerable(productHistory); // Create and add the forecast estimator to the pipeline. IEstimator <ITransformer> forecastEstimator = mlContext.Forecasting.ForecastBySsa( outputColumnName: nameof(ProductUnitTimeSeriesPrediction.ForecastedProductUnits), inputColumnName: nameof(ProductData.units), // This is the column being forecasted. windowSize: 12, // Window size is set to the time period represented in the product data cycle; our product cycle is based on 12 months, so this is set to a factor of 12, e.g. 3. seriesLength: productHistory.Count(), // This parameter specifies the number of data points that are used when performing a forecast. trainSize: productHistory.Count(), // This parameter specifies the total number of data points in the input time series, starting from the beginning. horizon: 1, // Indicates the number of values to forecast; 1 indicates that the next month 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(ProductUnitTimeSeriesPrediction.ConfidenceLowerBound), //This is the name of the column that will be used to store the lower interval bound for each forecasted value. confidenceUpperBoundColumn: nameof(ProductUnitTimeSeriesPrediction.ConfidenceUpperBound)); //This is the name of the column that will be used to store the upper interval bound for each forecasted value. // Train the forecasting model for the specified product's data series. ITransformer forecastTransformer = forecastEstimator.Fit(productDataView); // Create the forecast engine used for creating predictions. TimeSeriesPredictionEngine <ProductData, ProductUnitTimeSeriesPrediction> forecastEngine = forecastTransformer.CreateTimeSeriesEngine <ProductData, ProductUnitTimeSeriesPrediction>(mlContext); // Predict. var nextMonthUnitDemandEstimation = forecastEngine.Predict(); return(Ok(nextMonthUnitDemandEstimation.ForecastedProductUnits.First())); }
/// <summary> /// Применение модели для прогнозирования спроса /// </summary> /// <param name="testData"></param> /// <param name="horizon"></param> /// <param name="forecaster"></param> /// <param name="mlContext"></param> static void Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine <ModelInput, ModelOutput> forecaster, MLContext mlContext) { ModelOutput forecast = forecaster.Predict(); //Сравните фактические и прогнозируемые значения по семи периодам. IEnumerable <string> forecastOutput = mlContext.Data.CreateEnumerable <ModelInput>(testData, reuseRowObject: false) .Take(horizon) .Select((ModelInput rental, int index) => { string rentalDate = rental.RentalDate.ToShortDateString(); float actualRentals = rental.TotalRentals; float lowerEstimate = Math.Max(0, forecast.LowerBoundRentals[index]); float estimate = forecast.ForecastedRentals[index]; float upperEstimate = forecast.UpperBoundRentals[index]; return($"Date: {rentalDate}\n" + $"Actual Rentals: {actualRentals}\n" + $"Lower Estimate: {lowerEstimate}\n" + $"Forecast: {estimate}\n" + $"Upper Estimate: {upperEstimate}\n"); }); Console.WriteLine("Rental Forecast"); Console.WriteLine("---------------------"); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); } }
static void Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine <ModelInput, ModelOutput> forecaster, MLContext mlContext) { ModelOutput forecast = forecaster.Predict(); IEnumerable <string> forecastOutput = mlContext.Data.CreateEnumerable <ModelInput>(testData, reuseRowObject: false) .Take(horizon) .Select((ModelInput passants, int index) => { //string jour = Enum.GetName(typeof(DayOfWeek), passants.Jour); float semaine = passants.Semaine; float jour = passants.Jour; //DateTime horaire = passants.Horaire; float actualPassants = passants.NbPassants; float lowerEstimate = Math.Max(0, forecast.LowerBoundPassants[index]); float estimate = forecast.ForecastedPassants[index]; float upperEstimate = forecast.UpperBoundPassants[index]; return($"Date: {jour}\n" + $"Actual Passants: {actualPassants}\n" + $"Lower Estimate: {lowerEstimate}\n" + $"Forecast: {estimate}\n" + $"Upper Estimate: {upperEstimate}\n"); }); Console.WriteLine("Passants Forecast"); Console.WriteLine("---------------------"); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); } }
public void Forecast(IDataView compareAgainst, int horizon, TimeSeriesPredictionEngine <ModelInput, ModelOutput> forecaster, MLContext mlContext) { ModelOutput forecast = forecaster.Predict(horizon); IEnumerable <string> forecastOutput = mlContext.Data.CreateEnumerable <ModelInput>(compareAgainst, reuseRowObject: false) .Take(horizon) .Select((ModelInput input, int index) => { string purchaseDate = input.Date.ToString("yyyy-MM-dd"); float actualSales = input.TotalSold; float lowerEstimate = Math.Max(0, forecast.LowerBoundTotalSold[index]); float estimate = forecast.ForecastedTotalSold[index]; float upperEstimate = forecast.UpperBoundTotalSold[index]; return($"Date: {purchaseDate}\n" + $"Actual Sales: {actualSales}\n" + $"Lower Estimate: {lowerEstimate}\n" + $"Forecast: {estimate}\n" + $"Upper Estimate: {upperEstimate}\n"); }); Console.WriteLine("Purchase Forecast"); Console.WriteLine("---------------------"); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); } }
static List <ModelOutputExt> Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine <ModelInput, ModelOutput> forecaster, MLContext mlContext) { ModelOutput forecast = forecaster.Predict(); List <ModelOutputExt> moextList = new List <ModelOutputExt>(); IEnumerable <ModelOutputExt> forecastOutput = mlContext.Data.CreateEnumerable <ModelInput>(testData, reuseRowObject: false) .Take(horizon) .Select((ModelInput sale, int index) => { ModelOutputExt mext = new ModelOutputExt(); mext.ForecastedSales = (float)(Math.Max(0, Math.Round(forecast.ForecastedSales[index], 0))); mext.LowerBoundSales = Math.Max(0, forecast.LowerBoundSales[index]); mext.UpperBoundSales = forecast.UpperBoundSales[index]; mext.SalesDate = sale.SalesDate.ToShortDateString(); mext.TotalSales = sale.TotalSales; mext.indexX = index; return(mext); }); foreach (var prediction in forecastOutput) { moextList.Add(prediction); } return(moextList); }
static void Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine <ModelInput, ModelOutput> forecaster, MLContext mlContext) { ModelOutput forecast = forecaster.Predict(); int i = 0; IEnumerable <string> forecastOutput = mlContext.Data.CreateEnumerable <ModelInput>(testData, reuseRowObject: false) .Take(horizon) .Select((ModelInput rental, int index) => { i++; string Date = rental.Invoice_Date.ToShortDateString(); float actualDays = rental.OverDue_Days; float lowerEstimate = Math.Max(0, forecast.MinimumDays[index]); float estimate = forecast.ForecastedDays[index]; float upperEstimate = forecast.MaximumDays[index]; return // $"No : {i}\n" + ($"Date : {Date}\n" + $"Actual Days : {actualDays}\n" + $"Lower Estimate Days : {lowerEstimate}\n" + $"Forecast Days : {estimate}\n" + $"Upper Estimate Days : {upperEstimate}\n"); }); // Output predictions Console.WriteLine("Rental Forecast"); Console.WriteLine("---------------------"); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); } }
private static void Forecast(IDataView testData, int horizon, TimeSeriesPredictionEngine <ModelInput, ModelOutput> forecaster) { var forecast = forecaster.Predict(); // Align actual & forecast values for seven periods var forecastOutput = _mlContext.Data.CreateEnumerable <ModelInput>(testData, reuseRowObject: false) .Take(horizon) .Select((ModelInput rental, int index) => { string rentalDate = rental.RentalDate.ToShortDateString(); float actualRentals = rental.TotalRentals; float lowerEstimate = Math.Max(0, forecast.LowerBoundRentals[index]); float estimate = forecast.ForecastedRentals[index]; float upperEstimate = forecast.UpperBoundRentals[index]; return($"Date: {rentalDate}\n" + $"Actual Rentals: {actualRentals}\n" + $"Lower Estimate: {lowerEstimate}\n" + $"Forecast: {estimate}\n" + $"Upper Estimate: {upperEstimate}"); }); Console.WriteLine("Rental Forecast"); Console.WriteLine("--------------------"); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); Console.WriteLine(""); } }
static void Main(string[] args) { var mlContext = new MLContext(); int c = 0; float predictedPrice = 0; while (c < 10) { IEnumerable <BTC_TimeSeries> data = GetTrainingData(mlContext); IDataView trainingData = mlContext.Data.LoadFromEnumerable <BTC_TimeSeries>(data); var offset = TimeSpan.FromSeconds(data.Last().TimeStamp); var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); DateTime lastTime = epoch.Add(offset).ToLocalTime(); int seriesLength = data.Count(); var estimator = mlContext.Forecasting.ForecastBySsa(outputColumnName: nameof(PredictedSeries.ForecastedPrice), inputColumnName: nameof(BTC_TimeSeries.Price), windowSize: 360, seriesLength: seriesLength, trainSize: seriesLength, horizon: 5, confidenceLevel: 0.95f, confidenceLowerBoundColumn: nameof(PredictedSeries.ConfidenceLowerBound), confidenceUpperBoundColumn: nameof(PredictedSeries.ConfidenceUpperBound) ); Console.WriteLine("Training model"); ITransformer forecastTransformer = estimator.Fit(trainingData); TimeSeriesPredictionEngine <BTC_TimeSeries, PredictedSeries> forecastEngine = forecastTransformer.CreateTimeSeriesEngine <BTC_TimeSeries, PredictedSeries>(mlContext); PredictedSeries predictions = forecastEngine.Predict(); Console.WriteLine("last read time {0}: last read price {1}", lastTime, data.Last().Price); for (int i = 0; i < predictions.ForecastedPrice.Count(); i++) { lastTime = lastTime.AddMinutes(15); Console.WriteLine("{0} price: {1}, low: {2}, high: {3}", lastTime, predictions.ForecastedPrice[i].ToString(), predictions.ConfidenceLowerBound[i].ToString(), predictions.ConfidenceUpperBound[i].ToString()); } float delta = predictedPrice - data.Last().Price; Console.WriteLine("Delta, {0}", delta); predictedPrice = predictions.ForecastedPrice[0]; forecastEngine.CheckPoint(mlContext, "forecastmodel.zip"); System.Threading.Thread.Sleep(300000); c++; } Console.Read(); }
static ModelOutput Forecast(IEnumerable <ModelInput> testData, int horizon, TimeSeriesPredictionEngine <ModelInput, ModelOutput> forecaster, MLContext mlContext, string value) { ModelOutput forecast = forecaster.Predict(); IEnumerable <string> forecastOutput = testData.TakeLast(horizon) .Select((ModelInput values, int index) => { string rentalDate = values.OpenTime.ToString(); float actualValue; switch (value) { case "Close": actualValue = values.Close; break; case "High": actualValue = values.High; break; case "Low": actualValue = values.Low; break; default: actualValue = values.Close; break; } float lowerEstimate = forecast.LowerBoundValue[index]; float estimate = forecast.ForecastedValue[index]; float upperEstimate = forecast.UpperBoundValue[index]; return($"Date: {rentalDate}\n" + $"Actual {value}: {actualValue}\n" + $"Forecast: {estimate}\n"); }); Console.WriteLine("Stock Forecast"); Console.WriteLine("---------------------"); foreach (var prediction in forecastOutput) { Console.WriteLine(prediction); } return(forecast); }
static void Predict() { //prediction engine based on our fitted model TimeSeriesPredictionEngine <BTCDataModel, PredictedSeriesDataModel> forecastEngine = forecastTransformer.CreateTimeSeriesEngine <BTCDataModel, PredictedSeriesDataModel>(mlContext); //call to predict the next 5 minutes PredictedSeriesDataModel predictions = forecastEngine.Predict(); //write our predictions for (int i = 0; i < predictions.ForecastedPrice.Count(); i++) { lastTime = lastTime.AddMinutes(1); Console.WriteLine("{0} price: {1}, low: {2}, high: {3}, actual: {4}", lastTime, predictions.ForecastedPrice[i].ToString(), predictions.ConfidenceLowerBound[i].ToString(), predictions.ConfidenceUpperBound[i].ToString(), testingData[i].Amount); } //instead of saving, we use checkpoint. This allows us to continue training with updated data and not need to keep such a large data set //so we can append Jan. 2021 without having everythign before to train the model speeding up the process forecastEngine.CheckPoint(mlContext, fileName); }
public ModelOutput Predict() { return(timeSeriesPredictionEngine.Predict()); }
public IEnumerable <RatioAnalysis> Predict(IEnumerable <RatioAnalysis> data) { var mlContext = new MLContext(seed: 1); IEstimator <ITransformer> costofgoodsForcaster = mlContext.Forecasting.ForecastBySsa( outputColumnName: nameof(RatioAnalysisPrediction.Forecasted), inputColumnName: nameof(RatioAnalysis.CostOfGoods), // This is the column being forecasted. windowSize: 12, // Window size is set to the time period represented in the product data cycle; our product cycle is based on 12 months, so this is set to a factor of 12, e.g. 3. seriesLength: data.Count(), // This parameter specifies the number of data points that are used when performing a forecast. trainSize: data.Count(), // This parameter specifies the total number of data points in the input time series, starting from the beginning. horizon: 3, // Indicates the number of values to forecast; 3 indicates that the next 3 months of product units will be forecasted. confidenceLevel: 0.75f, // Indicates the likelihood the real observed value will fall within the specified interval bounds. confidenceLowerBoundColumn: nameof(RatioAnalysisPrediction.ConfidenceLowerBound), //This is the name of the column that will be used to store the lower interval bound for each forecasted value. confidenceUpperBoundColumn: nameof(RatioAnalysisPrediction.ConfidenceUpperBound)); //This is the name of the column that will be used to store the upper interval bound for each forecasted value. IEstimator <ITransformer> inventoryForcaster = mlContext.Forecasting.ForecastBySsa( outputColumnName: nameof(RatioAnalysisPrediction.Forecasted), inputColumnName: nameof(RatioAnalysis.Inventory), // This is the column being forecasted. windowSize: 12, // Window size is set to the time period represented in the product data cycle; our product cycle is based on 12 months, so this is set to a factor of 12, e.g. 3. seriesLength: data.Count(), // This parameter specifies the number of data points that are used when performing a forecast. trainSize: data.Count(), // This parameter specifies the total number of data points in the input time series, starting from the beginning. horizon: 3, // Indicates the number of values to forecast; 3 indicates that the next 3 months of product units will be forecasted. confidenceLevel: 0.75f, // Indicates the likelihood the real observed value will fall within the specified interval bounds. confidenceLowerBoundColumn: nameof(RatioAnalysisPrediction.ConfidenceLowerBound), //This is the name of the column that will be used to store the lower interval bound for each forecasted value. confidenceUpperBoundColumn: nameof(RatioAnalysisPrediction.ConfidenceUpperBound)); //This is the name of the column that will be used to store the upper interval bound for each forecasted value. IEstimator <ITransformer> turnoverForcaster = mlContext.Forecasting.ForecastBySsa( outputColumnName: nameof(RatioAnalysisPrediction.Forecasted), inputColumnName: nameof(RatioAnalysis.Turnover), // This is the column being forecasted. windowSize: 12, // Window size is set to the time period represented in the product data cycle; our product cycle is based on 12 months, so this is set to a factor of 12, e.g. 3. seriesLength: data.Count(), // This parameter specifies the number of data points that are used when performing a forecast. trainSize: data.Count(), // This parameter specifies the total number of data points in the input time series, starting from the beginning. horizon: 3, // Indicates the number of values to forecast; 3 indicates that the next 3 months of product units will be forecasted. confidenceLevel: 0.75f, // Indicates the likelihood the real observed value will fall within the specified interval bounds. confidenceLowerBoundColumn: nameof(RatioAnalysisPrediction.ConfidenceLowerBound), //This is the name of the column that will be used to store the lower interval bound for each forecasted value. confidenceUpperBoundColumn: nameof(RatioAnalysisPrediction.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 costofgoodsTransformer = costofgoodsForcaster.Fit(mlContext.Data.LoadFromEnumerable(data)); ITransformer inventoryTransformer = inventoryForcaster.Fit(mlContext.Data.LoadFromEnumerable(data)); ITransformer turnoverTransformer = turnoverForcaster.Fit(mlContext.Data.LoadFromEnumerable(data)); // Create the forecast engine used for creating predictions. TimeSeriesPredictionEngine <RatioAnalysis, RatioAnalysisPrediction> inventoryEngine = inventoryTransformer.CreateTimeSeriesEngine <RatioAnalysis, RatioAnalysisPrediction>(mlContext); TimeSeriesPredictionEngine <RatioAnalysis, RatioAnalysisPrediction> turneroverEngine = turnoverTransformer.CreateTimeSeriesEngine <RatioAnalysis, RatioAnalysisPrediction>(mlContext); TimeSeriesPredictionEngine <RatioAnalysis, RatioAnalysisPrediction> costofgoodEngine = costofgoodsTransformer.CreateTimeSeriesEngine <RatioAnalysis, RatioAnalysisPrediction>(mlContext); // Get the prediction; this will include the forecasted turnover for the next 3 months since this //the time period specified in the `horizon` parameter when the forecast estimator was originally created. var turnoverPrediction = turneroverEngine.Predict(); var costPrediction = costofgoodEngine.Predict(); var inventoryPrediction = inventoryEngine.Predict(); var last = data.Last(); var retVal = data.ToList(); for (int i = 0; i < turnoverPrediction.Forecasted.Count(); i++) { retVal.Add(new RatioAnalysis { Date = last.Date.AddMonths(i + 1), CostOfGoods = costPrediction.Forecasted[i], CostOfGoodsDelta = costPrediction.ConfidenceUpperBound[i] - costPrediction.Forecasted[i], Inventory = inventoryPrediction.Forecasted[i], InventoryDelta = inventoryPrediction.ConfidenceUpperBound[i] - inventoryPrediction.Forecasted[i], Turnover = turnoverPrediction.Forecasted[i], TurnoverDelta = turnoverPrediction.ConfidenceUpperBound[i] - turnoverPrediction.Forecasted[i] }); } return(retVal); }