glm 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/examples/test_glm_linear.rb +4 -3
 - data/examples/test_glm_logit.rb +3 -5
 - data/lib/glm.rb +1 -0
 - data/lib/glm/base.rb +19 -22
 - data/lib/glm/linear.rb +4 -3
 - data/lib/glm/logit.rb +1 -1
 - data/lib/glm/util.rb +12 -0
 - data/test/test_glm.rb +7 -3
 - metadata +3 -2
 
    
        data/examples/test_glm_linear.rb
    CHANGED
    
    | 
         @@ -8,16 +8,17 @@ T = 2000 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            iris = load_iris
         
     | 
| 
       10 
10 
     | 
    
         
             
            y_arr = iris.map {|r| r[0]}
         
     | 
| 
      
 11 
     | 
    
         
            +
            y = GSL::Vector.alloc y_arr
         
     | 
| 
       11 
12 
     | 
    
         
             
            x = iris.map {|r| r[1...-1]}
         
     | 
| 
       12 
13 
     | 
    
         
             
            x = x.map{|r| r << 1}
         
     | 
| 
       13 
     | 
    
         
            -
            x 
     | 
| 
      
 14 
     | 
    
         
            +
            x = GLM::Util.aa_to_gsl_matrix x
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
            linear = GLM::Linear.new(x, y)
         
     | 
| 
      
 16 
     | 
    
         
            +
            linear = GLM::Linear.new(x, y,0.05)
         
     | 
| 
       16 
17 
     | 
    
         | 
| 
       17 
18 
     | 
    
         
             
            (1..T).each do |i|
         
     | 
| 
       18 
19 
     | 
    
         
             
              linear.sto_update
         
     | 
| 
       19 
20 
     | 
    
         
             
              est_y =  linear.est(x)
         
     | 
