//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** @author John Miller * @version 1.6 * @date Sat Jun 13 01:27:00 EST 2017 * @see LICENSE (MIT style license file). * * @title Test: Economics Domain using ARIMA family */ package scalation.analytics package forecaster import scalation.linalgebra.{MatrixD, VectoD, VectorD} import scalation.plot.Plot import scalation.stat.Statistic import scalation.util.banner import ActivationFun._ import ImputeMean.{impute, setMissVal} //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** The `ExampleEcon2` object tests various prediction and forecasting techniques * on daily economic/finance time-series data. * > runMain scalation.analytics.forecaster.ExampleEcon2 */ object ExampleEcon2 extends App { val tech = Set ("RandomWalk", "SimpleExpSmoothing", "QuadSpline") val MISSING = -999999 // missing value val xyr = MatrixD (BASE_DIR + "ENERGY20200603.csv", 1) // val xyr = MatrixD (BASE_DIR + "ENERGY_DATA.csv", 1) // val xyr = MatrixD (BASE_DIR + "MERGED_DATA_7_25.csv", 1) // val xyr = MatrixD (BASE_DIR + "RESEARCH_DATA.csv", 1) println (s"xyr.dim1 = ${xyr.dim1}, xy.dim2 = ${xyr.dim2}") val xy = xyr.sliceCol (2, xyr.dim2) // setMissVal (MISSING) // var xy = impute (xyr) // * 100.0 for (j <- xy.range2) { banner (s"column $j") val y = xy.col (j) println (s"ymean = ${y.mean}, ymin = ${y.min()}, ymax = ${y.max()}") for (i <- y.range if y(i) == MISSING) println (s"i = $i, y(i) = ${y(i)}}") for (i <- y.dim - 5 until y.dim) println (s"i = $i, y(i) = ${y(i)}}") } // for // xy = xy.slice (0, 200) // comment out for all rows val _1 = VectorD.one (xy.dim1) // column of all ones println (s"xy.dim1 = ${xy.dim1}, xy.dim2 = ${xy.dim2}") // forecast column 0 using columns 1-7 val RESPONSE = 0 // for ENERGY_DATA.csv val FEATURE1 = 1 // for ENERGY_DATA.csv val FEATURE2 = 7 // for ENERGY_DATA.csv val y = xy.col (RESPONSE) val x = xy.sliceCol (FEATURE1, FEATURE2) val t = VectorD.range (0, y.dim) println (s"x.dim1 = ${x.dim1}, x.dim2 = ${x.dim2}") val rescaled = false // whether to rescale data val h = 10 // forecasting horizon //:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: /** Test the model. * @param modName the name of the model to test * @param p the order of the model (number of values to use in forecasts) * @param mod the model to test * @param kt the retraining frequency * @param h the forecasting horizon */ def test (modName: String, p: Int, mod: ForecasterVec, kt: Int = h, h: Int = h): Unit = { banner (s"Test $modName") if (mod.isInstanceOf [SimpleExpSmoothing]) { val ses = mod.asInstanceOf [SimpleExpSmoothing] ses.toggleOpt (); ses.reset (1.05) } // if mod.train (null, y).eval () val yf = mod.forecastAll (h, p) // forecast for all times and horizons for (k <- 1 to h) { banner (s"$modName: forecasting horizon h = $k") val yf_k = yf(k) if (y.dim != yf_k.dim) flaw ("test", s"y.dim = ${y.dim} != yf_k.dim = ${yf_k.dim}") mod.evalf (y, yf_k) println (mod.report) new Plot (null, y, yf_k, s"$modName in sample horizon $k: y and yf", true) val stats = SimpleRollingValidation.crossValidate2 (mod, kt, k) // val stats = RollingValidation.crossValidate2 (mod, kt, k) // Fit.showQofStatTable (stats) } // for } // test if (tech contains "NullModel") test ("NullModel", 1, if (rescaled) NullModel (y) else new NullModel (y)) if (tech contains "RandomWalk") test ("RandomWalk", 1, if (rescaled) RandomWalk (y) else new RandomWalk (y)) if (tech contains "SimpleExpSmoothing") test ("SimpleExpSmoothing", 1, if (rescaled) SimpleExpSmoothing (y) else new SimpleExpSmoothing (y)) if (tech contains "QuadSpline") test ("QuadSpline", 1, if (rescaled) QuadSpline (y) else new QuadSpline (y)) if (tech contains "MovingAverage") for (q <- 1 to 2) { MovingAverage.hp("q") = q.toDouble test ("MovingAverage", q, if (rescaled) MovingAverage (y) else new MovingAverage (y)) } // for if (tech contains "MovingAverageD") for (q <- 1 to 10) { MovingAverage.hp("q") = q.toDouble test ("MovingAverageD", q, if (rescaled) MovingAverageD (y) else new MovingAverageD (y)) } // for if (tech contains "AR") for (p <- 1 to 6) { ARMA.hp("p") = p.toDouble test (s"AR($p)", p, if (rescaled) AR (y) else new AR (y)) } // for if (tech contains "MA") for (q <- 1 to 6) { ARMA.hp("q") = q.toDouble test (s"MA($q)", q, if (rescaled) MA (y) else new MA (y)) } // for val q = 1 if (tech contains "ARMA") { ARMA.hp("q") = q.toDouble for (p <- 1 to 2) { banner (s"ARMA ($p, $q)") ARMA.hp("p") = p.toDouble test (s"ARMA($p, $q)", p, null) // if (rescaled) ARMA (y) // FIX - ARMA needs to extend ForecasterVec // else new ARMA (y)) } // for } // if } // ExampleEcon2 object