title: python linear regression change point detection
body: <p>I am trying to detect drift from a list of given stream of one dimensional data. If there is no trend in the data, I am expecting <code>0 &lt;= confidence score &lt;= 0.20</code>, but if drift detected, I am expecting <code>0.90 &lt;= confidence score &lt;= 1</code>.</p>
  <p>I am attaching the Python 3.x code snippet I am using, along with my calculations by hand (the picture in the end).</p>
  <pre><code>import numpy as np
  from univariate import UnivariateAnalysis
  from scipy import stats
  
  
  class UnivariateDriftAnalysis:
      ''' This technique looks for a trend in recent data using linear
      regression as a statistical test that the trend is non-zero
      Currently, this uses a fixed window length, but future versions might
      incorporate a search over a range of window lengths
      '''
  
      def __init__(self, n_window, p=0.01):
          '''
          n_window - (int) length of data history to look for a trend
          p - (int) desired confidence or false positive rate.
              p=.05 means that alarms will be raised when there is &lt;5% chance
              that there is no trend
          '''
          self.n_window = n_window
          self.p = p
  
      def drift_detected(self, data) -&gt; list:
          ''' Returns an array, x, of probabilities that the slope of the data is
          not zero. i.e., the confidence that there is a slope.
          x[i] corresponds to the slope of data[i-n_window:i]
          The first n_window values of x are np.NaN
          '''
          n = len(data)
          y = []
          x0 = np.arange(n)
          result: list = [np.NaN] * self.n_window
          i = 0
          for d in data:
              y.append(d)
              if len(y) &lt; self.n_window:
                  # if max_history_samples &lt; window_length
                  continue
              y = y[-self.n_window:]
              x = x0[i:i + self.n_window]
              p_value = stats.linregress(x, y).pvalue
              # slope, intercept, r_value, p_value, std_err = rez
              result.append(1-p_value)
              i += 1
          return result
  
      def update(self, data) -&gt; None:
          ''' this function is designed to handle live stream of data'''
          scores = self.alarm_score(data)
          alarms = [r &lt; self.p for r in alarm_scores]
          # some other stuff
  
  # Test
  np.random.seed(100)
  n_window = 10
  lr = LinearRegressionSPC(n_window=n_window, p=.01)
  data = np.concatenate([np.random.randint(24, 47, 1500), np.random.randint(1000, 4000, 2000), np.random.randint(1, 5, 500)])
  score = lr.alarm_score(data)
  print(result[n_window:])  # lowest: 0 highest: 0.9953301824956942
  </code></pre>
  <p><strong>Question:</strong></p>
  <ul>
  <li>What am I missing? Why the confidence score is as high as 0.9953!?</li>
  <li>My end objective is to define <code>p value</code> for a given data array to calculate drift existence confidence.</li>
  </ul>
  <p><a href="https://i.stack.imgur.com/Gfk2e.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Gfk2e.png" alt="p value calculation by hand screenshot" /></a></p>