Алгоритм рекурсивной сегментации временных рядов - PullRequest
3 голосов
/ 28 января 2012

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

    split(T [ta, tb ]) – split a time series T of length
    n from time ta to time tb where 0 ≤ a < b ≤ n
    1: Ttemp = ∅
    2: εmin = ∞;
    3: εtotal = 0;
    4: for i = a to b do
            5:εi = (pi − pi )^2 ;
            6:if εmin > εi then
                7:  εmin = εi ;
                8:  tk = ti ;
            9:end if
        10:εtotal = εtotal + εi ;
    11: end for
    12: ε = εtotal /(tb − ta );
    13: if t-test.reject(ε) then
            14:Ttemp = Ttemp ∪ split(T [ta , tk ]);
            15:Ttemp = Ttemp ∪ split(T [tk , tb ]);
        16: end if
    17: return Ttemp ;

Мой класс временных рядов выглядит следующим образом:

class MySeries{
      ArrayList<Date> time;
      Double[] value;
}

В приведенном выше алгоритме Ttemp является еще одним экземпляром временных рядов. Расчеты по строкам 4-12 предназначены для расчета ошибки.
Проблема в том, что я не могу реализовать рекурсию и объединение частей выше (строки 14 и 15). Мне не ясно, как выполнить рекурсию и создать объединение объектов MySeries.

************ EDIT *************** ***

class Segmentation{
    static MySeries series1 = new MySeries();    //contains the complete time series
    static HashSet<MySeries> series_set = new HashSet<MySeries>();    

    public static MySeries split(MySeries series, int start, int limit) throws ParseException{      
        if(limit-start < 3){     //get min of 3 readings atleast
        return null;
        }

    tTemp = MySeries.createSegment(series1, start, limit);

    double emin = 999999999, e,etotal=0, p, pcap;
    DescriptiveStatistics errors = new DescriptiveStatistics();

    for(int i=start;i<limit;i++){
        p = series1.y[i];
        pcap = series1.regress.predict(series1.x[i]);
        e = (p-pcap)*(p-pcap);
        errors.addValue(e);
        if(emin > e){
            emin = e;
            splitPoint = i;
        }
        etotal = etotal + e;
    }
    e = etotal/(limit-start);

    double std_dev_error = errors.getStandardDeviation();
    double tTstatistic = e/(std_dev_error/Math.sqrt(errors.getN()));

        if(ttest.tTest(tTstatistic, errors, 0.10)){
            union(split(series1, start, splitPoint));
            union(split(series1, splitPoint+1, limit));
        }
    return tTemp;
}

    static void union(MySeries ms){
        series_set.add(ms);    
    }
}

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

Ответы [ 2 ]

0 голосов
/ 26 июня 2013

Ваш εi всегда равен нулю!Таким образом, ваше утверждение if после εi = (pi - pi) ^ 2 всегда будет верным!

0 голосов
/ 07 июля 2012

Я не знаю, почему он попадает в бесконечный цикл

Легко узнать почему. Просто вставьте несколько операторов печати, чтобы увидеть, что происходит (или используйте отладчик). Например,

    if(ttest.tTest(tTstatistic, errors, 0.10)){
        System.out.printf("About to split %d .. %d .. %d%n", start, splitPoint, limit);
        union(split(series1, start, splitPoint));
        union(split(series1, splitPoint+1, limit));
    }
    else
        System.out.printf("Not splitting %d .. %d%n", start, limit);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...