public override TimeSeries BuildForecasts(TimeSeries simulatedData, List <DateTime> futureTimes)
        {
            // fit model first, using maximum likelihood estimation
            var model = new ARMAModel(mAROrder, mMAOrder);           // create the model object

            model.TheData = simulatedData;                           // this is the data we want to fit the model to
            model.FitByMLE(mNumberIterLDS, mNumberIterOpt, 0, null); // first param is # low discrepancy sequence iterations, should be at least about 200
            // second param is # standard optimizer iterations, should be at least about 100

            // now do some forecasting beyond the end of the data
            var forecaster = new ForecastTransform();

            forecaster.FutureTimes = futureTimes.ToArray(); // these are future times at which we want forecasts
            // for now, ARMA models do not use the times in any meaningful way when forecasting,
            // they just assume that these are the timestamps for the next sequential points
            // after the end of the existing time series

            forecaster.SetInput(0, model, null);            // the ARMA model used for forecasting
            forecaster.SetInput(1, simulatedData, null);    // the original data

            // normally you would call the Recompute() method of a transform, but there is no need
            // here; it is automatically called as soon as all inputs are set to valid values (in the 2 statements above)
            var predictors = forecaster.GetOutput(0) as TimeSeries;

            return(predictors);
        }
Example #2
0
        // given a file, x attr, y attr, date delimiter, has time boolean, how many values to include in the model, how many to predict,
        // whether the data should be reversed to have the dates increasing, and the significance level for the stationarity test,
        // the predicted values, the actual values, and the MAE, RMSE, and MAPE errors.
        public static void forecasttest(string file, string outfile, string xattr, char delimiter, bool hastime, bool change, double split, bool reverse, double siglevel, bool log)
        {
            var data = GetData(file, xattr, hastime).Select(a => TimeSeriesWrapper.getDataObject(a, change));

            if (reverse)
            {
                data = data.Reverse();
            }

            var splitData = DivideData(data.ToArray(), split);

            TimeSeriesWrapper ts = new TimeSeriesWrapper();

            ARMAModel model = ts.buildARMAModel(splitData.Item1.ToArray(), siglevel, -1, log: log);

            List <DateTime> futureTimes = splitData.Item2.Select(a => a.Date).ToList();

            TimeSeries mergedtimeseries = ts.predictARMA(futureTimes, model);

            var points = GetPoints(mergedtimeseries, splitData);

            ChartPoints(file.Split('/').Last(), points.Item1, points.Item2);

            double[] errresults = TimeSeriesWrapper.evaluatePrediction(mergedtimeseries, splitData.Item2, outfile);
            Console.WriteLine("Mean absolute error (MAE): " + errresults[0]);
            Console.WriteLine("Root mean squared error (RMSE): " + errresults[1]);
            Console.WriteLine("Mean absolute percentage error (MAPE): " + errresults[2]);
        }
Example #3
0
        public void ArmaFromExtData()
        {
            var arma = new ARMAModel(1, 1, _extData);

            Assert.IsTrue(arma.CanUseMLE());
            arma.FitByMLE(200, 100, 0, null);
            Write($"Sample mean: {_extData.SampleMean()}, From model: {arma.Mu} \n");
            Write($"Desc: {arma.Description}");
        }
Example #4
0
        public void ArmaSimulates()
        {
            var _arma        = new ARMAModel(1, 1);
            var simulateData = _arma.SimulateData(_dates, 22);

            Assert.NotNull(simulateData);
            Assert.IsTrue(simulateData.Count > 0);
            Write($"Sample mean: {simulateData.SampleMean()}");
            _arma.TheData = simulateData; // Feed back in
            _arma.FitByMLE(200, 100, 0, null);
            Write(_arma.Description);
        }
        protected override TimeSeries _BuildOutput(TimeSeries simulatedData, object userState = null)
        {
            ARMAModel model = new ARMAModel(mAROrder, mMAOrder);

            model.SetInput(0, simulatedData, null);
            //Maximum Likelihood Estimation
            model.FitByMLE(mNumberIterLDS, mNumberIterOpt, 0, null);   // first param is # low discrepancy sequence iterations, should be at least about 200
            // second param is # standard optimizer iterations, should be at least about 100

            //Compute the residuals
            model.ComputeResidualsAndOutputs();

            //model1.GetOutputName(3);
            //model1.Description;

            //Get the predicted values
            return(model.GetOutput(3) as TimeSeries);
        }
