示例#1
0
        private static Lazy <TimeSeriesPredictionEngine <ModelInput, ModelOutput> > GetModel(MLContext context)
        {
            ITransformer model  = context.Model.Load(Model_File, out _);
            var          engine = model.CreateTimeSeriesEngine <ModelInput, ModelOutput>(context);

            return(new Lazy <TimeSeriesPredictionEngine <ModelInput, ModelOutput> >(engine));
        }
示例#2
0
        public void Predict(string inputDataFile)
        {
            if (!File.Exists(ModelPath))
            {
                Console.WriteLine($"Failed to find model at {ModelPath}");

                return;
            }

            if (!File.Exists(inputDataFile))
            {
                Console.WriteLine($"Failed to find input data at {inputDataFile}");

                return;
            }
            ITransformer mlModel = MlContext.Model.Load(ModelPath, out var modelInputSchema);

            if (mlModel == null)
            {
                Console.WriteLine("Failed to load model");

                return;
            }
            // Using ML Transforms TimeSeries
            var predictionEngine = mlModel.CreateTimeSeriesEngine <NetworkTrafficHistory, NetworkTrafficPrediction>(MlContext);

            // var predictionEngine = MlContext.Model.CreatePredictionEngine<NetworkTrafficHistory, NetworkTrafficPrediction>(mlModel);

            var inputData =
                MlContext.Data.LoadFromTextFile <NetworkTrafficHistory>(inputDataFile, separatorChar: ',');

            var rows = MlContext.Data.CreateEnumerable <NetworkTrafficHistory>(inputData, false);

            Console.WriteLine($"Based on input file ({inputDataFile}):");

            foreach (var row in rows)
            {
                var prediction = predictionEngine.Predict(row);

                Console.Write($"HOST: {row.HostMachine} TIMESTAMP: {row.Timestamp} TRANSFER: {row.BytesTransferred} ");
                Console.Write($"ALERT: {prediction.Prediction[0]} SCORE: {prediction.Prediction[1]:f2} P-VALUE: {prediction.Prediction[2]:F2}{Environment.NewLine}");
            }
        }
