class StatiStica::LinearRegression

Public Class Methods

new(dx:, dy: nil) click to toggle source
# File lib/stati_stica/linear_regression.rb, line 6
def initialize(dx:, dy: nil)
  if dx.all? {|x| x.class == Array}
    @number_of_series = dx.size
    @series_size = dx.first.size
  else
    @number_of_series = 1
    @series_size = dx.size
  end

  dy,dx = dx,axis unless dy
  raise ArgumentError unless dx.size == dy.size

  @dx = dx
  @dy = dy.flatten

  sxx = sxy = sx = sy = 0
  
  dx.flatten.zip(dy.flatten).each do |x,y|
    sxy += x * y 
    sxx += x ** 2
    sx  += x
    sy  += y
  end

  @slope  = Float(( dx.size * sxy - sx * sy ) / ( dx.size * sxx - sx * sx ))
  @offset = Float((sy - @slope * sx) / dx.size)
end

Public Instance Methods

confidence_bounds(x, probability, error = standard_error) click to toggle source
# File lib/stati_stica/linear_regression.rb, line 69
def confidence_bounds(x, probability, error = standard_error)
  bounds = Array(x).each_with_object(Array.new) do |x, bounds|
    bounds << [lower_confidence_bound(x, probability, error), upper_confidence_bound(x, probability, error)]
  end

  bounds.one? ? bounds.first : bounds
end
fit() click to toggle source
# File lib/stati_stica/linear_regression.rb, line 42
def fit
  @dx.map{ |value| predict(value) }
end
lower_confidence_bound(x, probability, error = standard_error) click to toggle source
# File lib/stati_stica/linear_regression.rb, line 53
def lower_confidence_bound(x, probability, error = standard_error)
  bounds = Array(x).each_with_object(Array.new) do |x, bounds|
    bounds << predict(x) - confidence_level_at(x, probability, error)
  end

  bounds.one? ? bounds.first : bounds
end
offset() click to toggle source
# File lib/stati_stica/linear_regression.rb, line 38
def offset
  @offset
end
slope() click to toggle source
# File lib/stati_stica/linear_regression.rb, line 34
def slope
  @slope
end
standard_error() click to toggle source
# File lib/stati_stica/linear_regression.rb, line 46
def standard_error
  raise ArgumentError unless @series_size > 2

  sum_y = @dy.zip(self.fit).map{ |y, fit| (fit - y) **2 }.inject(0, &:+)
  Math.sqrt(sum_y / (@series_size - 2))
end
upper_confidence_bound(x, probability, error = standard_error) click to toggle source
# File lib/stati_stica/linear_regression.rb, line 61
def upper_confidence_bound(x, probability, error = standard_error)
  bounds = Array(x).each_with_object(Array.new) do |x, bounds|
    bounds << predict(x) + confidence_level_at(x, probability, error)
  end

  bounds.one? ? bounds.first : bounds
end

Private Instance Methods

axis() click to toggle source
# File lib/stati_stica/linear_regression.rb, line 79
def axis
  (0...@series_size).to_a * @number_of_series
end
confidence_level_at(x, probability, error = standard_error) click to toggle source
# File lib/stati_stica/linear_regression.rb, line 87
def confidence_level_at(x, probability, error = standard_error)
  raise ArgumentError unless @series_size > 2
  
  TDistribution.value_for(probability, degree_of_freedom) * error * last(x)
end
degree_of_freedom() click to toggle source
# File lib/stati_stica/linear_regression.rb, line 101
def degree_of_freedom 
  (@series_size - 2) * @number_of_series
end
last(x) click to toggle source
# File lib/stati_stica/linear_regression.rb, line 93
def last(x)
  mean = StatiStica::Mean.new(@dx).value
  
  diff_from_mean_square = (x - mean) **2
  sum_squares_deviations = @dx.map{ |x| (x - mean) **2 }.inject(0, &:+)
  Math.sqrt((1.0 / @series_size) + (diff_from_mean_square / sum_squares_deviations))
end
predict(x) click to toggle source
# File lib/stati_stica/linear_regression.rb, line 83
def predict(x)
  @slope * x + @offset
end