# Change detection in circular data

Suppose I have a data set that represents circular data measured in degrees:

x <- c(rnorm(1000, 0, 10), rnorm(700, 110, 3), rnorm(1100, 230, 5)) %% 360


The R package circular provides a very nice way to represent that data, and a basic tool for detecting change points in it:

library(circular)
x <- circular(x, units='degrees')
cp <- change.point(x)


However, this particular algorithm is limited, because it's (in my experience) relatively inefficient, and it's limited to finding one change point at a time, so if multiple change points are present, a recursive approach is needed. This causes some difficulty in deciding when to terminate.

If a linear change point algorithm is used, it will have difficulty with x[1:1000] because some values will be close to 0 and some close to 360.

For linear data, I like the 'PELT' algorithm of Killick, Fearnhead, and Eckley (2011) implemented by the R package changepoint's cpt.mean() function. It's fast and seems to be pretty reliable. Has anyone looked at adapting this method to circular data?

Or other recommendations?

PELT can be applied to any test statistic which satisfies the assumptions in the paper. The PELT code is the same regardless of the cost function. The existing changepoint package implementation is in C. It is simply a case of coding up a new cost function that can be plugged into the existing PELT code instead of e.g.mll.mean for the PELT.mean.norm function in C.
Which test statistic from the change.point function were you interested in? I can then check if it satisfies the assumptions for PELT. If it does then it isn't a large job to code it up.
• To be honest I don't really know what change.point() is doing - it's an implementation of an algorithm given in a book, but the book is \$175 on Amazon. Luckily the code is open, but I haven't been able to look into it yet. Nor do I necessarily like its results yet, I just like the fact that it's circular. =) Sep 24, 2012 at 12:43
• Essentially, you just want to extend the single changepoint method to multiple changes. The easiest way to do this (not necessarily the best) is to implement Binary Segmentation. That is essentially a smart while loop which starts with the entire data, runs the change.point function then splits the data at the changepoint if one is identified. Then you run change.point again on the sub series. Repeat the above until no more changepoints are found. This is an approximate segmentation though compared to PELT which is exact. Sep 26, 2012 at 12:33