示例#3
0
        // This example creates a time series (list of Data with the i-th element
        // corresponding to the i-th time slot). It demonstrates stateful prediction
        // engine that updates the state of the model and allows for
        // saving/reloading. The estimator is applied then to identify points where
        // data distribution changed. This estimator can account for temporal
        // seasonality in the data.
        public static void Example()
        {
            // Create a new ML context, for ML.NET operations. It can be used for
            // exception tracking and logging, as well as the source of randomness.
            var ml = new MLContext();

            // Generate sample series data with a recurring pattern
            const int SeasonalitySize = 5;
            const int TrainingSeasons = 3;
            const int TrainingSize    = SeasonalitySize * TrainingSeasons;
            var       data            = new List <TimeSeriesData>()
            {
                new TimeSeriesData(0),
                new TimeSeriesData(1),
                new TimeSeriesData(2),
                new TimeSeriesData(3),
                new TimeSeriesData(4),

                new TimeSeriesData(0),
                new TimeSeriesData(1),
                new TimeSeriesData(2),
                new TimeSeriesData(3),
                new TimeSeriesData(4),

                new TimeSeriesData(0),
                new TimeSeriesData(1),
                new TimeSeriesData(2),
                new TimeSeriesData(3),
                new TimeSeriesData(4),
            };

            // Convert data to IDataView.
            var dataView = ml.Data.LoadFromEnumerable(data);

            // Setup SsaChangePointDetector arguments
            var inputColumnName     = nameof(TimeSeriesData.Value);
            var outputColumnName    = nameof(ChangePointPrediction.Prediction);
            int confidence          = 95;
            int changeHistoryLength = 8;

            // Train the change point detector.
            ITransformer model = ml.Transforms.DetectChangePointBySsa(
                outputColumnName, inputColumnName, confidence, changeHistoryLength,
                TrainingSize, SeasonalitySize + 1).Fit(dataView);

            // Create a prediction engine from the model for feeding new data.
            var engine = model.CreateTimeSeriesEngine <TimeSeriesData,
                                                       ChangePointPrediction>(ml);

            // Start streaming new data points with no change point to the
            // prediction engine.
            Console.WriteLine($"Output from ChangePoint predictions on new data:");
            Console.WriteLine("Data\tAlert\tScore\tP-Value\tMartingale value");

            // Output from ChangePoint predictions on new data:
            // Data    Alert   Score   P-Value Martingale value

            for (int i = 0; i < 5; i++)
            {
                PrintPrediction(i, engine.Predict(new TimeSeriesData(i)));
            }

            // 0       0      -1.01    0.50    0.00
            // 1       0      -0.24    0.22    0.00
            // 2       0      -0.31    0.30    0.00
            // 3       0       0.44    0.01    0.00
            // 4       0       2.16    0.00    0.24

            // Now stream data points that reflect a change in trend.
            for (int i = 0; i < 5; i++)
            {
                int value = (i + 1) * 100;
                PrintPrediction(value, engine.Predict(new TimeSeriesData(value)));
            }
            // 100     0      86.23    0.00    2076098.24
            // 200     0     171.38    0.00    809668524.21
            // 300     1     256.83    0.01    22130423541.93    <-- alert is on, note that delay is expected
            // 400     0     326.55    0.04    241162710263.29
            // 500     0     364.82    0.08    597660527041.45   <-- saved to disk

            // Now we demonstrate saving and loading the model.

            // Save the model that exists within the prediction engine.
            // The engine has been updating this model with every new data point.
            byte[] modelBytes;
            using (var stream = new MemoryStream())
            {
                engine.CheckPoint(ml, stream);
                modelBytes = stream.ToArray();
            }

            // Load the model.
            using (var stream = new MemoryStream(modelBytes))
                model = ml.Model.Load(stream, out DataViewSchema schema);

            // We must create a new prediction engine from the persisted model.
            engine = model.CreateTimeSeriesEngine <TimeSeriesData,
                                                   ChangePointPrediction>(ml);

            // Run predictions on the loaded model.
            for (int i = 0; i < 5; i++)
            {
                int value = (i + 1) * 100;
                PrintPrediction(value, engine.Predict(new TimeSeriesData(value)));
            }

            // 100     0     -58.58    0.15    1096021098844.34  <-- loaded from disk and running new predictions
            // 200     0     -41.24    0.20    97579154688.98
            // 300     0     -30.61    0.24    95319753.87
            // 400     0      58.87    0.38    14.24
            // 500     0     219.28    0.36    0.05
        }
        public void ChangePointDetectionWithSeasonalityPredictionEngine()
        {
            const int changeHistorySize         = 10;
            const int seasonalitySize           = 10;
            const int numberOfSeasonsInTraining = 5;
            const int maxTrainingSize           = numberOfSeasonsInTraining * seasonalitySize;

            List <Data> data = new List <Data>();

            var ml       = new MLContext(seed: 1);
            var dataView = ml.Data.LoadFromEnumerable(data);

            for (int j = 0; j < numberOfSeasonsInTraining; j++)
            {
                for (int i = 0; i < seasonalitySize; i++)
                {
                    data.Add(new Data(i));
                }
            }

            for (int i = 0; i < changeHistorySize; i++)
            {
                data.Add(new Data(i * 100));
            }


            // Pipeline.
            var pipeline = ml.Transforms.Text.FeaturizeText("Text_Featurized", "Text")
                           .Append(ml.Transforms.Conversion.ConvertType("Value", "Value", DataKind.Single))
                           .Append(new SsaChangePointEstimator(ml, new SsaChangePointDetector.Options()
            {
                Confidence          = 95,
                Source              = "Value",
                Name                = "Change",
                ChangeHistoryLength = changeHistorySize,
                TrainingWindowSize  = maxTrainingSize,
                SeasonalWindowSize  = seasonalitySize
            }));

            // Train.
            var model = pipeline.Fit(dataView);

            //Model 1: Prediction #1.
            var engine     = model.CreateTimeSeriesEngine <Data, Prediction>(ml);
            var prediction = engine.Predict(new Data(1));

            Assert.Equal(0, prediction.Change[0], precision: 7);                      // Alert
            Assert.Equal(1.1661833524703979, prediction.Change[1], precision: 5);     // Raw score
            Assert.Equal(0.5, prediction.Change[2], precision: 7);                    // P-Value score
            Assert.Equal(5.1200000000000114E-08, prediction.Change[3], precision: 7); // Martingale score

            //Model 1: Checkpoint.
            var modelPath = "temp.zip";

            engine.CheckPoint(ml, modelPath);

            //Model 1: Prediction #2
            prediction = engine.Predict(new Data(1));
            Assert.Equal(0, prediction.Change[0], precision: 7);                      // Alert
            Assert.Equal(0.12216401100158691, prediction.Change[1], precision: 5);    // Raw score
            Assert.Equal(0.14823824685192111, prediction.Change[2], precision: 5);    // P-Value score
            Assert.Equal(1.5292508189989167E-07, prediction.Change[3], precision: 7); // Martingale score

            // Load Model 1.
            ITransformer model2 = null;

            using (var file = File.OpenRead(modelPath))
                model2 = ml.Model.Load(file, out var schema);

            //Predict and expect the same result after checkpointing(Prediction #2).
            engine     = model2.CreateTimeSeriesEngine <Data, Prediction>(ml);
            prediction = engine.Predict(new Data(1));
            Assert.Equal(0, prediction.Change[0], precision: 7);                      // Alert
            Assert.Equal(0.12216401100158691, prediction.Change[1], precision: 5);    // Raw score
            Assert.Equal(0.14823824685192111, prediction.Change[2], precision: 5);    // P-Value score
            Assert.Equal(1.5292508189989167E-07, prediction.Change[3], precision: 5); // Martingale score
        }
        public void ChangePointDetectionWithSeasonalityPredictionEngineNoColumn()
        {
            const int changeHistorySize         = 10;
            const int seasonalitySize           = 10;
            const int numberOfSeasonsInTraining = 5;
            const int maxTrainingSize           = numberOfSeasonsInTraining * seasonalitySize;

            List <Data> data = new List <Data>();

            var ml       = new MLContext(seed: 1);
            var dataView = ml.Data.LoadFromEnumerable(data);

            for (int j = 0; j < numberOfSeasonsInTraining; j++)
            {
                for (int i = 0; i < seasonalitySize; i++)
                {
                    data.Add(new Data(i));
                }
            }

            for (int i = 0; i < changeHistorySize; i++)
            {
                data.Add(new Data(i * 100));
            }


            // Pipeline.
            var pipeline = ml.Transforms.Text.FeaturizeText("Text_Featurized", "Text")
                           .Append(new SsaChangePointEstimator(ml, new SsaChangePointDetector.Options()
            {
                Confidence          = 95,
                Source              = "Value",
                Name                = "Change",
                ChangeHistoryLength = changeHistorySize,
                TrainingWindowSize  = maxTrainingSize,
                SeasonalWindowSize  = seasonalitySize
            }));

            // Train.
            var model = pipeline.Fit(dataView);

            //Create prediction function.
            var engine = model.CreateTimeSeriesEngine <Data, Prediction1>(ml);

            //Checkpoint with no inputs passed at prediction.
            var modelPath = "temp.zip";

            engine.CheckPoint(ml, modelPath);

            //Load time series model and we will use this to pass two inputs and compare the raw score
            //with "engine".
            ITransformer model2 = null;

            using (var file = File.OpenRead(modelPath))
                model2 = ml.Model.Load(file, out var schema);

            //Raw score after state gets updated with two inputs.
            var engine2     = model2.CreateTimeSeriesEngine <Data, Prediction>(ml);
            var prediction2 = engine2.Predict(new Data(1));

            //Raw score after first input.
            Assert.Equal(1.1661833524703979, prediction2.Change[1], precision: 5); // Raw score
            prediction2 = engine2.Predict(new Data(1));
            //Raw score after second input.
            Assert.Equal(0.12216401100158691, prediction2.Change[1], precision: 5); // Raw score

            //Even though time series column is not requested it will
            // pass the observation through time series transform and update the state with the first input.
            var prediction = engine.Predict(new Data(1));

            Assert.Equal(-1, prediction.Random);

            //Save the model with state updated with just one input.
            engine.CheckPoint(ml, modelPath + 1);
            ITransformer model3 = null;

            using (var file = File.OpenRead(modelPath + 1))
                model3 = ml.Model.Load(file, out var schema);

            //Load the model with state updated with just one input, then pass in the second input
            //and raw score should match the raw score obtained by passing the two input in the first model.
            var engine3     = model3.CreateTimeSeriesEngine <Data, Prediction>(ml);
            var prediction3 = engine3.Predict(new Data(1));

            Assert.Equal(0.12216401100158691, prediction2.Change[1], precision: 5); // Raw score
        }
