| Signature | Description | Parameters |
|---|---|---|
#include <DataFrame/DataFrameMLVisitors.h> template<arithmetic T, typename I = unsigned long> struct LSTMForecastVisitor; // ------------------------------------- template<typename T, typename I = unsigned long> using lstm_v = LSTMForecastVisitor<T, I>; |
This is a "single action visitor", meaning it is passed the whole data vector in one call and you must use the single_act_visit() interface. Long Short-Term Memory (LSTM) forecasting is a technique that uses a type of recurrent neural network to predict future values in a time series, excelling at capturing long-term dependencies in sequential data. LSTMs are effective for forecasting because their architecture, featuring a memory cell and three gates, allows them to remember and process information from past time steps, overcoming the vanishing gradient problem that affects traditional recurrent neural networks. This makes them well-suited for predicting future trends in fields like stock prices, streamflow, and groundwater levels. This visitor has the following methods to get result: get_result(): Retruns a vector of forecasted datapoints for the next periods periods ahead.
explicit
LSTMForecastVisitor(long input_size = 1,
long hidden_size = 32,
long seq_len = 10,
long batch_size = 1,
long epochs = 20,
value_type learning_rate = 0.001,
long periods = 3,
unsigned int seed = static_cast
|
T: Column data type. I: Index type. |
static void test_LSTMForecastVisitor() { std::cout << "\nTesting LSTMForecastVisitor{ } ..." << std::endl; std::vector<unsigned long> idxvec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; std::vector<double> col1 = { 266.0, 145.9, 183.1, 119.3, 180.3, 168.5, 231.8, 224.5, 192.8, 122.9, 336.5, 185.9, 194.3 }; std::vector<double> oscil = { 1.5, 1.8, 1.62, 1.78, 1.5, 1.68, 1.6, 1.8, 1.71, 1.9, 1.78, 1.84, 1.69 }; std::vector<double> constant = { 10.56, 10.56, 10.56, 10.56, 10.56, 10.56, 10.56, 10.56, 10.56, 10.56, 10.56, 10.56, 10.56 }; std::vector<double> increasing = { 10.56, 10.68, 10.78, 10.90, 11.01, 11.45, 11.99, 12.01, 12.21, 12.35, 12.67, 13.89, 14.01 }; std::vector<double> decreasing = { 10.56, 10.30, 10.12, 10.01, 9.80, 9.74, 9.41, 9.03, 9.0, 8.20, 8.01, 7.9, 7.55 }; MyDataFrame df; df.load_data(std::move(idxvec), std::make_pair("col1", col1), std::make_pair("oscil", oscil), std::make_pair("constant", constant), std::make_pair("increasing", increasing), std::make_pair("decreasing", decreasing)); lstm_v<double> lstm { 1, 40, 4, 1, 100, 0.001, 3, 123 }; df.single_act_visit<double>("col1", lstm); const auto result1 = lstm.get_result(); assert(result1.size() == 3); assert(std::fabs(result1[0] - 177.075) < 0.001); assert(std::fabs(result1[1] - 181.576) < 0.001); assert(std::fabs(result1[2] - 185.103) < 0.001); lstm_v<double> lstm2 { 1, 40, 4, 1, 1000, 0.001, 3, 123 }; df.single_act_visit<double>("oscil", lstm2); const auto result2 = lstm2.get_result(); assert(result2.size() == 3); assert(std::fabs(result2[0] - 1.7698) < 0.00001); assert(std::fabs(result2[1] - 1.64903) < 0.00001); assert(std::fabs(result2[2] - 1.74927) < 0.00001); df.single_act_visit<double>("constant", lstm); const auto result3 = lstm.get_result(); assert(result3.size() == 3); assert(std::fabs(result3[0] - 10.56) < 0.00001); assert(std::fabs(result3[1] - 10.56) < 0.00001); assert(std::fabs(result3[2] - 10.56) < 0.00001); lstm_v<double> lstm3 { 1, 100, 4, 1, 100, 0.001, 3, 123 }; df.single_act_visit<double>("increasing", lstm3); const auto result4 = lstm3.get_result(); // It doesn't see the pattern here // assert(result4.size() == 3); assert(std::fabs(result4[0] - 13.4408) < 0.0001); assert(std::fabs(result4[1] - 13.4358) < 0.0001); assert(std::fabs(result4[2] - 13.4193) < 0.0001); df.single_act_visit<double>("decreasing", lstm3); const auto result5 = lstm3.get_result(); // Strangely, it sees the pattern here // assert(result5.size() == 3); assert(std::fabs(result5[0] - 7.23448) < 0.00001); assert(std::fabs(result5[1] - 7.14929) < 0.00001); assert(std::fabs(result5[2] - 7.10167) < 0.00001); // Now some real data // StrDataFrame df2; try { df2.read("IBM.csv", io_format::csv2); } catch (const DataFrameError &ex) { std::cout << ex.what() << std::endl; ::exit(-1); } lstm_v<double> lstm4 { 1, 50, 4, 1, 100, 0.001, 4, 123 }; df2.single_act_visit<double>("IBM_Close", lstm4); const auto result6 = lstm4.get_result(); assert(result6.size() == 4); assert(std::fabs(result6[0] - 175.419) < 0.001); assert(std::fabs(result6[1] - 100.078) < 0.001); assert(std::fabs(result6[2] - 186.713) < 0.001); assert(std::fabs(result6[3] - 99.2631) < 0.0001); }