Example #6
0
        // forecasts values for the given dates from the model
        public TimeSeries predictARMA(List <DateTime> futureTimes, ARMAModel model)
        {
            var forecaster = new ForecastTransform();

            forecaster.FutureTimes = futureTimes.ToArray();

            forecaster.SetInput(0, model, null);
            forecaster.SetInput(1, model.TheData, null);

            var predictors = forecaster.GetOutput(0) as TimeSeries;

            // now we need to merge the forecast time series and the original time series with the original data

            var merger = new MergeTransform();

            merger.SetInput(0, model.TheData, null);
            merger.SetInput(1, predictors, null);

            merger.Recompute();

            return(merger.GetOutput(0) as TimeSeries);
        }
Example #7
0
        public bool AuxiliaryFunction(int index, out object output)
        {
            var approx = new ARMAModel(0, maxLag); // we should be able to get close with an MA
            var hlds   = new HaltonSequence(maxLag);

            double bestError        = double.MaxValue;
            var    bestMAPolynomial = Vector <double> .Build.Dense(maxLag);//new Polynomial(maxLag);

            for (int i = 0; i < 200000; ++i)
            {
                var cube    = hlds.GetNext();                            // this is the MA part to try in the ARMA
                var curCube = approx.ParameterToCube(approx.Parameters); // el. 0=mu, el. 1=d, el. 2=sigma
                for (int j = 0; j < maxLag; ++j)
                {
                    curCube[j + 3] = cube[j];
                }
                approx.SetParameters(approx.CubeToParameter(curCube));

                // now compare autocorrelation function (don't care about mean or sigma)
                var    acf   = approx.ComputeACF(maxLag, true);
                double error = 0;
                for (int j = 0; j < maxLag; ++j)
                {
                    error += Math.Abs(acf[j + 1] - Rho(j));
                }
                if (error < bestError)
                {
                    bestError        = error;
                    bestMAPolynomial = approx.GetMAPolynomial();
                }
            }

            approx.SetMAPolynomial(bestMAPolynomial);
            approx.Mu = Mu;
            output    = approx;
            return(true);
        }
Example #8
0
 public ArmaEngine()
 {
     armaModel = new ARMAModel(4, 2);
 }
Example #9
0
        // this method fits an ARMA model to the data and returns it, in the process testing for non-stationarity and calculating the orders of the
        // MA and AR terms of the model
        public ARMAModel buildARMAModel(DataObject[] series, double siglevel, int len = 50, bool print = true, bool log = false)
        {
            bool nonstationarity = testStationarity(series, siglevel);

            if (print)
            {
                Console.WriteLine("non-stationarity: " + nonstationarity.ToString());
            }

            int d = 0;

            if (nonstationarity)
            {
                d = 1;
            }

            var tSeries = series;

            //Difference the series
            if (d != 0)
            {
                double[] dcol = new double[tSeries.Length];
                for (int i = 0; i < dcol.Length; i++)
                {
                    dcol[i] = (tSeries[i].Value);
                }
                double[] xdiff = ArrayManipulation.diff(dcol);
                for (int i = dcol.Length - xdiff.Length; i < xdiff.Length; i++)
                {
                    tSeries[i] = new DataObject(tSeries[i].Date, xdiff[i]);
                }
            }

            var ts = new TimeSeries
            {
                Title       = "Time Series",
                Description = "TS Description"
            };

            for (int i = 0; i < series.GetLength(0); i++)
            {
                ts.Add(tSeries[i].Date, (tSeries[i].Value), false); //datetime, value, false
            }

            if (log)
            {
                //log transform the time series
                var logTransform = new LogTransform();
                logTransform.SetInput(0, ts, null);
                logTransform.Recompute();
                ts = logTransform.GetOutput(0) as TimeSeries;
            }

            //Use ACF and PACF to find ARMA parameters
            var highInterval = 1.96 / Math.Sqrt(series.Length);
            var acf          = ts.ComputeACF(20, false);
            int p            = 1;
            var low          = acf[0];

            for (int i = 0; i < acf.Count; i++)
            {
                if (Math.Min(low, acf[i]) <= highInterval && highInterval < Math.Max(acf[i], low))
                {
                    p = i;
                    if (p != 0)
                    {
                        p--;
                    }
                    if (p == 0)
                    {
                        p = 1;
                    }
                    break;
                }
                low = acf[i];
            }
            var pacf = TimeSeries.GetPACFFrom(acf);
            int q    = 1;

            low = pacf[0];
            for (int i = 0; i < pacf.Count; i++)
            {
                if (Math.Min(low, pacf[i]) <= highInterval && highInterval < Math.Max(pacf[i], low))
                {
                    q = i;
                    if (q != 0)
                    {
                        q--;
                    }
                    if (q == 0)
                    {
                        q = 1;
                    }
                    break;
                }
                low = pacf[i];
            }
            if (p > 4)
            {
                p = 4;
            }
            if (q > 4)
            {
                q = 4;
            }
            if (print)
            {
                Console.WriteLine("p: " + p.ToString() + " q: " + q.ToString());
                Console.WriteLine("Fitting the model...");
            }
            var model = new ARMAModel(p, q);

            model.TheData = ts;
            Stopwatch watch = new Stopwatch();

            watch.Start();
            model.FitByMLE(200, 100, 0, null);
            watch.Stop();
            if (print)
            {
                Console.WriteLine("Model took " + watch.Elapsed.TotalSeconds.ToString() + " seconds to fit parameters to the data.");
                Console.WriteLine("Model has been fitted.");
            }

            return(model);
        }
 public ArmaEngine()
 {
     armaModel = new ARMAModel(4, 2);
 }