示例#6
0
        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()));
        }
示例#7
0
        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);
        }
        // This example creates a time series (list of Data with the i-th element
        // corresponding to the i-th time slot). The estimator is applied then to
        // identify spiking points in the series. This estimator can account for
        // temporal seasonality in the data.
        public static void Example()
        {
            // Create a new ML context, for ML.NET operations. It can be used for
            // exception tracking and logging, as well as the source of randomness.
            var ml = new MLContext();

            // Generate sample series data with a recurring pattern
            const int SeasonalitySize = 5;
            const int TrainingSeasons = 3;
            const int TrainingSize    = SeasonalitySize * TrainingSeasons;
            var       data            = new List <TimeSeriesData>()
            {
                new TimeSeriesData(0),
                new TimeSeriesData(1),
                new TimeSeriesData(2),
                new TimeSeriesData(3),
                new TimeSeriesData(4),

                new TimeSeriesData(0),
                new TimeSeriesData(1),
                new TimeSeriesData(2),
                new TimeSeriesData(3),
                new TimeSeriesData(4),

                new TimeSeriesData(0),
                new TimeSeriesData(1),
                new TimeSeriesData(2),
                new TimeSeriesData(3),
                new TimeSeriesData(4),
            };

            // Convert data to IDataView.
            var dataView = ml.Data.LoadFromEnumerable(data);

            // Setup IidSpikeDetector arguments
            var inputColumnName  = nameof(TimeSeriesData.Value);
            var outputColumnName = nameof(SsaSpikePrediction.Prediction);

            // Train the change point detector.
            ITransformer model = ml.Transforms.DetectSpikeBySsa(outputColumnName,
                                                                inputColumnName, 95, 8, TrainingSize, SeasonalitySize + 1).Fit(
                dataView);

            // Create a prediction engine from the model for feeding new data.
            var engine = model.CreateTimeSeriesEngine <TimeSeriesData,
                                                       SsaSpikePrediction>(ml);

            // Start streaming new data points with no change point to the
            // prediction engine.
            Console.WriteLine($"Output from spike predictions on new data:");
            Console.WriteLine("Data\tAlert\tScore\tP-Value");

            // Output from spike predictions on new data:
            // Data    Alert   Score   P-Value

            for (int j = 0; j < 2; j++)
            {
                for (int i = 0; i < 5; i++)
                {
                    PrintPrediction(i, engine.Predict(new TimeSeriesData(i)));
                }
            }

            // 0       0      -1.01    0.50
            // 1       0      -0.24    0.22
            // 2       0      -0.31    0.30
            // 3       0       0.44    0.01
            // 4       0       2.16    0.00
            // 0       0      -0.78    0.27
            // 1       0      -0.80    0.30
            // 2       0      -0.84    0.31
            // 3       0       0.33    0.31
            // 4       0       2.21    0.07

            // Now send a data point that reflects a spike.
            PrintPrediction(100, engine.Predict(new TimeSeriesData(100)));

            // 100     1      86.17    0.00   <-- alert is on, predicted spike

            // Now we demonstrate saving and loading the model.
            // Save the model that exists within the prediction engine.
            // The engine has been updating this model with every new data point.
            var modelPath = "model.zip";

            engine.CheckPoint(ml, modelPath);

            // Load the model.
            using (var file = File.OpenRead(modelPath))
                model = ml.Model.Load(file, out DataViewSchema schema);

            // We must create a new prediction engine from the persisted model.
            engine = model.CreateTimeSeriesEngine <TimeSeriesData,
                                                   SsaSpikePrediction>(ml);

            // Run predictions on the loaded model.
            for (int i = 0; i < 5; i++)
            {
                PrintPrediction(i, engine.Predict(new TimeSeriesData(i)));
            }

            // 0       0      -2.74    0.40   <-- saved to disk, re-loaded, and running new predictions
            // 1       0      -1.47    0.42
            // 2       0     -17.50    0.24
            // 3       0     -30.82    0.16
            // 4       0     -23.24    0.28
        }
        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);
        }
        /// <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">Trained model path.</param>
        private static void TrainAndSaveModel(MLContext mlContext, IDataView productDataView, string outputModelPath)
        {
            ConsoleWriteHeader("Training product forecasting Time Series model");

            var supplementedProductDataSeries       = TimeSeriesDataGenerator.SupplementData(mlContext, productDataView);
            var supplementedProductDataSeriesLength = supplementedProductDataSeries.Count(); // 36
            var supplementedProductDataView         = mlContext.Data.LoadFromEnumerable(supplementedProductDataSeries, productDataView.Schema);

            // 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: supplementedProductDataSeriesLength,                                         // TODO: Need clarification on what this should be set to; assuming product series length for now.
                trainSize: supplementedProductDataSeriesLength,                                            // TODO: Need clarification on what this should be set to; assuming product series length for now.
                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,                                                                    // 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);

            // Save the forecasting model so that it can be loaded within an end-user app.
            forecastEngine.CheckPoint(mlContext, outputModelPath);
        }
        // This example creates a time series (list of Data with the i-th element
        // corresponding to the i-th time slot). The estimator is applied then to
        // identify points where data distribution changed.
        public static void Example()
        {
            // Create a new ML context, for ML.NET operations. It can be used for
            // exception tracking and logging, as well as the source of randomness.
            var ml = new MLContext();

            // Generate sample series data with a change
            const int Size = 16;
            var       data = new List <TimeSeriesData>(Size)
            {
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),

                //Change point data.
                new TimeSeriesData(7),
                new TimeSeriesData(7),
                new TimeSeriesData(7),
                new TimeSeriesData(7),
                new TimeSeriesData(7),
                new TimeSeriesData(7),
                new TimeSeriesData(7),
                new TimeSeriesData(7),
            };

            // Convert data to IDataView.
            var dataView = ml.Data.LoadFromEnumerable(data);

            // Setup IidSpikeDetector arguments
            string outputColumnName = nameof(ChangePointPrediction.Prediction);
            string inputColumnName  = nameof(TimeSeriesData.Value);

            // Time Series model.
            ITransformer model = ml.Transforms.DetectIidChangePoint(
                outputColumnName, inputColumnName, 95, Size / 4).Fit(dataView);

            // Create a time series prediction engine from the model.
            var engine = model.CreateTimeSeriesEngine <TimeSeriesData,
                                                       ChangePointPrediction>(ml);

            Console.WriteLine($"{outputColumnName} column obtained " +
                              $"post-transformation.");

            Console.WriteLine("Data\tAlert\tScore\tP-Value\tMartingale value");

            // Data Alert      Score   P-Value Martingale value

            // Create non-anomalous data and check for change point.
            for (int index = 0; index < 8; index++)
            {
                // Anomaly change point detection.
                PrintPrediction(5, engine.Predict(new TimeSeriesData(5)));
            }

            // 5       0       5.00    0.50    0.00       <-- Time Series 1.
            // 5       0       5.00    0.50    0.00
            // 5       0       5.00    0.50    0.00
            // 5       0       5.00    0.50    0.00
            // 5       0       5.00    0.50    0.00
            // 5       0       5.00    0.50    0.00
            // 5       0       5.00    0.50    0.00
            // 5       0       5.00    0.50    0.00

            // Change point
            PrintPrediction(7, engine.Predict(new TimeSeriesData(7)));

            // 7       1       7.00    0.00    10298.67   <-- alert is on, predicted changepoint (and model is checkpointed).

            // Checkpoint the model.
            var modelPath = "temp.zip";

            engine.CheckPoint(ml, modelPath);

            // Reference to current time series engine because in the next step
            // "engine" will point to the
            // checkpointed model being loaded from disk.
            var timeseries1 = engine;

            // Load the model.
            using (var file = File.OpenRead(modelPath))
                model = ml.Model.Load(file, out DataViewSchema schema);

            // Create a time series prediction engine from the checkpointed model.
            engine = model.CreateTimeSeriesEngine <TimeSeriesData,
                                                   ChangePointPrediction>(ml);

            for (int index = 0; index < 8; index++)
            {
                // Anomaly change point detection.
                PrintPrediction(7, engine.Predict(new TimeSeriesData(7)));
            }

            // 7       0       7.00    0.13    33950.16   <-- Time Series 2 : Model loaded back from disk and prediction is made.
            // 7       0       7.00    0.26    60866.34
            // 7       0       7.00    0.38    78362.04
            // 7       0       7.00    0.50    0.01
            // 7       0       7.00    0.50    0.00
            // 7       0       7.00    0.50    0.00
            // 7       0       7.00    0.50    0.00

            // Prediction from the original time series engine should match the
            // prediction from check pointed model.
            engine = timeseries1;
            for (int index = 0; index < 8; index++)
            {
                // Anomaly change point detection.
                PrintPrediction(7, engine.Predict(new TimeSeriesData(7)));
            }

            // 7       0       7.00    0.13    33950.16   <-- Time Series 1 and prediction is made.
            // 7       0       7.00    0.26    60866.34
            // 7       0       7.00    0.38    78362.04
            // 7       0       7.00    0.50    0.01
            // 7       0       7.00    0.50    0.00
            // 7       0       7.00    0.50    0.00
            // 7       0       7.00    0.50    0.00
        }
        private static void SaveModel(MLContext context, ITransformer model)
        {
            TimeSeriesPredictionEngine <ModelInput, ModelOutput> forecastEngine = model.CreateTimeSeriesEngine <ModelInput, ModelOutput>(context);

            forecastEngine.CheckPoint(context, MODEL_PATH);
        }
        /// <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)
        {
            ConsoleWriteHeader("Fitting product forecasting Time Series model");

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

            // 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: numSeriesDataPoints,                                                         // This parameter specifies the number of data points that are used when performing a forecast.
                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(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.

            // 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 <ProductData, ProductUnitTimeSeriesPrediction> forecastEngine = forecastTransformer.CreateTimeSeriesEngine <ProductData, ProductUnitTimeSeriesPrediction>(mlContext);

            // Save the forecasting model so that it can be loaded within an end-user app.
            forecastEngine.CheckPoint(mlContext, outputModelPath);
        }
示例#14
0
        /// <summary>
        /// Crea el modelo y lo guarda en el path entrado
        /// </summary>
        /// <param name="mlContext">ML.NET context.</param>
        /// <param name="productId">Id of the product series to forecast.</param>
        /// <param name="dataPath">Input data file path.</param>
        private static void CreateAndSaveModelTimeSeries(MLContext mlContext, string dataPath, float id)
        {
            var productModelPath = $"product{id}_month_timeSeriesSSA.zip";

            if (File.Exists(productModelPath))
            {
                File.Delete(productModelPath);
            }
            IDataView saleDataView            = LoadData(mlContext, dataPath, id);
            var       singleProductDataSeries = mlContext.Data.CreateEnumerable <SaleData>(saleDataView, false).OrderBy(p => p.ano).ThenBy(p => p.mes);
            SaleData  lastMonthSalesData      = singleProductDataSeries.Last();

            Console.WriteLine("Creando el modelo: Time Series Model");

            const int numSeriesDataPoints = 34;
            IEstimator <ITransformer> forecastEstimator = mlContext.Forecasting.ForecastBySsa(
                outputColumnName: nameof(ProductUnitTimeSeriesPrediction.ForecastedProductUnits),
                inputColumnName: nameof(SaleData.unidades),                                                // 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: numSeriesDataPoints,                                                         // This parameter specifies the number of data points that are used when performing a forecast.
                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(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.

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

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

            // Save the forecasting model so that it can be loaded within an end-user app.
            forecastEngine.CheckPoint(mlContext, productModelPath);
            TestPrediction(mlContext, lastMonthSalesData, productModelPath);
        }
示例#15
0
        // This example creates a time series (list of Data with the i-th element corresponding to the i-th time slot).
        // The estimator is applied then to identify spiking points in the series.
        public static void Example()
        {
            // Create a new ML context, for ML.NET operations. It can be used for exception tracking and logging,
            // as well as the source of randomness.
            var ml = new MLContext();

            // Generate sample series data with a spike
            const int Size = 10;
            var       data = new List <TimeSeriesData>(Size + 1)
            {
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),

                // This is a spike.
                new TimeSeriesData(10),

                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
                new TimeSeriesData(5),
            };

            // Convert data to IDataView.
            var dataView = ml.Data.LoadFromEnumerable(data);

            // Setup IidSpikeDetector arguments
            string outputColumnName = nameof(IidSpikePrediction.Prediction);
            string inputColumnName  = nameof(TimeSeriesData.Value);

            // The transformed model.
            ITransformer model = ml.Transforms.DetectIidSpike(outputColumnName, inputColumnName, 95, Size).Fit(dataView);

            // Create a time series prediction engine from the model.
            var engine = model.CreateTimeSeriesEngine <TimeSeriesData, IidSpikePrediction>(ml);

            Console.WriteLine($"{outputColumnName} column obtained post-transformation.");
            Console.WriteLine("Data\tAlert\tScore\tP-Value");

            // Prediction column obtained post-transformation.
            // Data Alert   Score   P-Value

            // Create non-anomalous data and check for anomaly.
            for (int index = 0; index < 5; index++)
            {
                // Anomaly spike detection.
                PrintPrediction(5, engine.Predict(new TimeSeriesData(5)));
            }

            // 5      0       5.00    0.50
            // 5      0       5.00    0.50
            // 5      0       5.00    0.50
            // 5      0       5.00    0.50
            // 5      0       5.00    0.50

            // Spike.
            PrintPrediction(10, engine.Predict(new TimeSeriesData(10)));

            // 10     1      10.00    0.00  <-- alert is on, predicted spike (check-point model)

            // Checkpoint the model.
            var modelPath = "temp.zip";

            engine.CheckPoint(ml, modelPath);

            // Load the model.
            using (var file = File.OpenRead(modelPath))
                model = ml.Model.Load(file, out DataViewSchema schema);

            for (int index = 0; index < 5; index++)
            {
                // Anomaly spike detection.
                PrintPrediction(5, engine.Predict(new TimeSeriesData(5)));
            }

            // 5      0       5.00    0.26  <-- load model from disk.
            // 5      0       5.00    0.26
            // 5      0       5.00    0.50
            // 5      0       5.00    0.50
            // 5      0       5.00    0.50
        }
示例#16
0
        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()));
        }
        // This example creates a time series (list of Data with the i-th element
        // corresponding to the i-th time slot). The estimator is applied then to
        // identify spiking points in the series.
        public static void Example()
        {
            // Create a new ML context, for ML.NET operations. It can be used for
            // exception tracking and logging, as well as the source of randomness.
            var ml = new MLContext();

            // Generate sample series data with an anomaly
            var data = new List <TimeSeriesData>();

            for (int index = 0; index < 20; index++)
            {
                data.Add(new TimeSeriesData(5));
            }
            data.Add(new TimeSeriesData(10));
            for (int index = 0; index < 5; index++)
            {
                data.Add(new TimeSeriesData(5));
            }

            // Convert data to IDataView.
            var dataView = ml.Data.LoadFromEnumerable(data);

            // Setup the estimator arguments
            string outputColumnName = nameof(SrCnnAnomalyDetection.Prediction);
            string inputColumnName  = nameof(TimeSeriesData.Value);

            // The transformed model.
            ITransformer model = ml.Transforms.DetectAnomalyBySrCnn(
                outputColumnName, inputColumnName, 16, 5, 5, 3, 8, 0.35).Fit(
                dataView);

            // Create a time series prediction engine from the model.
            var engine = model.CreateTimeSeriesEngine <TimeSeriesData,
                                                       SrCnnAnomalyDetection>(ml);

            Console.WriteLine($"{outputColumnName} column obtained post-" +
                              $"transformation.");

            Console.WriteLine("Data\tAlert\tScore\tMag");

            // Prediction column obtained post-transformation.
            // Data	Alert	Score	Mag

            // Create non-anomalous data and check for anomaly.
            for (int index = 0; index < 20; index++)
            {
                // Anomaly detection.
                PrintPrediction(5, engine.Predict(new TimeSeriesData(5)));
            }

            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.00    0.00
            //5   0   0.03    0.18
            //5   0   0.03    0.18
            //5   0   0.03    0.18
            //5   0   0.03    0.18
            //5   0   0.03    0.18

            // Anomaly.
            PrintPrediction(10, engine.Predict(new TimeSeriesData(10)));

            //10	1	0.47	0.93    <-- alert is on, predicted anomaly

            // Checkpoint the model.
            var modelPath = "temp.zip";

            engine.CheckPoint(ml, modelPath);

            // Load the model.
            using (var file = File.OpenRead(modelPath))
                model = ml.Model.Load(file, out DataViewSchema schema);

            for (int index = 0; index < 5; index++)
            {
                // Anomaly detection.
                PrintPrediction(5, engine.Predict(new TimeSeriesData(5)));
            }

            //5   0   0.31    0.50
            //5   0   0.05    0.30
            //5   0   0.01    0.23
            //5   0   0.00    0.21
            //5   0   0.01    0.25
        }
示例#18
0
        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();
        }