nimbus 0.1
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/MIT-LICENSE.txt +20 -0
- data/README.rdoc +1 -0
- data/bin/nimbus +26 -0
- data/lib/nimbus/application.rb +77 -0
- data/lib/nimbus/configuration.rb +153 -0
- data/lib/nimbus/exceptions.rb +10 -0
- data/lib/nimbus/forest.rb +38 -0
- data/lib/nimbus/individual.rb +13 -0
- data/lib/nimbus/loss_functions.rb +23 -0
- data/lib/nimbus/training_set.rb +12 -0
- data/lib/nimbus/tree.rb +84 -0
- data/lib/nimbus.rb +48 -0
- data/spec/fixtures/config.yml +14 -0
- data/spec/nimbus_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- metadata +84 -0
data/MIT-LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Juanjo Bazán & Oscar González Recio
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
= Nimbus
|
data/bin/nimbus
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright (c) 2011 Juanjo Bazan
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to
|
8
|
+
# deal in the Software without restriction, including without limitation the
|
9
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10
|
+
# sell copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
14
|
+
# all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
22
|
+
# IN THE SOFTWARE.
|
23
|
+
#++
|
24
|
+
|
25
|
+
require 'nimbus'
|
26
|
+
Nimbus.application.run
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Nimbus
|
2
|
+
|
3
|
+
#####################################################################
|
4
|
+
# Nimbus main application object. When invoking +nimbus+ from the
|
5
|
+
# command line, a Nimbus::Application object is created and run.
|
6
|
+
#
|
7
|
+
class Application
|
8
|
+
attr_accessor :config
|
9
|
+
|
10
|
+
# Initialize a Nimbus::Application object.
|
11
|
+
# Check and load the configuration options.
|
12
|
+
#
|
13
|
+
def initialize
|
14
|
+
nimbus_exception_handling do
|
15
|
+
config.load
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Run the Nimbus application. The run method performs the following
|
20
|
+
# two steps:
|
21
|
+
#
|
22
|
+
# * Creates a Nimbus::Forest object.
|
23
|
+
# * Writes results to output files.
|
24
|
+
def run
|
25
|
+
nimbus_exception_handling do
|
26
|
+
forest = ::Nimbus::Forest.new @config
|
27
|
+
forest.grow if @config.do_training && @config.load_training_data
|
28
|
+
output_random_forest_file(forest)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Createas an instance of Nimbus::Configuration if it does not exist.
|
33
|
+
def config
|
34
|
+
@config ||= ::Nimbus::Configuration.new
|
35
|
+
end
|
36
|
+
|
37
|
+
# Provide exception handling for the given block.
|
38
|
+
def nimbus_exception_handling
|
39
|
+
begin
|
40
|
+
yield
|
41
|
+
rescue SystemExit => ex
|
42
|
+
raise
|
43
|
+
rescue OptionParser::InvalidOption => ex
|
44
|
+
display_error_message(Nimbus::InvalidOptionError ex.message)
|
45
|
+
Nimbus.stop
|
46
|
+
rescue Nimbus::Error => ex
|
47
|
+
display_error_message(ex)
|
48
|
+
Nimbus.stop
|
49
|
+
rescue Exception => ex
|
50
|
+
display_error_message(ex)
|
51
|
+
Nimbus.stop
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Display the error message that caused the exception.
|
56
|
+
def display_error_message(ex)
|
57
|
+
Nimbus.error_message "* Nimbus encountered an error! The random forest was not generated *"
|
58
|
+
Nimbus.error_message "#{ex.class}: #{ex.message}"
|
59
|
+
# if config.trace
|
60
|
+
Nimbus.error_message ex.backtrace.join("\n")
|
61
|
+
# else
|
62
|
+
# Nimbus.error_message "(See full error trace by running Nimbus with --trace)"
|
63
|
+
# end
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
def output_random_forest_file(forest)
|
68
|
+
File.open(@config.output_forest_file , 'w') {|f| f.write(forest.to_yaml) }
|
69
|
+
Nimbus.message "* Resulting forest structure be saved to:"
|
70
|
+
Nimbus.message "* Output forest file: #{@config.output_forest_file}"
|
71
|
+
Nimbus.message "*" * 50
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Nimbus
|
2
|
+
class Configuration
|
3
|
+
attr_accessor(
|
4
|
+
:training_file,
|
5
|
+
:testing_file,
|
6
|
+
:forest_file,
|
7
|
+
:config_file,
|
8
|
+
:forest_size,
|
9
|
+
:tree_SNP_sample_size,
|
10
|
+
:tree_SNP_total_count,
|
11
|
+
:tree_max_branches,
|
12
|
+
:tree_node_min_size,
|
13
|
+
:loss_function_discrete,
|
14
|
+
:loss_function_continuous,
|
15
|
+
:do_training,
|
16
|
+
:do_testing,
|
17
|
+
:training_set,
|
18
|
+
:output_forest_file
|
19
|
+
)
|
20
|
+
|
21
|
+
DEFAULTS = {
|
22
|
+
:forest_size => 500,
|
23
|
+
:tree_SNP_sample_size => 60,
|
24
|
+
:tree_SNP_total_count => 200,
|
25
|
+
:tree_max_branches => 2000,
|
26
|
+
:tree_node_min_size => 5,
|
27
|
+
|
28
|
+
:loss_function_discrete => 'majority_class',
|
29
|
+
:loss_function_continuous => 'mean',
|
30
|
+
|
31
|
+
:training_file => 'training.data',
|
32
|
+
:testing_file => 'testing.data',
|
33
|
+
:forest_file => 'forest.yml',
|
34
|
+
:config_file => 'config.yml',
|
35
|
+
|
36
|
+
:output_forest_file => 'random_forest.yml'
|
37
|
+
}
|
38
|
+
|
39
|
+
|
40
|
+
def initialize
|
41
|
+
@do_training = false
|
42
|
+
@do_testing = false
|
43
|
+
|
44
|
+
@forest_size = DEFAULTS[:forest_size]
|
45
|
+
@tree_SNP_sample_size = DEFAULTS[:tree_SNP_sample_size]
|
46
|
+
@tree_SNP_total_count = DEFAULTS[:tree_SNP_total_count]
|
47
|
+
@tree_max_branches = DEFAULTS[:tree_max_branches]
|
48
|
+
@tree_node_min_size = DEFAULTS[:tree_node_min_size]
|
49
|
+
@loss_function_discrete = DEFAULTS[:loss_function_discrete]
|
50
|
+
@loss_function_continuous = DEFAULTS[:loss_function_continuous]
|
51
|
+
|
52
|
+
@output_forest_file = File.expand_path(DEFAULTS[:output_forest_file], Dir.pwd)
|
53
|
+
end
|
54
|
+
|
55
|
+
def tree
|
56
|
+
{
|
57
|
+
:snp_sample_size => @tree_SNP_sample_size,
|
58
|
+
:snp_total_count => @tree_SNP_total_count,
|
59
|
+
:tree_max_branches => @tree_max_branches,
|
60
|
+
:tree_node_min_size => @tree_node_min_size
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def load(config_file = DEFAULTS[:config_file])
|
65
|
+
user_config_params = {}
|
66
|
+
if File.exists?(File.expand_path(config_file, Dir.pwd))
|
67
|
+
begin
|
68
|
+
user_config_params = YAML.load(File.open(File.expand_path config_file, Dir.pwd))
|
69
|
+
rescue ArgumentError => e
|
70
|
+
raise Nimbus::WrongFormatFileError, "It was not posible to parse the config file (#{config_file}): \r\n#{e.message} "
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
if user_config_params['input']
|
75
|
+
@training_file = File.expand_path(user_config_params['input']['training'], Dir.pwd) if user_config_params['input']['training']
|
76
|
+
@testing_file = File.expand_path(user_config_params['input']['testing' ], Dir.pwd) if user_config_params['input']['testing']
|
77
|
+
@forest_file = File.expand_path(user_config_params['input']['forest' ], Dir.pwd) if user_config_params['input']['forest']
|
78
|
+
else
|
79
|
+
@training_file = File.expand_path(DEFAULTS[:training_file], Dir.pwd) if File.exists? File.expand_path(DEFAULTS[:training_file], Dir.pwd)
|
80
|
+
@testing_file = File.expand_path(DEFAULTS[:testing_file ], Dir.pwd) if File.exists? File.expand_path(DEFAULTS[:testing_file ], Dir.pwd)
|
81
|
+
@forest_file = File.expand_path(DEFAULTS[:forest_file ], Dir.pwd) if File.exists? File.expand_path(DEFAULTS[:forest_file ], Dir.pwd)
|
82
|
+
end
|
83
|
+
|
84
|
+
@do_training = true if @training_file
|
85
|
+
@do_testing = true if @testing_file
|
86
|
+
|
87
|
+
if @do_testing && !@do_training && !@forest_file
|
88
|
+
raise Nimbus::InputFileError, "There is not random forest data (training file not defined, and forest file not found)."
|
89
|
+
end
|
90
|
+
|
91
|
+
if user_config_params['forest']
|
92
|
+
@forest_size = user_config_params['forest']['forest_size'].to_i if user_config_params['forest']['forest_size']
|
93
|
+
@tree_SNP_total_count = user_config_params['forest']['SNP_total_count'].to_i if user_config_params['forest']['SNP_total_count']
|
94
|
+
@tree_SNP_sample_size = user_config_params['forest']['SNP_sample_size_mtry'].to_i if user_config_params['forest']['SNP_sample_size_mtry']
|
95
|
+
@tree_max_branches = user_config_params['forest']['max_branches'].to_i if user_config_params['forest']['max_branches']
|
96
|
+
@tree_node_min_size = user_config_params['forest']['node_min_size'].to_i if user_config_params['forest']['node_min_size']
|
97
|
+
end
|
98
|
+
|
99
|
+
check_configuration
|
100
|
+
log_configuration
|
101
|
+
end
|
102
|
+
|
103
|
+
def load_training_data
|
104
|
+
File.open(@training_file) {|file|
|
105
|
+
@training_set = Nimbus::TrainingSet.new({}, {})
|
106
|
+
file.each do |line|
|
107
|
+
next if line.strip == ''
|
108
|
+
data_feno, data_id, *snp_list = line.strip.split
|
109
|
+
raise Nimbus::InputFileError, "Individual ##{data_id} from training set has no value for all #{@tree_SNP_total_count} SNPs" unless snp_list.size == @tree_SNP_total_count
|
110
|
+
@training_set.individuals[data_id.to_i] = Nimbus::Individual.new(data_id.to_i, data_feno.to_f, snp_list.map{|snp| snp.to_i})
|
111
|
+
@training_set.ids_fenotypes[data_id.to_i] = data_feno.to_f
|
112
|
+
end
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def load_testing_data
|
117
|
+
end
|
118
|
+
|
119
|
+
def load_forest_data
|
120
|
+
end
|
121
|
+
|
122
|
+
def check_configuration
|
123
|
+
raise Nimbus::ConfigurationError, "The mtry sample size must be smaller than the total SNPs count." if @tree_SNP_sample_size > @tree_SNP_total_count
|
124
|
+
end
|
125
|
+
|
126
|
+
def log_configuration
|
127
|
+
Nimbus.message "*" * 50
|
128
|
+
Nimbus.message "* Nimbus configured with the following parameters: "
|
129
|
+
Nimbus.message "* Forest size: #{@forest_size} trees"
|
130
|
+
Nimbus.message "* Total SNP count: #{@tree_SNP_total_count}"
|
131
|
+
Nimbus.message "* SNPs sample size (mtry): #{@SNP_sample_size}"
|
132
|
+
Nimbus.message "* Maximum number of branches per tree: #{@tree_max_branches}"
|
133
|
+
Nimbus.message "* Minimun node size in tree: #{@tree_node_min_size}"
|
134
|
+
Nimbus.message "*" * 50
|
135
|
+
if @do_training
|
136
|
+
Nimbus.message "* Training data:"
|
137
|
+
Nimbus.message "* Training file: #{@training_file}"
|
138
|
+
Nimbus.message "*" * 50
|
139
|
+
end
|
140
|
+
|
141
|
+
if @do_testing
|
142
|
+
Nimbus.message "* Data to be tested:"
|
143
|
+
Nimbus.message "* Testing file: #{@testing_file}"
|
144
|
+
if @forest_file && !@do_training
|
145
|
+
Nimbus.message "* using the structure of the random forest stored in:"
|
146
|
+
Nimbus.message "* Random forest file: #{@forest_file}"
|
147
|
+
end
|
148
|
+
Nimbus.message "*" * 50
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Nimbus
|
2
|
+
class Error < StandardError; end
|
3
|
+
class InvalidOptionError < Error; end
|
4
|
+
class InputFileError < Error; end
|
5
|
+
class WrongFormatFileError < Error; end
|
6
|
+
class ConfigurationError < Error; end
|
7
|
+
class ForestError < Error; end
|
8
|
+
class TreeError < Error; end
|
9
|
+
class IndividualError < Error; end
|
10
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Nimbus
|
2
|
+
|
3
|
+
class Forest
|
4
|
+
attr_accessor :size, :trees
|
5
|
+
attr_accessor :options
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@trees = []
|
9
|
+
@options = config
|
10
|
+
@size = config.forest_size
|
11
|
+
raise Nimbus::ForestError, "Forest size parameter (#{@size}) is invalid. You need at least one tree." if @size < 1
|
12
|
+
end
|
13
|
+
|
14
|
+
def grow
|
15
|
+
i=0
|
16
|
+
@size.times do
|
17
|
+
i+=1
|
18
|
+
tree = Tree.new @options.tree
|
19
|
+
@trees << tree.seed(@options.training_set.individuals, individuals_random_sample, @options.training_set.ids_fenotypes)
|
20
|
+
#OOB << Tree.traverse OOB por el tree.
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_yaml
|
25
|
+
@trees.to_yaml
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def individuals_random_sample
|
32
|
+
bag = (1..@options.training_set.individuals.size).to_a
|
33
|
+
individuals_sample = bag.inject([]){|items, i| items << bag.sample }.sort
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Nimbus
|
2
|
+
module LossFunctions
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def average(ids, value_table)
|
7
|
+
ids.inject(0.0){|sum, i| sum + value_table[i]} / ids.size
|
8
|
+
end
|
9
|
+
|
10
|
+
def mean_squared_error(ids, value_table, mean = nil)
|
11
|
+
mean ||= self.average ids, value_table
|
12
|
+
ids.inject(0.0){|sum, i| sum + ((value_table[i] - mean)**2) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def quadratic_loss(ids, value_table, mean = nil)
|
16
|
+
self.mean_squared_error(ids, value_table, mean) / ids.size
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
data/lib/nimbus/tree.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
module Nimbus
|
2
|
+
|
3
|
+
class Tree
|
4
|
+
attr_accessor :snp_sample_size, :snp_total_count, :node_min_size, :max_branches, :structure
|
5
|
+
attr_accessor :individuals, :id_to_fenotype
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@snp_total_count = options[:snp_total_count]
|
9
|
+
@snp_sample_size = options[:snp_sample_size]
|
10
|
+
@node_min_size = options[:tree_node_min_size]
|
11
|
+
@max_branches = options[:tree_max_branches]
|
12
|
+
end
|
13
|
+
|
14
|
+
def seed(all_individuals, individuals_sample, ids_fenotypes)
|
15
|
+
@individuals = all_individuals
|
16
|
+
@id_to_fenotype = ids_fenotypes
|
17
|
+
|
18
|
+
@structure = build_node individuals_sample, Nimbus::LossFunctions.average(individuals_sample, @id_to_fenotype)
|
19
|
+
end
|
20
|
+
|
21
|
+
def build_node(individuals_ids, y_hat)
|
22
|
+
# General loss function value for the node
|
23
|
+
individuals_count = individuals_ids.size
|
24
|
+
return y_hat.round(5) if individuals_count < @node_min_size
|
25
|
+
node_loss_function = Nimbus::LossFunctions.quadratic_loss individuals_ids, @id_to_fenotype, y_hat
|
26
|
+
|
27
|
+
# Finding the SNP that minimizes loss function
|
28
|
+
snps = snps_random_sample
|
29
|
+
min_loss, min_SNP, split, means = node_loss_function, nil, nil, nil
|
30
|
+
|
31
|
+
snps.each do |snp|
|
32
|
+
individuals_split_by_snp_value = split_by_snp_value individuals_ids, snp
|
33
|
+
mean_0 = Nimbus::LossFunctions.average individuals_split_by_snp_value[0], @id_to_fenotype
|
34
|
+
mean_1 = Nimbus::LossFunctions.average individuals_split_by_snp_value[1], @id_to_fenotype
|
35
|
+
mean_2 = Nimbus::LossFunctions.average individuals_split_by_snp_value[2], @id_to_fenotype
|
36
|
+
loss_0 = Nimbus::LossFunctions.mean_squared_error individuals_split_by_snp_value[0], @id_to_fenotype, mean_0
|
37
|
+
loss_1 = Nimbus::LossFunctions.mean_squared_error individuals_split_by_snp_value[1], @id_to_fenotype, mean_1
|
38
|
+
loss_2 = Nimbus::LossFunctions.mean_squared_error individuals_split_by_snp_value[2], @id_to_fenotype, mean_2
|
39
|
+
loss_snp = (loss_0 + loss_1 + loss_2) / individuals_count
|
40
|
+
|
41
|
+
min_loss, min_SNP, split, means = loss_snp, snp, individuals_split_by_snp_value, [mean_0, mean_1, mean_2] if loss_snp < min_loss
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
return build_branch(min_SNP, split, means, y_hat) if min_loss < node_loss_function
|
46
|
+
return y_hat.round(5)
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_branch(snp, split, y_hats, parent_y_hat)
|
50
|
+
node_0 = split[0].size == 0 ? parent_y_hat.round(5) : build_node(split[0], y_hats[0])
|
51
|
+
node_1 = split[1].size == 0 ? parent_y_hat.round(5) : build_node(split[1], y_hats[1])
|
52
|
+
node_2 = split[2].size == 0 ? parent_y_hat.round(5) : build_node(split[2], y_hats[2])
|
53
|
+
|
54
|
+
return { snp => [node_0, node_1, node_2] }
|
55
|
+
end
|
56
|
+
|
57
|
+
def traverse
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.traverse(structure, data)
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def snps_random_sample
|
69
|
+
(1..@snp_total_count).to_a.sample(@snp_sample_size).sort
|
70
|
+
end
|
71
|
+
|
72
|
+
def split_by_snp_value(ids, snp)
|
73
|
+
split = [[], [], []]
|
74
|
+
ids.each do |i|
|
75
|
+
split[ @individuals[i].snp_list[snp-1] ] << @individuals[i].id
|
76
|
+
end
|
77
|
+
split
|
78
|
+
rescue => ex
|
79
|
+
raise Nimbus::TreeError, "Values for SNPs columns must be in [0, 1, 2]"
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
data/lib/nimbus.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'optparse'
|
3
|
+
require 'nimbus/exceptions'
|
4
|
+
require 'nimbus/training_set'
|
5
|
+
require 'nimbus/configuration'
|
6
|
+
require 'nimbus/loss_functions'
|
7
|
+
require 'nimbus/individual'
|
8
|
+
require 'nimbus/tree'
|
9
|
+
require 'nimbus/forest'
|
10
|
+
require 'nimbus/application'
|
11
|
+
|
12
|
+
module Nimbus
|
13
|
+
|
14
|
+
STDERR = $stderr
|
15
|
+
STDOUT = $stdout
|
16
|
+
|
17
|
+
# Nimbus module singleton methods.
|
18
|
+
#
|
19
|
+
class << self
|
20
|
+
# Current Nimbus Application
|
21
|
+
def application
|
22
|
+
@application ||= ::Nimbus::Application.new
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set the current Nimbus application object.
|
26
|
+
def application=(app)
|
27
|
+
@application = app
|
28
|
+
end
|
29
|
+
|
30
|
+
# Stops the execution of the Nimbus application.
|
31
|
+
def stop(msg = "Error: Nimbus finished.") # :nodoc:
|
32
|
+
STDERR.puts msg
|
33
|
+
exit(false)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Writes message to the standard output
|
37
|
+
def message(msg)
|
38
|
+
STDOUT.puts msg
|
39
|
+
end
|
40
|
+
|
41
|
+
# Writes message to the error output
|
42
|
+
def error_message(msg)
|
43
|
+
STDERR.puts msg
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#Input files
|
2
|
+
input:
|
3
|
+
training: Rtraining.h40
|
4
|
+
testing: Rtesting.h40
|
5
|
+
|
6
|
+
#Forest parameters
|
7
|
+
forest:
|
8
|
+
forest_size: 500 #how many trees
|
9
|
+
SNP_sample_size_mtry: 60 #mtry
|
10
|
+
SNP_total_count: 200
|
11
|
+
max_branches: 2000
|
12
|
+
node_min_size: 5
|
13
|
+
loss_function_discrete: 2
|
14
|
+
loss_function_cont: 2
|
data/spec/nimbus_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nimbus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: "0.1"
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- "Juanjo Baz\xC3\xA1n"
|
9
|
+
- "Oscar Gonz\xC3\xA1lez Recio"
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2011-08-01 00:00:00 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 2.5.0
|
25
|
+
type: :development
|
26
|
+
version_requirements: *id001
|
27
|
+
description: Nimbus is a Ruby gem to implement Random Forest in a genomic selection context.
|
28
|
+
email:
|
29
|
+
- jjbazan@gmail.com
|
30
|
+
executables:
|
31
|
+
- nimbus
|
32
|
+
extensions: []
|
33
|
+
|
34
|
+
extra_rdoc_files: []
|
35
|
+
|
36
|
+
files:
|
37
|
+
- MIT-LICENSE.txt
|
38
|
+
- README.rdoc
|
39
|
+
- lib/nimbus/application.rb
|
40
|
+
- lib/nimbus/configuration.rb
|
41
|
+
- lib/nimbus/exceptions.rb
|
42
|
+
- lib/nimbus/forest.rb
|
43
|
+
- lib/nimbus/individual.rb
|
44
|
+
- lib/nimbus/loss_functions.rb
|
45
|
+
- lib/nimbus/training_set.rb
|
46
|
+
- lib/nimbus/tree.rb
|
47
|
+
- lib/nimbus.rb
|
48
|
+
- spec/fixtures/config.yml
|
49
|
+
- spec/nimbus_spec.rb
|
50
|
+
- spec/spec_helper.rb
|
51
|
+
- bin/nimbus
|
52
|
+
homepage: http://github.com/xuanxu/nimbus
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options:
|
57
|
+
- --main
|
58
|
+
- README.rdoc
|
59
|
+
- --charset=UTF-8
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.8.6
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Random Forest algorithm for Genomics
|
81
|
+
test_files:
|
82
|
+
- spec/fixtures/config.yml
|
83
|
+
- spec/nimbus_spec.rb
|
84
|
+
- spec/spec_helper.rb
|