class LinearRegressionTrend::Calculator

Attributes

intercept[RW]
slope[RW]

Public Class Methods

new(y_values, non_negative: false) click to toggle source

Pass in an array of values to get the regression on

# File lib/linear_regression_trend.rb, line 14
def initialize(y_values, non_negative: false)
  @y_values = y_values
  @size     = @y_values.size
  @x_values = (1..@size).to_a
  @no_negs  = non_negative

  #initialize everything to 0
  sum_x  = 0
  sum_y  = 0
  sum_xx = 0
  sum_xy = 0

  # calculate the sums
  @y_values.zip(@x_values).each do |y, x|
    sum_xy += x*y
    sum_xx += x*x
    sum_x  += x
    sum_y  += y
  end

  # calculate the slope
  @slope     = 1.0 * ((@size * sum_xy) - (sum_x * sum_y)) / ((@size * sum_xx) - (sum_x * sum_x))
  @intercept = 1.0 * (sum_y - (@slope * sum_x)) / @size
end

Public Instance Methods

forecast_next(n = 1) click to toggle source
# File lib/linear_regression_trend.rb, line 44
def forecast_next(n = 1)
  start_val = @size + 1
  stop_val  = @size + n.to_i

  (start_val..stop_val).to_a.map { |x| predict(x) }
end
next() click to toggle source

Get the “next” value if the sequence was continued one more element

# File lib/linear_regression_trend.rb, line 64
def next
  predict (@size + 1)
end
predict(x) click to toggle source

Get the Y value for any given X value from y = mx + b, or y = slope * x + intercept

# File lib/linear_regression_trend.rb, line 54
def predict(x)
  predicted = @slope * x + @intercept

  return 0 if predicted < 0 and @no_negs

  predicted
end
stabilize_over_all() click to toggle source

Determine the target needed to stabilize the slope back to 0, assuming slope is negative. The target returned will be the number needed to have stabilized slope inclusive of all values in the set

# File lib/linear_regression_trend.rb, line 73
def stabilize_over_all
  stabilize @y_values
end
stabilize_over_n_values(n) click to toggle source

Determine the target needed to stabilize the slope back to 0, assuming slope is negative. The target returned will be the number needed to have stabilized slope over a set of values of size n (including the target value

# File lib/linear_regression_trend.rb, line 83
def stabilize_over_n_values(n)
  values = []
  values = @y_values.last(n-1) if n - 1 >= 0

  stabilize values
end
trend() click to toggle source

Get the y-axis values of the trend line

# File lib/linear_regression_trend.rb, line 40
def trend
  @x_values.map { |x| predict(x) }
end

Private Instance Methods

stabilize(values) click to toggle source
# File lib/linear_regression_trend.rb, line 92
def stabilize(values)
  n      = values.length
  sum    = 0
  target = 0

  values.each_with_index do |value, i|
    sum += (n - (2 * i)) * value
  end

  target = 1.0 * sum / n if n > 0
  target
end