статистика временных рядов algrothim для генерации рекурсивной структуры данных в C # - PullRequest
0 голосов
/ 15 марта 2012

У меня есть список значений, может быть double или DateTimes.

15, 36, -7, 12, 8

Это данные TimeSeries, поэтому порядок имеет значение. Также в списке всего от 3 до 6 значений, поэтому мы не говорим о большом наборе данных.

Скажите, что я хочу получить статистику по ним, например, отношения.

15/36, 36 / -7, -7/12, 12/8 == .417, -5,14, -.583, 1,5

, а затем отношения коэффициентов

.417 / -5,14, -5,14 / -. 583, -.583 / 1,5

.. и так далее.

Мне также нужно генерировать статистику для каждого значения против каждого значения в прошлом.

12/8, -7/8, 36/8, 15/8

12 / -7, 12/36, 12/15

...

Также необходимо соотношение каждого значения к среднему значению предыдущих значений.

ср (12, -7) / 8, ср (12, -7,36) / 8

Когда данные установлены в DateTime, будет использоваться TimeSpan. Также нужен уклон, средний уклон, тренд коэффициентов, тренд уклона и т. Д.

В основном пытается получить как можно больше релевантных данных. Поскольку это временная серия, соответствующие данные ограничены статистикой по значениям слева от каждого, а также по первому и последнему значению.

не уверен, что я ищу шаблон проектирования, математическую формулу или концепции анализа TimeSeries.

Мой текущий дизайн - делать это поэтапно. Класс для отношений каждой пары, затем класс для отношений ... и т.д. Ищет что-то более абстрактное.

Существует ли шаблон проектирования, математическая формула или концепция TimeSeries, которые позволили бы мне написать более абстрактное решение моей проблемы?

Спасибо, переполнение стека!

1 Ответ

2 голосов
/ 15 марта 2012

Я думаю, вам нужно начать с абстрагирования списка чисел временного ряда.Кажется, что каждый набор вычислений должен проходить по-разному.

interface IMyList<T>
{
    void SetList(IList<T> series);

    bool IsDone();
    T GetOperand1();
    T GetOperand2();
    T Calculate(T op1, T op2);
    void SetResult(T result);
    void Next();

    Dictionary<int, IList<T>> GetResults();
}

Когда вы реализуете каждый IMyList в каждом из ваших классов, вы встраиваете в класс именно то, как должен проходиться список.Я реализовал ваш первый пример.Также обратите внимание, что я не использовал рекурсию.Для каждого типа обхода и вычисления вы можете создать класс, подобный этому:

public class Ratio : IMyList<double>
{
    private Dictionary<int, IList<double>> _results;
    private int _currentSeries;
    private int _seriesResults;
    private int _op1Index;
    private int _op2Index;
    private bool _bDone;

    public Ratio()
    {
        _op1Index = 0;
        _op2Index = 1;
        _currentSeries = 0;
        _seriesResults = 1;
    }

    public void SetList(IList<double> series)
    {
        // the zero entry is the first result set
        _results = new Dictionary<int, IList<double>>();
        _results.Add(_currentSeries, series);
        _results.Add(_seriesResults, new List<double>());
    }

    public bool IsDone()
    {
        return _bDone;
    }

    public double GetOperand1()
    {
        return _results[_currentSeries][_op1Index];
    }

    public double GetOperand2()
    {
        return _results[_currentSeries][_op2Index];
    }

    public double Calculate(double op1, double op2)
    {
        return op1 / op2;
    }

    public void SetResult(double result)
    {
        _results[_seriesResults].Add(result);
    }

    public void Next()
    {
        _op1Index++;
        _op2Index++;

        if (_op2Index >= _results[_currentSeries].Count())
        {
            if (_results[_seriesResults].Count == 1)
            {
                _bDone = true;
            }
            else
            {
                _currentSeries++;
                _seriesResults++;
                _results.Add(_seriesResults, new List<double>());
                _op1Index = 0;
                _op2Index = 1;
            }
        }
    }

    public Dictionary<int, IList<double>> GetResults()
    {
        return _results;
    }
}

Чтобы применить это в действии, код будет:

        List<double> firstList = new List<double>() { 15, 36, -7, 12, 8 };

        // the following section could be refactored further by putting the classes
        // in a list of IMyList and then looping through it
        var rat = new Ratio();
        rat.SetList(firstList);
        while (!rat.IsDone())
        {
            double op1 = rat.GetOperand1();
            double op2 = rat.GetOperand2();
            rat.SetResult(rat.Calculate(op1, op2);
            rat.Next();
        }
        var results = rat.GetResults();
...