| 
       20 
     | 
    
         
            -
              err = ( 
     | 
| 
      
 21 
     | 
    
         
            +
              err = (est_y - y).nrm2
         
     | 
| 
       21 
22 
     | 
    
         
             
              puts err
         
     | 
| 
       22 
23 
     | 
    
         
             
            end
         
     | 
| 
       23 
24 
     | 
    
         | 
    
        data/examples/test_glm_logit.rb
    CHANGED
    
    | 
         @@ -8,19 +8,17 @@ T = 200 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            iris = load_iris
         
     | 
| 
       10 
10 
     | 
    
         
             
            y_arr = iris.map {|r| r[-1].to_i}
         
     | 
| 
      
 11 
     | 
    
         
            +
            y = GSL::Vector.alloc y_arr
         
     | 
| 
       11 
12 
     | 
    
         
             
            x = iris.map {|r| r[0...-2]}
         
     | 
| 
       12 
13 
     | 
    
         
             
            x = x.map{|r| r << 1}
         
     | 
| 
       13 
     | 
    
         
            -
            x 
     | 
| 
      
 14 
     | 
    
         
            +
            x = GLM::Util.aa_to_gsl_matrix x
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
       15 
16 
     | 
    
         
             
            glm = GLM::Logit.new(x, y, 0.1)
         
     | 
| 
       16 
17 
     | 
    
         | 
| 
       17 
18 
     | 
    
         
             
            (1..T).each do |i|
         
     | 
| 
       18 
19 
     | 
    
         
             
              glm.sto_update
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
20 
     | 
    
         
             
              est_y =  glm.est(x)
         
     | 
| 
       21 
     | 
    
         
            -
              err = ( 
     | 
| 
       22 
     | 
    
         
            -
            #  pp y.zip(est_y)
         
     | 
| 
       23 
     | 
    
         
            -
              
         
     | 
| 
      
 21 
     | 
    
         
            +
              err = (est_y - y).nrm2
         
     | 
| 
       24 
22 
     | 
    
         
             
              puts err
         
     | 
| 
       25 
23 
     | 
    
         
             
              pp glm.theta
         
     | 
| 
       26 
24 
     | 
    
         
             
            end
         
     | 
    
        data/lib/glm.rb
    CHANGED
    
    
    
        data/lib/glm/base.rb
    CHANGED
    
    | 
         @@ -1,10 +1,10 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            class GLM::Base
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              def initialize(x,y,alpha = 0. 
     | 
| 
      
 2 
     | 
    
         
            +
              @@initial_weight = 1
         
     | 
| 
      
 3 
     | 
    
         
            +
              def initialize(x,y,alpha = 0.05)
         
     | 
| 
       4 
4 
     | 
    
         
             
                @x = x
         
     | 
| 
       5 
5 
     | 
    
         
             
                @y = y
         
     | 
| 
       6 
6 
     | 
    
         
             
                @@alpha = alpha
         
     | 
| 
       7 
     | 
    
         
            -
                @theta = Array.new(x. 
     | 
| 
      
 7 
     | 
    
         
            +
                @theta = GSL::Vector.alloc(Array.new(x.size2, @@initial_weight))
         
     | 
| 
       8 
8 
     | 
    
         
             
              end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
              #Log partition function <b>a(eta)</b>, intended to be overriden
         
     | 
| 
         @@ -18,22 +18,16 @@ class GLM::Base 
     | 
|
| 
       18 
18 
     | 
    
         
             
              end
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
              def format(x)
         
     | 
| 
       21 
     | 
    
         
            -
                if x.is_a?  
     | 
| 
       22 
     | 
    
         
            -
                   
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                   
     | 
| 
       26 
     | 
    
         
            -
                    output(x)
         
     | 
| 
       27 
     | 
    
         
            -
                   
     | 
| 
       28 
     | 
    
         
            -
                #Assuming x.is_a?(Matrix) == true
         
     | 
| 
       29 
     | 
    
         
            -
                else
         
     | 
| 
       30 
     | 
    
         
            -
                  x.row_vectors.map {|e|
         
     | 
| 
       31 
     | 
    
         
            -
                    output(Matrix.row_vector(e))
         
     | 
| 
       32 
     | 
    
         
            -
                  }
         
     | 
| 
      
 21 
     | 
    
         
            +
                if x.is_a? GSL::Vector
         
     | 
| 
      
 22 
     | 
    
         
            +
                  return output(x)
         
     | 
| 
      
 23 
     | 
    
         
            +
                elsif x.is_a? GSL::Matrix
         
     | 
| 
      
 24 
     | 
    
         
            +
                  tmp = GSL::Vector.alloc x.size1
         
     | 
| 
      
 25 
     | 
    
         
            +
                  (0...x.size1).each {|i|
         
     | 
| 
      
 26 
     | 
    
         
            +
                    tmp[i]= output(x.row(i))}
         
     | 
| 
      
 27 
     | 
    
         
            +
                  return tmp
         
     | 
| 
       33 
28 
     | 
    
         
             
                end
         
     | 
| 
       34 
29 
     | 
    
         
             
              end
         
     | 
| 
       35 
30 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
31 
     | 
    
         
             
              # Estimator
         
     | 
| 
       38 
32 
     | 
    
         
             
              # =Arguments:
         
     | 
| 
       39 
33 
     | 
    
         
             
              #   x: a feature vector in Array
         
     | 
| 
         @@ -46,12 +40,12 @@ class GLM::Base 
     | 
|
| 
       46 
40 
     | 
    
         
             
              #Output estimation from E(y|theta,x)
         
     | 
| 
       47 
41 
     | 
    
         
             
              #Need overriding, except for plain linear regression
         
     | 
| 
       48 
42 
     | 
    
         
             
              def output(x)
         
     | 
| 
       49 
     | 
    
         
            -
                return h(x 
     | 
| 
      
 43 
     | 
    
         
            +
                return h(x)
         
     | 
| 
       50 
44 
     | 
    
         
             
              end
         
     | 
| 
       51 
45 
     | 
    
         | 
| 
       52 
46 
     | 
    
         
             
              #Natural parameter eta
         
     | 
| 
       53 
47 
     | 
    
         
             
              def eta(x)
         
     | 
| 
       54 
     | 
    
         
            -
                tmp =  
     | 
| 
      
 48 
     | 
    
         
            +
                tmp = @theta * x.transpose
         
     | 
| 
       55 
49 
     | 
    
         
             
                return tmp
         
     | 
| 
       56 
50 
     | 
    
         
             
              end
         
     | 
| 
       57 
51 
     | 
    
         | 
| 
         @@ -69,7 +63,8 @@ class GLM::Base 
     | 
|
| 
       69 
63 
     | 
    
         
             
              #Gradient on one sample
         
     | 
| 
       70 
64 
     | 
    
         
             
              def gradient(x,y,v)
         
     | 
| 
       71 
65 
     | 
    
         
             
                tmp = h(v)
         
     | 
| 
       72 
     | 
    
         
            -
                 
     | 
| 
      
 66 
     | 
    
         
            +
                res = (y - tmp) * x
         
     | 
| 
      
 67 
     | 
    
         
            +
                return res
         
     | 
| 
       73 
68 
     | 
    
         
             
              end
         
     | 
| 
       74 
69 
     | 
    
         | 
| 
       75 
70 
     | 
    
         
             
              # Hypothesis function, outputs E(y|theta, x), mean of y given x parameterized by theta
         
     | 
| 
         @@ -89,11 +84,13 @@ class GLM::Base 
     | 
|
| 
       89 
84 
     | 
    
         | 
| 
       90 
85 
     | 
    
         
             
              #One complete loop of stochastic gradient descend
         
     | 
| 
       91 
86 
     | 
    
         
             
              def sto_update()
         
     | 
| 
       92 
     | 
    
         
            -
                (0...(@x. 
     | 
| 
       93 
     | 
    
         
            -
                  (0...(@x. 
     | 
| 
       94 
     | 
    
         
            -
                     
     | 
| 
      
 87 
     | 
    
         
            +
                (0...(@x.size1)).each do |i|
         
     | 
| 
      
 88 
     | 
    
         
            +
                  (0...(@x.size2)).each do |j|
         
     | 
| 
      
 89 
     | 
    
         
            +
                    updates = gradient(@x[i,j], @y[i], @x.row(i))
         
     | 
| 
      
 90 
     | 
    
         
            +
                    @theta[j] = @theta[j] + @@alpha * updates
         
     | 
| 
       95 
91 
     | 
    
         
             
                  end
         
     | 
| 
       96 
92 
     | 
    
         
             
                end
         
     | 
| 
      
 93 
     | 
    
         
            +
                pp @theta
         
     | 
| 
       97 
94 
     | 
    
         
             
              end
         
     | 
| 
       98 
95 
     | 
    
         | 
| 
       99 
96 
     | 
    
         
             
              def theta()
         
     | 
    
        data/lib/glm/linear.rb
    CHANGED
    
    | 
         @@ -13,15 +13,16 @@ class GLM::Linear < GLM::Base 
     | 
|
| 
       13 
13 
     | 
    
         
             
              def self.g(eta)
         
     | 
| 
       14 
14 
     | 
    
         
             
                return eta
         
     | 
| 
       15 
15 
     | 
    
         
             
              end
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
              
         
     | 
| 
      
 17 
     | 
    
         
            +
              #Normal equation estimation
         
     | 
| 
       17 
18 
     | 
    
         
             
              def ne_est(x)
         
     | 
| 
       18 
19 
     | 
    
         
             
                @theta = ne_fit
         
     | 
| 
       19 
     | 
    
         
            -
                [@theta, x *  
     | 
| 
      
 20 
     | 
    
         
            +
                [@theta, x * @theta]
         
     | 
| 
       20 
21 
     | 
    
         
             
              end
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         
             
              #Normal equation fit
         
     | 
| 
       23 
24 
     | 
    
         
             
              def ne_fit
         
     | 
| 
       24 
     | 
    
         
            -
                ( 
     | 
| 
      
 25 
     | 
    
         
            +
                ( @x.transpose * @x ).invert * @x.transpose * @y
         
     | 
| 
       25 
26 
     | 
    
         
             
              end
         
     | 
| 
       26 
27 
     | 
    
         | 
| 
       27 
28 
     | 
    
         
             
            end
         
     | 
    
        data/lib/glm/logit.rb
    CHANGED
    
    
    
        data/lib/glm/util.rb
    CHANGED
    
    | 
         @@ -6,4 +6,16 @@ class GLM::Util 
     | 
|
| 
       6 
6 
     | 
    
         
             
                y = Matrix.column_vector(y)
         
     | 
| 
       7 
7 
     | 
    
         
             
                return [x, y]
         
     | 
| 
       8 
8 
     | 
    
         
             
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              #Construct a GSL::Matrix out of an Array of Arrays, should have been in GSL::Matrix already
         
     | 
| 
      
 11 
     | 
    
         
            +
              def self.aa_to_gsl_matrix(aa)
         
     | 
| 
      
 12 
     | 
    
         
            +
                n_rows = aa.length
         
     | 
| 
      
 13 
     | 
    
         
            +
                n_cols = aa[0].length
         
     | 
| 
      
 14 
     | 
    
         
            +
                gmat = GSL::Matrix.alloc n_rows,n_cols
         
     | 
| 
      
 15 
     | 
    
         
            +
                (0...n_rows).each {|i|
         
     | 
| 
      
 16 
     | 
    
         
            +
                  (0...n_cols).each {|j|
         
     | 
| 
      
 17 
     | 
    
         
            +
                    gmat.set i, j, aa[i][j]}}
         
     | 
| 
      
 18 
     | 
    
         
            +
                return gmat
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       9 
21 
     | 
    
         
             
            end
         
     | 
    
        data/test/test_glm.rb
    CHANGED
    
    | 
         @@ -1,7 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'test/unit'
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'glm'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'pp'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'ruby-debug' 
     | 
| 
      
 4 
     | 
    
         
            +
            require 'ruby-debug'
         
     | 
| 
      
 5 
     | 
    
         
            +
            Debugger.start(:post_mortem => true)
         
     | 
| 
      
 6 
     | 
    
         
            +
            Debugger.settings[:autoeval] = true
         
     | 
| 
       5 
7 
     | 
    
         | 
| 
       6 
8 
     | 
    
         
             
            class GLMTest < Test::Unit::TestCase
         
     | 
| 
       7 
9 
     | 
    
         
             
              def test_glm_logit_truth
         
     | 
| 
         @@ -30,10 +32,12 @@ class GLMTest < Test::Unit::TestCase 
     | 
|
| 
       30 
32 
     | 
    
         
             
                y = iris.map {|r| r[0]}
         
     | 
| 
       31 
33 
     | 
    
         
             
                x = iris.map {|r| r[1...-1]}
         
     | 
| 
       32 
34 
     | 
    
         
             
                x = x.map{|r| r << 1}
         
     | 
| 
       33 
     | 
    
         
            -
                x,y = GLM::Util.formatArrays(x, y)
         
     | 
| 
      
 35 
     | 
    
         
            +
                #x,y = GLM::Util.formatArrays(x, y)
         
     | 
| 
      
 36 
     | 
    
         
            +
                x = GLM::Util.aa_to_gsl_matrix(x)
         
     | 
| 
      
 37 
     | 
    
         
            +
                y = GSL::Vector.alloc(y)
         
     | 
| 
       34 
38 
     | 
    
         
             
                linear = GLM::Linear.new(x, y)
         
     | 
| 
       35 
39 
     | 
    
         
             
                theta, y_est = linear.ne_est(x)
         
     | 
| 
       36 
     | 
    
         
            -
                assert  ((y_est - y).map {|e| e ** 2}). 
     | 
| 
      
 40 
     | 
    
         
            +
                assert  ((y_est - y).map {|e| e ** 2}).norm < 0.1
         
     | 
| 
       37 
41 
     | 
    
         
             
              end
         
     | 
| 
       38 
42 
     | 
    
         | 
| 
       39 
43 
     | 
    
         | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: glm
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.2
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
6 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       7 
7 
     | 
    
         
             
            authors:
         
     | 
| 
         @@ -48,8 +48,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       48 
48 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       49 
49 
     | 
    
         
             
            requirements: []
         
     | 
| 
       50 
50 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       51 
     | 
    
         
            -
            rubygems_version: 1.8. 
     | 
| 
      
 51 
     | 
    
         
            +
            rubygems_version: 1.8.19
         
     | 
| 
       52 
52 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       53 
53 
     | 
    
         
             
            specification_version: 3
         
     | 
| 
       54 
54 
     | 
    
         
             
            summary: This is a W.I.P implementation of GLM
         
     | 
| 
       55 
55 
     | 
    
         
             
            test_files: []
         
     | 
| 
      
 56 
     | 
    
         
            +
            has_rdoc: 
         
     |