wangtengyao / ocd

online changepoint detection
5 stars 1 forks source link

ocd detector returning 0 for all test statistics #1

Open multimeric opened 3 years ago

multimeric commented 3 years ago

Following the examples in the user guide, I have come up with this code:

require('ocd')

# Takes a data frame, trains the detector on the burn-in set, then starts detecting
segment.ocd = function(data, burnin, alpha){
  det = ChangepointDetector(dim=ncol(data), method='ocd', beta=1, thresh=c(11.6, 179.5, 54.9))
  det = setStatus(det, 'estimating')
  for(i in 1:burnin){
    row = unlist(data[i,])
    det = getData(det, row)
  }

  detector = setStatus(det, 'monitoring')
  changepoints = list()
  for(i in (burnin+1):nrow(data)){
    row = unlist(data[i,])
    det = getData(det, row)
    chpt = status(detector)
    if (is.numeric(chpt)){
      changepoints[[length(changepoints)+1]] = chpt
    }
  }
  print(changepoints)
  print(statistics(det))
}

# Makes an p-dimensional data.frame that shifts after a certain point in time
get.changepoint = function(dims=2, pre.args=list(n=50, mean=0, sd=1), post.args=list(n=50, mean=2, sd=1)){
  columns = list()
  for (i in 1:dims){
    columns[[letters[i]]] = c(do.call(rnorm, pre.args), do.call(rnorm, post.args))
  }
  data.frame(columns)
}

chpt = get.changepoint(dims=10, post.args=list(n=50, mean=2, sd=1))
segment.ocd(chpt, burnin=20, alpha=0.1)

So, I create a dataset that has a mean shift from 0 to 2 at n=50. This should be fairly easy to detect, however the changepoints list that I obtain is always empty, and the test statistics vector contains only 0s. What am I doing wrong here?

yudongchen88 commented 3 years ago

In the second part of your segment.ocd function, detector should be changed into det (2 places). Then, you will see that the change is declared at time 31 (i.e. 50+1-burnin).