Class: RubyLinearRegression

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_linear_regression.rb

Overview

RubyLinearRegression

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRubyLinearRegression

Returns a new instance of RubyLinearRegression.



8
9
10
11
# File 'lib/ruby_linear_regression.rb', line 8

def initialize
  @mu = 0
  @sigma = 1
end

Instance Attribute Details

#muObject (readonly)

Returns the value of attribute mu.



6
7
8
# File 'lib/ruby_linear_regression.rb', line 6

def mu
  @mu
end

#sigmaObject (readonly)

Returns the value of attribute sigma.



6
7
8
# File 'lib/ruby_linear_regression.rb', line 6

def sigma
  @sigma
end

#thetaObject (readonly)

Returns the value of attribute theta.



6
7
8
# File 'lib/ruby_linear_regression.rb', line 6

def theta
  @theta
end

#xObject (readonly)

Returns the value of attribute x.



6
7
8
# File 'lib/ruby_linear_regression.rb', line 6

def x
  @x
end

#yObject (readonly)

Returns the value of attribute y.



6
7
8
# File 'lib/ruby_linear_regression.rb', line 6

def y
  @y
end

Instance Method Details

#compute_costObject

Compute the mean squared cost / error function



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/ruby_linear_regression.rb', line 33

def compute_cost
  # First use matrix multiplication and vector subtracton to find errors
  errors = (@x * @theta) - @y

  # Then square all errors
  errors = errors.map { |e| e * e  }

  # Find the mean of the square errors
  mean_square_error = 0.5 * (errors.inject{ |sum, e| sum + e }.to_f / errors.row_size)

  return mean_square_error
end

#load_training_data(x_data, y_data) ⇒ Object

Loads and normalizes the training data, must be called prior to training. Arguments:

x_data: (Two dimensiolnal array with the independent variables of your training data)
y_data: (Array with the dependent variables of your training data)


17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/ruby_linear_regression.rb', line 17

def load_training_data x_data, y_data

      # normalize the x_data
      x_data = normalize_data( x_data )

      # add 1 column to our data
      x_data = x_data.map { |r| [1].concat(r) }

      # build our x Matrix & y Vector
      @x = Matrix.rows( x_data )
      @y = Matrix.rows( y_data.collect { |e| [e] } )

      @theta = Matrix.zero(@x.column_count, 1)
end

#predict(data) ⇒ Object

Makes a prediction based on your trained model. train_normal_equation must be called prior to making a prediction.

Arguments:

data: (Array of independent variables to base your prediction on)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ruby_linear_regression.rb', line 80

def predict data

  # normalize
  data.each_index do |i|
    data[i] = (data[i] - @mu[i]) / @sigma[i].to_f
  end

  # add 1 column to prediction data
  data = [1].concat( data )

  # perform prediction
  prediction = (Matrix[data] * @theta)[0,0].to_f

  return prediction

end

#train_gradient_descent(alpha = 0.01, iterations = 500, verbose = false) ⇒ Object

Calculate optimal theta using gradient descent Arguments:

alpha: Learning rate
iterations: Number of iterations to run gradient descent
verbose: If true will output cost after each iteration, can be used to find optimal learning rate (alpha) and iteration


60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ruby_linear_regression.rb', line 60

def train_gradient_descent( alpha = 0.01, iterations = 500, verbose = false )

  0.upto( iterations ) do |i|
    @temp_theta = Array.new(@theta.row_size)
    0.upto(@theta.row_size-1) do |row|
      @temp_theta[row] = @theta[row,0] - alpha * compute_gradient(row)
    end

    @theta = Matrix.columns([@temp_theta])

    puts "Cost after #{i} iterations = #{compute_cost}" if verbose
  end

end

#train_normal_equationObject

Calculate the optimal theta using the normal equation



47
48
49
50
51
52
53
# File 'lib/ruby_linear_regression.rb', line 47

def train_normal_equation
  # Calculate the optimal theta using the normal equation
  # theta = ( X' * X )^1 * X' * y
  @theta = (@x.transpose * @x).inverse * @x.transpose * @y

  return @theta
end