statsample-glm 0.0.1 → 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +51 -0
- data/.rspec +1 -0
- data/.travis.yml +2 -9
- data/Gemfile +2 -20
- data/LICENSE.txt +1 -1
- data/README.rdoc +14 -11
- data/Rakefile +16 -24
- data/lib/statsample-glm.rb +1 -11
- data/lib/statsample-glm/{regression.rb → glm.rb} +13 -46
- data/lib/statsample-glm/glm/base.rb +99 -0
- data/lib/statsample-glm/glm/irls/base.rb +54 -0
- data/lib/statsample-glm/glm/irls/logistic.rb +46 -0
- data/lib/statsample-glm/glm/irls/poisson.rb +48 -0
- data/lib/statsample-glm/glm/logistic.rb +16 -0
- data/lib/statsample-glm/glm/mle/base.rb +157 -0
- data/lib/statsample-glm/glm/mle/logistic.rb +113 -0
- data/lib/statsample-glm/glm/mle/normal.rb +94 -0
- data/lib/statsample-glm/glm/mle/probit.rb +100 -0
- data/lib/statsample-glm/glm/normal.rb +17 -0
- data/lib/statsample-glm/glm/poisson.rb +17 -0
- data/lib/statsample-glm/glm/probit.rb +16 -0
- data/lib/statsample-glm/version.rb +5 -0
- data/spec/data/logistic.csv +51 -0
- data/spec/data/logistic_mle.csv +201 -0
- data/spec/data/normal.csv +30 -0
- data/spec/logistic_spec.rb +37 -0
- data/spec/normal_spec.rb +15 -0
- data/spec/poisson_spec.rb +32 -0
- data/spec/probit_spec.rb +19 -0
- data/spec/spec_helper.rb +50 -0
- data/statsample-glm.gemspec +35 -0
- metadata +71 -145
- data/VERSION +0 -1
- data/features/bio-statsample-glm.feature +0 -9
- data/features/step_definitions/bio-statsample-glm_steps.rb +0 -0
- data/features/support/env.rb +0 -15
- data/lib/statsample-glm/regression/logistic.rb +0 -108
- data/lib/statsample-glm/regression/poisson.rb +0 -90
- data/test/helper.rb +0 -87
- data/test/test_glm.rb +0 -4
- data/test/test_glm_logistic.rb +0 -23
- data/test/test_glm_poisson.rb +0 -25
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a514ad693d8ef698d63b3c51c903ead6837bf498
|
4
|
+
data.tar.gz: 9a06cc01573d053da123a6f91f50dce703141244
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4330fe635519e054cd8f01e0dddde160cc1f61c21efbc2cedbae8f509c855e4b145982b99b8867fda6d6ecf03f9eea395de062ed0bf675a8309e4c921c26daf8
|
7
|
+
data.tar.gz: 979f0af03a502f92b1b09d1e4561ff3d8f77e45a832f1756136591db5ac1adcf807cd513a634f838339ff252214dc8356bf3f4a34088cc0c33fdf5dade192c35
|
data/.gitignore
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# rcov generated
|
2
|
+
coverage
|
3
|
+
coverage.data
|
4
|
+
|
5
|
+
# rdoc generated
|
6
|
+
rdoc
|
7
|
+
|
8
|
+
# yard generated
|
9
|
+
doc
|
10
|
+
.yardoc
|
11
|
+
|
12
|
+
# bundler
|
13
|
+
.bundle
|
14
|
+
|
15
|
+
# jeweler generated
|
16
|
+
pkg
|
17
|
+
|
18
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
19
|
+
#
|
20
|
+
# * Create a file at ~/.gitignore
|
21
|
+
# * Include files you want ignored
|
22
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
23
|
+
#
|
24
|
+
# After doing this, these files will be ignored in all your git projects,
|
25
|
+
# saving you from having to 'pollute' every project you touch with them
|
26
|
+
#
|
27
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
28
|
+
#
|
29
|
+
# For MacOS:
|
30
|
+
#
|
31
|
+
#.DS_Store
|
32
|
+
|
33
|
+
# For TextMate
|
34
|
+
#*.tmproj
|
35
|
+
#tmtags
|
36
|
+
|
37
|
+
# For emacs:
|
38
|
+
#*~
|
39
|
+
#\#*
|
40
|
+
#.\#*
|
41
|
+
|
42
|
+
# For vim:
|
43
|
+
#*.swp
|
44
|
+
|
45
|
+
# For redcar:
|
46
|
+
#.redcar
|
47
|
+
|
48
|
+
# For rubinius:
|
49
|
+
#*.rbc
|
50
|
+
# Ignore Gemfile.lock for gems. See http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/
|
51
|
+
Gemfile.lock
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
CHANGED
@@ -1,13 +1,6 @@
|
|
1
1
|
language: ruby
|
2
|
+
cache: bundler
|
2
3
|
rvm:
|
3
|
-
- 1.9.2
|
4
4
|
- 1.9.3
|
5
5
|
- 2.0.0
|
6
|
-
-
|
7
|
-
- rbx-19mode
|
8
|
-
# - 1.8.7
|
9
|
-
# - jruby-18mode # JRuby in 1.8 mode
|
10
|
-
# - rbx-18mode
|
11
|
-
|
12
|
-
# uncomment this line if your project needs to run something other than `rake`:
|
13
|
-
# script: bundle exec rspec spec
|
6
|
+
- 2.1.1
|
data/Gemfile
CHANGED
@@ -1,20 +1,2 @@
|
|
1
|
-
source "
|
2
|
-
|
3
|
-
gem 'statsample', '>=1.2.0'
|
4
|
-
# Add dependencies required to use your gem here.
|
5
|
-
# Example:
|
6
|
-
gem "activesupport", "= 3.2.10"
|
7
|
-
|
8
|
-
# Add dependencies to develop your gem here.
|
9
|
-
# Include everything needed to run rake, tests, features, etc.
|
10
|
-
group :development do
|
11
|
-
gem "shoulda", ">= 0"
|
12
|
-
gem "rdoc", "~> 3.12"
|
13
|
-
gem "minitest", "~> 4.7.5"
|
14
|
-
gem "cucumber", ">= 0"
|
15
|
-
gem "bundler", "~> 1.3.5"
|
16
|
-
gem "jeweler", "~> 1.8.4"
|
17
|
-
gem "bio", ">= 1.4.2"
|
18
|
-
gem "rdoc", "~> 3.12"
|
19
|
-
gem "mocha", "~> 0.14.0"
|
20
|
-
end
|
1
|
+
source "https://rubygems.org"
|
2
|
+
gemspec
|
data/LICENSE.txt
CHANGED
@@ -9,7 +9,7 @@ You *must* read the Contributor Agreement before contributing code to the SciRub
|
|
9
9
|
|
10
10
|
-----
|
11
11
|
|
12
|
-
Copyright (c)
|
12
|
+
Copyright (c) 2013, Ankur Goel and the Ruby Science Foundation
|
13
13
|
All rights reserved.
|
14
14
|
|
15
15
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
data/README.rdoc
CHANGED
@@ -6,6 +6,8 @@ src="https://secure.travis-ci.org/AnkurGel/statsample-glm.png"
|
|
6
6
|
|
7
7
|
Statsample-GLM is an extension of *Generalized Linear Models* to {Statsample}[https://github.com/SciRuby/statsample], a suite of advance statistics in Ruby.
|
8
8
|
|
9
|
+
Requires ruby 1.9.3 or higher.
|
10
|
+
|
9
11
|
* {sciruby.com}[http://sciruby.com]
|
10
12
|
* {Google+}[https://plus.google.com/109304769076178160953/posts]
|
11
13
|
* {Ankur Goel}[http://ankurgoel.com]
|
@@ -13,14 +15,17 @@ Statsample-GLM is an extension of *Generalized Linear Models* to {Statsample}[ht
|
|
13
15
|
|
14
16
|
|
15
17
|
== Description
|
16
|
-
Statsample-
|
18
|
+
Statsample-glm includes the following Generalized Linear Models:
|
17
19
|
|
18
|
-
* Poisson Regression
|
19
|
-
* Logistic Regression
|
20
|
-
* Exponential Regression
|
21
20
|
* Iteratively Reweighted Least Squares
|
21
|
+
* Poisson Regression
|
22
|
+
* Logistic Regression
|
23
|
+
* Maximum Likelihood Models (Newton Raphson)
|
24
|
+
* Logistic Regression
|
25
|
+
* Probit Regression
|
26
|
+
* Normal Regression
|
22
27
|
|
23
|
-
Statsample-GLM was created by Ankur Goel as part of Google's Summer of Code 2013. It is the part of {SciRuby}[http://sciruby.com]
|
28
|
+
Statsample-GLM was created by Ankur Goel as part of Google's Summer of Code 2013. It is the part of {the SciRuby Project}[http://sciruby.com].
|
24
29
|
|
25
30
|
Note: This is under active development!
|
26
31
|
|
@@ -40,7 +45,7 @@ You can also go through the blog-posts on {my blog}[http://ankurgoel.com] for de
|
|
40
45
|
|
41
46
|
== Documentation
|
42
47
|
|
43
|
-
The API doc is {online}[http://rubygems.org/gems/statsample-glm]. For more code examples see also the
|
48
|
+
The API doc is {online}[http://rubygems.org/gems/statsample-glm]. For more code examples see also the spec files in the source tree.
|
44
49
|
|
45
50
|
|
46
51
|
== Contributing
|
@@ -49,7 +54,7 @@ The API doc is {online}[http://rubygems.org/gems/statsample-glm]. For more code
|
|
49
54
|
* Create your feature branch
|
50
55
|
* Add/Modify code.
|
51
56
|
* Write equivalent documentation and **tests**.
|
52
|
-
* Run `
|
57
|
+
* Run `rspec` to verify that all test case passes.
|
53
58
|
* Push your branch.
|
54
59
|
* Pull request. :)
|
55
60
|
|
@@ -60,12 +65,10 @@ Information on the source tree, documentation, issues and how to contribute, see
|
|
60
65
|
|
61
66
|
http://github.com/ankurgel/statsample-glm
|
62
67
|
|
63
|
-
|
64
|
-
== Biogems.info
|
65
|
-
|
66
68
|
This Biogem is published at http://biogems.info/index.html#statsample-glm
|
67
69
|
|
68
70
|
== Copyright
|
69
71
|
|
70
|
-
Copyright (c) 2013 Ankur Goel. See LICENSE.txt for further details.
|
72
|
+
Copyright (c) 2013 Ankur Goel and the Ruby Science Foundation. See LICENSE.txt for further details.
|
71
73
|
|
74
|
+
Statsample is (c) 2009-2013 Claudio Bustos and the Ruby Science Foundation.
|
data/Rakefile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require 'rake'
|
3
|
+
require 'bundler/gem_tasks'
|
2
4
|
|
3
|
-
require 'rubygems'
|
4
5
|
require 'bundler'
|
5
6
|
begin
|
6
7
|
Bundler.setup(:default, :development)
|
@@ -9,37 +10,28 @@ rescue Bundler::BundlerError => e
|
|
9
10
|
$stderr.puts "Run `bundle install` to install missing gems"
|
10
11
|
exit e.status_code
|
11
12
|
end
|
12
|
-
require 'rake'
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
gem.email = "ankurgel@gmail.com"
|
23
|
-
gem.authors = ["Ankur Goel"]
|
24
|
-
# dependencies defined in Gemfile
|
14
|
+
desc "Open IRB with statsample-timeseries loaded."
|
15
|
+
task :console do
|
16
|
+
require 'irb'
|
17
|
+
require 'irb/completion'
|
18
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
19
|
+
require 'statsample-glm'
|
20
|
+
ARGV.clear
|
21
|
+
IRB.start
|
25
22
|
end
|
26
|
-
Jeweler::RubygemsDotOrgTasks.new
|
27
23
|
|
28
|
-
require 'rake/testtask'
|
29
|
-
Rake::TestTask.new(:test) do |test|
|
30
|
-
test.libs << 'lib' << 'test'
|
31
|
-
test.pattern = 'test/**/test_*.rb'
|
32
|
-
test.verbose = true
|
33
|
-
end
|
34
24
|
|
35
|
-
require '
|
36
|
-
|
25
|
+
require 'rspec/core/rake_task'
|
26
|
+
|
27
|
+
RSpec::Core::RakeTask.new(:spec)
|
37
28
|
|
38
|
-
task :default => :
|
29
|
+
task :default => :spec
|
39
30
|
|
40
31
|
require 'rdoc/task'
|
41
32
|
Rake::RDocTask.new do |rdoc|
|
42
|
-
|
33
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
34
|
+
version = Statsample::GLM::VERSION
|
43
35
|
|
44
36
|
rdoc.rdoc_dir = 'rdoc'
|
45
37
|
rdoc.title = "statsample-glm #{version}"
|
data/lib/statsample-glm.rb
CHANGED
@@ -1,12 +1,2 @@
|
|
1
|
-
# Please require your code below, respecting the naming conventions in the
|
2
|
-
# bioruby directory tree.
|
3
|
-
#
|
4
|
-
# For example, say you have a plugin named bio-plugin, the only uncommented
|
5
|
-
# line in this file would be
|
6
|
-
#
|
7
|
-
# require 'bio/bio-plugin/plugin'
|
8
|
-
#
|
9
|
-
# In this file only require other files. Avoid other source code.
|
10
|
-
|
11
1
|
require 'statsample'
|
12
|
-
require 'statsample-glm/
|
2
|
+
require 'statsample-glm/glm'
|
@@ -1,7 +1,10 @@
|
|
1
|
-
require 'statsample-glm/
|
2
|
-
require 'statsample-glm/
|
1
|
+
require 'statsample-glm/glm/logistic'
|
2
|
+
require 'statsample-glm/glm/probit'
|
3
|
+
require 'statsample-glm/glm/poisson'
|
4
|
+
require 'statsample-glm/glm/normal'
|
5
|
+
|
3
6
|
module Statsample
|
4
|
-
module
|
7
|
+
module GLM
|
5
8
|
include Statsample::VectorShorthands
|
6
9
|
|
7
10
|
# = Generalized linear models
|
@@ -15,55 +18,19 @@ module Statsample
|
|
15
18
|
# require 'statsample-glm'
|
16
19
|
# x1=Statsample::Vector.new([0.537322309644812,-0.717124209978434,-0.519166718891331,0.434970973986765,-0.761822002215759,1.51170030921189,0.883854199811195,-0.908689798854196,1.70331977539793,-0.246971150634099,-1.59077593922623,-0.721548040910253,0.467025703920194,-0.510132788447137,0.430106510266798,-0.144353683251536,-1.54943800728303,0.849307651309298,-0.640304240933579,1.31462478279425,-0.399783455165345,0.0453055645017902,-2.58212161987746,-1.16484414309359,-1.08829266466281,-0.243893919684792,-1.96655661929441,0.301335373291024,-0.665832694463588,-0.0120650855753837,1.5116066367604,0.557300353673344,1.12829931872045,0.234443748015922,-2.03486690662651,0.275544751380246,-0.231465849558696,-0.356880153225012,-0.57746647541923,1.35758352580655,1.23971669378224,-0.662466275100489,0.313263561921793,-1.08783223256362,1.41964722846899,1.29325100940785,0.72153880625103,0.440580131022748,0.0351917814720056, -0.142353224879252],:scale)
|
17
20
|
# x2=Statsample::Vector.new([-0.866655707911859,-0.367820249977585,0.361486610435,0.857332626245179,0.133438466268095,0.716104533073575,1.77206093023382,-0.10136697295802,-0.777086491435508,-0.204573554913706,0.963353531412233,-1.10103024900542,-0.404372761837392,-0.230226345183469,0.0363730246866971,-0.838265540390497,1.12543549657924,-0.57929175648001,-0.747060244805248,0.58946979365152,-0.531952663697324,1.53338594419818,0.521992029051441,1.41631763288724,0.611402316795129,-0.518355638373296,-0.515192557101107,-0.672697937866108,1.84347042325327,-0.21195540664804,-0.269869371631611,0.296155694010096,-2.18097898069634,-1.21314663927206,1.49193669881581,1.38969280369493,-0.400680808117106,-1.87282814976479,1.82394870451051,0.637864732838274,-0.141155946382493,0.0699950644281617,1.32568550595165,-0.412599258349398,0.14436832227506,-1.16507785388489,-2.16782049922428,0.24318371493798,0.258954871320764,-0.151966534521183],:scale)
|
18
|
-
#
|
19
|
-
#
|
20
|
-
# obj = Statsample::Regression.glm(x, y, :binomial)
|
21
|
+
# x=Statsample::Dataset.new({"x1"=>x1,"x2"=>x2})
|
22
|
+
# obj = Statsample::GLM.compute(x, y, :logit, {algorithm: :irls})
|
21
23
|
# #=> Logistic Regression object
|
22
24
|
#
|
23
25
|
# == Returns
|
24
26
|
# GLM object for given method.
|
25
|
-
def self.
|
26
|
-
|
27
|
-
if method.downcase.to_sym == :poisson
|
28
|
-
obj = Statsample::Regression::GLM::Poisson.new(x,y)
|
29
|
-
elsif method.downcase.to_sym == :binomial
|
30
|
-
obj = Statsample::Regression::GLM::Logistic.new(x,y)
|
31
|
-
else
|
32
|
-
raise("Not implemented yet")
|
33
|
-
end
|
34
|
-
obj.irwls
|
35
|
-
obj
|
36
|
-
end
|
37
|
-
|
38
|
-
|
39
|
-
def self.irwls(x, y, mu, w, j, h, epsilon = 1e-7, max_iter = 100)
|
40
|
-
b = Matrix.column_vector(Array.new(x.column_size,0.0))
|
41
|
-
converged = false
|
42
|
-
1.upto(max_iter) do |i|
|
43
|
-
#conversion from : (solve(j(x,b)) %*% h(x,b,y))
|
27
|
+
def self.compute(data_set, dependent_column, method, opts={})
|
28
|
+
opts[:method] = method
|
44
29
|
|
45
|
-
|
46
|
-
b_new = b - intermediate
|
47
|
-
|
48
|
-
if((b_new - b).map(&:abs)).to_a.flatten.inject(:+) < epsilon
|
49
|
-
converged = true
|
50
|
-
b = b_new
|
51
|
-
break
|
52
|
-
end
|
53
|
-
b = b_new
|
54
|
-
end
|
55
|
-
ss = j.call(x,b).inverse.diagonal.map{ |x| -x}.map{ |y| Math.sqrt(y) }
|
56
|
-
values = mu.call(x,b)
|
57
|
-
|
58
|
-
residuals = y - values.column_vectors.map(&:to_a).flatten
|
59
|
-
df_residuals = y.count - x.column_size
|
60
|
-
return [create_vector(b.column_vectors[0]), create_vector(ss), create_vector(values.to_a.flatten),
|
61
|
-
residuals, max_iter, df_residuals, converged]
|
62
|
-
end
|
30
|
+
# TODO: Remove this const_get jugaad after 1.9.3 support is removed.
|
63
31
|
|
64
|
-
|
65
|
-
|
66
|
-
Statsample::Vector.new(arr, :scale)
|
32
|
+
Kernel.const_get("Statsample").const_get("GLM").const_get("#{method.capitalize}").new data_set,
|
33
|
+
dependent_column, opts
|
67
34
|
end
|
68
35
|
end
|
69
36
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'statsample-glm/glm/irls/logistic'
|
2
|
+
require 'statsample-glm/glm/irls/poisson'
|
3
|
+
require 'statsample-glm/glm/mle/logistic'
|
4
|
+
require 'statsample-glm/glm/mle/probit'
|
5
|
+
require 'statsample-glm/glm/mle/normal'
|
6
|
+
|
7
|
+
module Statsample
|
8
|
+
module GLM
|
9
|
+
class Base
|
10
|
+
|
11
|
+
def initialize ds, y, opts={}
|
12
|
+
@opts = opts
|
13
|
+
|
14
|
+
set_default_opts_if_any
|
15
|
+
|
16
|
+
@data_set = ds.dup(ds.fields - [y.to_s])
|
17
|
+
@dependent = ds[y.to_s]
|
18
|
+
|
19
|
+
add_constant_vector if @opts[:constant]
|
20
|
+
add_constant_vector(1) if self.is_a? Statsample::GLM::Normal
|
21
|
+
|
22
|
+
algorithm = @opts[:algorithm].upcase
|
23
|
+
method = @opts[:method].capitalize
|
24
|
+
|
25
|
+
# TODO: Remove this const_get jugaad after 1.9.3 support is removed.
|
26
|
+
|
27
|
+
@regression = Kernel.const_get("Statsample").const_get("GLM")
|
28
|
+
.const_get("#{algorithm}").const_get("#{method}")
|
29
|
+
.new(@data_set, @dependent, @opts)
|
30
|
+
end
|
31
|
+
|
32
|
+
def coefficients as_a=:array
|
33
|
+
if as_a == :hash
|
34
|
+
c = {}
|
35
|
+
@data_set.fields.each_with_index do |f,i|
|
36
|
+
c[f.to_sym] = @regression.coefficients[i]
|
37
|
+
end
|
38
|
+
return c
|
39
|
+
end
|
40
|
+
create_vector @regression.coefficients
|
41
|
+
end
|
42
|
+
|
43
|
+
def standard_error as_a=:array
|
44
|
+
if as_a == :hash
|
45
|
+
se = {}
|
46
|
+
@data_set.fields.each_with_index do |f,i|
|
47
|
+
se[f.to_sym] = @regression.standard_error[i]
|
48
|
+
end
|
49
|
+
return se
|
50
|
+
end
|
51
|
+
|
52
|
+
create_vector @regression.standard_error
|
53
|
+
end
|
54
|
+
|
55
|
+
def iterations
|
56
|
+
@regression.iterations
|
57
|
+
end
|
58
|
+
|
59
|
+
def fitted_mean_values
|
60
|
+
@regression.fitted_mean_values
|
61
|
+
end
|
62
|
+
|
63
|
+
def residuals
|
64
|
+
@regression.residuals
|
65
|
+
end
|
66
|
+
|
67
|
+
def degree_of_freedom
|
68
|
+
@regression.degree_of_freedom
|
69
|
+
end
|
70
|
+
|
71
|
+
def log_likelihood
|
72
|
+
@regression.log_likelihood if @opts[:algorithm] == :mle
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def set_default_opts_if_any
|
78
|
+
@opts[:algorithm] ||= :irls
|
79
|
+
@opts[:iterations] ||= 100
|
80
|
+
@opts[:epsilon] ||= 1e-7
|
81
|
+
@opts[:link] ||= :log
|
82
|
+
end
|
83
|
+
|
84
|
+
def create_vector arr
|
85
|
+
Statsample::Vector.new(arr, :scale)
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_constant_vector x=nil
|
89
|
+
@data_set.add_vector "constant",
|
90
|
+
(([@opts[:constant]]*@data_set.cases).to_vector(:scale))
|
91
|
+
|
92
|
+
unless x.nil?
|
93
|
+
@data_set.add_vector "constant",
|
94
|
+
(([1]*@data_set.cases).to_vector(:scale))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Statsample
|
2
|
+
module GLM
|
3
|
+
module IRLS
|
4
|
+
class Base
|
5
|
+
|
6
|
+
attr_reader :coefficients, :standard_error, :iterations,
|
7
|
+
:fitted_mean_values, :residuals, :degree_of_freedom
|
8
|
+
|
9
|
+
def initialize data_set, dependent, opts={}
|
10
|
+
@data_set = data_set.to_matrix
|
11
|
+
@dependent = dependent
|
12
|
+
@opts = opts
|
13
|
+
|
14
|
+
irls
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def irls
|
20
|
+
|
21
|
+
max_iter = @opts[:iterations]
|
22
|
+
b = Matrix.column_vector Array.new(@data_set.column_size,0.0)
|
23
|
+
|
24
|
+
1.upto(max_iter) do
|
25
|
+
intermediate = (hessian(@data_set,b).inverse *
|
26
|
+
jacobian(@data_set, b, @dependent))
|
27
|
+
|
28
|
+
b_new = b - intermediate
|
29
|
+
|
30
|
+
if((b_new - b).map(&:abs)).to_a.flatten.inject(:+) < @opts[:epsilon]
|
31
|
+
b = b_new
|
32
|
+
break
|
33
|
+
end
|
34
|
+
b = b_new
|
35
|
+
end
|
36
|
+
|
37
|
+
@coefficients = create_vector(b.column_vectors[0])
|
38
|
+
@iterations = max_iter
|
39
|
+
@standard_error = hessian(@data_set,b).inverse
|
40
|
+
.diagonal
|
41
|
+
.map{ |x| -x}
|
42
|
+
.map{ |y| Math.sqrt(y) }
|
43
|
+
@fitted_mean_values = create_vector measurement(@data_set,b).to_a.flatten
|
44
|
+
@residuals = @dependent - @fitted_mean_values
|
45
|
+
@degree_of_freedom = @dependent.count - @data_set.column_size
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_vector arr
|
49
|
+
Statsample::Vector.new(arr, :scale)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|