Example #11
0
        // given a file, x attr, y attr, date delimiter, has time boolean, how many values to include in the model, how many to predict,
        // whether the data should be reversed to have the dates increasing, and the significance level for the stationarity test,
        // the predicted values, the actual values, and the MAE, RMSE, and MAPE errors.
        public void forecasttest(string file, string outfile, string xattr, char delimiter, bool hastime, bool change, double inmodel, double numpredict, bool reverse, double siglevel, bool log)
        {
            CSVReader reader = new CSVReader();

            string[] headers = reader.getHeaders(file, ',');
            int      xindex  = -1;

            for (int j = 0; j < headers.Length; j++)
            {
                if (String.Compare(headers[j], xattr) == 0)
                {
                    xindex = j;
                }
            }
            List <String[]> data = new List <String[]>();

            data = reader.getData(xindex, 0, file, ',', hastime);
            if (numpredict < 1)
            {
                numpredict = (int)(data.Count * numpredict);
            }
            if (inmodel < 1)
            {
                inmodel = (int)(data.Count * inmodel);
            }
            int trainnum = (int)inmodel;

            Console.WriteLine("Model will contain " + trainnum.ToString() + " events.");
            List <double>     predicted = new List <double>();
            TimeSeriesWrapper ts        = new TimeSeriesWrapper();

            DataObject[] series = new DataObject[1];
            if (reverse)
            {
                data.Reverse();
                series = ts.getSeries(data, trainnum, change);
            }
            else
            {
                series = ts.getSeries(data, trainnum, change);
            }
            ARMAModel model = ts.beginARMAProcess(series, siglevel, -1, log: log);

            DataObject[]    Y           = series;
            List <DateTime> futureTimes = new List <DateTime>();
            int             totaldata   = trainnum + (int)numpredict;
            DateTime        last        = ((TimeSeries)model.TheData).GetLastTime();

            Console.WriteLine(last.ToString());
            DataObject[] yactual = ts.getSeries(data, (int)numpredict, change, start: trainnum);
            for (int t = 0; t < yactual.Length; ++t)
            {
                futureTimes.Add(yactual[t].Date);
            }
            var mergedtimeseries = ts.predictARMA(futureTimes, model);

            double[] errresults = TimeSeriesWrapper.evaluatePrediction(mergedtimeseries, yactual, futureTimes, outfile, trainnum);
            Console.WriteLine("Mean absolute error (MAE): " + errresults[0].ToString());
            Console.WriteLine("Root mean squared error (RMSE): " + errresults[1].ToString());
            Console.WriteLine("Mean absolute percentage error (MAPE): " + errresults[2].ToString());
        }