Exemplo n.º 1
0
        public void trainingEnsemble(List<timeSeries> tslocal, forecastSettings _fs, bool additionalTraining)
        {
            trainingSet = new List<StructuredDataSet>();
            for (int ts = 0; ts < n_timestamps; ts++)
            {
                //create training set

                //Console.WriteLine("train nns for timestamp = " + ts.ToString() + " out of 95");
                trainingSet.Add(new StructuredDataSet());
                cvSet.Add(new StructuredDataSet());

                double valueMax = 0;
                double valueMin = double.MaxValue;
                for (int i = 0; i < tslocal[ts].timeseries.Count; i++)
                {
                    //if (tslocal[ts].timeseries[i] == 0)
                    {
                        var value = tslocal[ts].timeseries[i];
                        if (value > valueMax) valueMax = value;
                        if (value < valueMin) valueMin = value;
                    }
                }

                maxValue[ts] = valueMax;
                minValue[ts] = 0.0;// valueMin;//_ts.timeseries.Average() / maxValue; //

                maxValueT[ts] = tslocal[ts].temperature.Max();
                meanValueT[ts] = 0.0;//_ts.timeseries.Average() / maxValue; //

                trainingSet[ts].Pairs = new List<DataPair>();

                //преобразуем то, что нужно в выборки данных.
                //формируем trainingset
                for (int time = _fs.energyLags.Max(); time < tslocal[ts].timeseries.Count(); time++)
                //var time = tslocal[ts].timeseries.Count - 1;
                {
                    //if (tslocal[ts].outlierLabel[time] == 0)
                    {
                        DataPair trainingPair = new DataPair();

                        trainingPair.InputVector = new List<double>();
                        trainingPair.InputVector = createInputVector(time, tslocal[ts], _fs, maxValue[ts], minValue[ts],
                                                                     1, maxValueT[ts], meanValueT[ts], false);

                        trainingPair.OutputVector = new List<double>();
                        trainingPair.OutputVector = createOutputVector(time, tslocal[ts], _fs, maxValue[ts],
                                                                       minValue[ts]);
                        //trainingPair.OutputVector.Add(_ts.timeseries[i] / maxValue[counter] - minValue[counter]);

                        if (trainingPair.InputVector != null)
                            trainingSet[ts].Pairs.Add(trainingPair);
                    }
                }

                //do training

                if (trainingSet[ts].Pairs.Any())
                {
                    var mlNN = new MultiLayersNN(trainingSet[ts].Pairs[0].InputVector.Count, trainingSet[ts].Pairs[0].OutputVector.Count, 4, new[] { trainingSet[ts].Pairs[0].InputVector.Count, 8, 8, trainingSet[ts].Pairs[0].OutputVector.Count });
                    mlNN.trainNetwork(trainingSet[ts], 1000, 0.1, true);

                    int errorsNumber = mlNN.absoluteErrors.Count;

                    for (int i = 0; i < errorsNumber; i++)
                    {
                        mlNN.absoluteErrors[i] = (mlNN.absoluteErrors[i] * (maxValue[ts] - minValue[ts]) + minValue[ts]);
                    }

                    if (mlnset.Count <= ts)
                    {
                        mlnset.Add((mlNN));
                    }
                    else
                    {
                        mlnset[ts] = mlNN;
                    }
                }

            }
        }
        /// <summary>
        /// Тренировка модели.
        /// </summary>
        /// <param name="source">Подготовленный список значений для тренировки. 
        /// "Подготовленность" заключается в том, что каждое значение списка содержит все значения в соответствующее время суток.
        /// Например, source[0] содержит все значения энергопотребления в 00:00, source[1] - в 00:15, и так далее. В данном примере длина списка будет равна 96.</param>
        /// <param name="settings">Настройки прогнозирования.</param>
        /// <param name="additionalTraining">Производится ли дообучение модели.</param>
        public void Train(List<TimeSeries> source, ForecastSettings settings, bool additionalTraining)
        {
            var trainSet = new List<StructuredDataSet>();
            var cvSet = new List<StructuredDataSet>();

            for (int i = 0; i < timestampNumber; i++)
            {
                trainSet.Add(new StructuredDataSet());
                cvSet.Add(new StructuredDataSet());

                double valueMax = 0;
                double valueMin = double.MaxValue;
                for (int day = 0; day < source[i].timeseries.Count; day++)
                {
                    var value = source[i].timeseries[day];
                    valueMax = Math.Max(value, valueMax);
                    valueMin = Math.Min(value, valueMin);
                }

                maxValues[i] = valueMax;
                minValues[i] = valueMin;

                trainSet[i].Pairs = new List<DataPair>();

                //преобразуем то, что нужно в выборки данных.
                //формируем trainingset
                for (int time = settings.energyLags.Max(); time < source[i].timeseries.Count(); time++)
                {
                    DataPair trainingPair = new DataPair();

                    trainingPair.InputVector = createInputVector(time, source[i],
                        settings, maxValues[i], minValues[i], 1);

                    trainingPair.OutputVector = createOutputVector(time, source[i],
                        maxValues[i], minValues[i]);

                    if(trainingPair.InputVector != null)
                        trainSet[i].Pairs.Add(trainingPair);
                }

                if (trainSet[i].Pairs.Any())
                {
                    var neuralNetwork = new MultiLayersNN(
                        trainSet[i].Pairs[0].InputVector.Count,
                        trainSet[i].Pairs[0].OutputVector.Count,
                        4,
                        new[]
                            {
                                trainSet[i].Pairs[0].InputVector.Count,
                                8, 8,
                                trainSet[i].Pairs[0].OutputVector.Count
                            });

                    neuralNetwork.trainNetwork(trainSet[i], 1000, 0.1, true);

                    for (int e = 0; e < neuralNetwork.absoluteErrors.Count; e++)
                    {
                        //денормализация
                        neuralNetwork.absoluteErrors[e] = (neuralNetwork.absoluteErrors[e] * (maxValues[i] - minValues[i]) + minValues[i]);
                    }

                    if (networkSet.Count <= i)
                        networkSet.Add(neuralNetwork);
                    else
                        networkSet[i] = neuralNetwork;
                }
            }
        }
        protected override DataStreamUnit[] _Execute(DataStreamUnit[] input)
        {
            var value = input[0];

            value.Values["Number"] = counter;
            var waitUntil = DateTime.Parse(value.Values["EnergyLag"].ToString());
            var dateTime = DateTime.Parse(value.Values["TimeStamp"].ToString());
            if (dateTime > waitUntil)
            {
                List<double> absoluteErrors = new List<double>();
                neuralNetwork = parameters["NeuralNetwork"] as MultiLayersNN;
                if (neuralNetwork != null)
                {
                    absoluteErrors = neuralNetwork.absoluteErrors;
                }

                var realValue = Double.Parse(value.Values["Value"].ToString());
                var predictedValue = value.Values["PredictedValue"] != null ? Double.Parse(value.Values["PredictedValue"].ToString()) : (double?)null;

                if (predictedValue != null)
                {
                    var absoluteError = Math.Abs(predictedValue.Value - realValue);

                    if (realValue != 0)
                    {
                        counter++;
                        mapeSum += Math.Abs(absoluteError/realValue);
                    }

                    testCounter++;
                    value.Values["MAPE"] = mapeSum/testCounter;
                }

                D = (int)Math.Round(absoluteErrors.Count / 1.0, MidpointRounding.AwayFromZero);

                value.Values["D"] = D;

                double errorSum = 0;
                for (int i = absoluteErrors.Count - D; i < absoluteErrors.Count; i++)
                {
                    errorSum += absoluteErrors[i];
                }
                var mu = errorSum / D;

                value.Values["mu"] = mu;

                double sum = 0;
                for (int i = makeNonNegative(absoluteErrors.Count - D) + 1; i < absoluteErrors.Count; i++)
                {
                    sum += Math.Pow(absoluteErrors[i] - mu, 2);
                }

                var resultError = Math.Sqrt(sum) / D;

                value.Values["Error"] = resultError;

            }
            else
            {
                value.Values["MAPE"] = null;
            }
            return input;
        }