public double? Forecast(TimeSeries source, int horizon, ForecastSettings settings) { var i = source.timeseries.Count - 1; //это означает, что хотим получить прогноз для последнего значения в ряду var counter = i % timestampNumber; List<double> inputVector = createInputVector(i, source, settings, maxValues[counter], minValues[counter], timestampNumber); if (inputVector == null) return null; //не получилось if (networkSet.Count <= counter) return null; networkSet[counter].propagate(inputVector); var output = networkSet[counter].Outputs.First(); output = output*(maxValues[counter] - minValues[counter]) + minValues[counter]; return output; }
public onNeuralPredictionFilter(FilterParameters parameters, DateTime trainTill, DataExchange exchange = null) { this.exchange = exchange; this.waitUntil = trainTill; this.timeSeries = new TimeSeries(0); settings = new ForecastSettings(); for (int i = 0; i < 5; i++) { settings.energyLags.Add(i + 1); } model = new MultipleNeuralNetworksModel(); this.parameters = parameters; parameters.Values["model"] = model; }
/// <summary> /// Извлечь выходные данные для обучения. /// </summary> /// <param name="counter"></param> /// <param name="_ts"></param> /// <param name="_fs"></param> /// <param name="_maxValue"></param> /// <param name="_minValue"></param> /// <returns></returns> private List<double> createOutputVector(int counter, TimeSeries source, double maxValue, double minValue) { List<double> OutputVector = new List<double>(); var energyValue = source.timeseries[counter]; var normalizedValue = maxValue != minValue ? (energyValue - minValue) / (maxValue - minValue) : 0.5; OutputVector.Add(normalizedValue); return OutputVector; }
/// <summary> /// Извлечь входной вектор для обучения /// </summary> /// <param name="counter">Порядковый номер значения во временном ряду, которое будет прогнозироваться.</param> /// <param name="source">Временной ряд, из которого брать значения.</param> /// <param name="settings">Настройки прогнозирования.</param> /// <param name="_maxValue">Максимальное значение для данного времени суток.</param> /// <param name="_minValue">Минимальное значение для данного времени суток.</param> /// <param name="timestampNumber">Количество отсчетов в день.</param> /// <returns></returns> private List<double> createInputVector(int counter, TimeSeries source, ForecastSettings settings, double _maxValue, double _minValue, int timestampNumber) { //вычисляем нижнюю границу, т.е. минимальное количество ретроспективных значений, //необходимое для осуществления прогноза var minLength = settings.energyLags.Max() * timestampNumber; //если доступно значений меньше, чем нужно, то ничего не получится if (counter < minLength) return null; List<double> InputVector = new List<double>(); InputVector.Add(1.0); //это вот точно здесь нужно? зачем? for (int j = 0; j < settings.energyLags.Count; j++) { var energyValue = source.timeseries[counter - (settings.energyLags[j] * timestampNumber)]; var normalizedValue = _maxValue != _minValue ? (energyValue - _minValue)/(_maxValue - _minValue) : 0.5; InputVector.Add(normalizedValue); } return InputVector; }