fuzzy_infer 0.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/.gitignore +17 -0
- data/Gemfile +10 -0
- data/LICENSE +22 -0
- data/README.markdown +48 -0
- data/Rakefile +12 -0
- data/fuzzy_infer.gemspec +22 -0
- data/lib/fuzzy_infer.rb +14 -0
- data/lib/fuzzy_infer/active_record_class_methods.rb +15 -0
- data/lib/fuzzy_infer/active_record_instance_methods.rb +14 -0
- data/lib/fuzzy_infer/fuzzy_inference_machine.rb +126 -0
- data/lib/fuzzy_infer/registry.rb +15 -0
- data/lib/fuzzy_infer/version.rb +3 -0
- data/test/helper.rb +83 -0
- data/test/test_fuzzy_infer.rb +58 -0
- metadata +101 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Seamus Abshere
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# FuzzyInfer
|
2
|
+
|
3
|
+
## Where it's used
|
4
|
+
|
5
|
+
* [Brighter Planet CM1 Impact Estimate web service](http://impact.brighterplanet.com)
|
6
|
+
|
7
|
+
## setup
|
8
|
+
|
9
|
+
1) gem install a bleeding edge earth
|
10
|
+
|
11
|
+
cd earth
|
12
|
+
git pull
|
13
|
+
gem build earth.gemspec
|
14
|
+
gem install earth-0.11.10.gem --ignore-dependencies --no-rdoc --no-ri
|
15
|
+
|
16
|
+
2) create your test database
|
17
|
+
|
18
|
+
mysql -u root -ppassword -e "create database test_fuzzy_infer charset utf8"
|
19
|
+
|
20
|
+
3) load cbecs (just the first time - note that it is hardcoded to ONLY run cbecs data_miner)
|
21
|
+
|
22
|
+
RUN_DATA_MINER=true rake
|
23
|
+
|
24
|
+
## further testing
|
25
|
+
|
26
|
+
rake
|
27
|
+
|
28
|
+
## future plans
|
29
|
+
|
30
|
+
**in the future the fuzzy inference machine will make TEMPORARY tables, rather than gum up your db**
|
31
|
+
|
32
|
+
for now, it makes permanent tables so that you can examine them
|
33
|
+
|
34
|
+
wishlist:
|
35
|
+
|
36
|
+
* re-use FIM for multiple targets
|
37
|
+
* cache #fuzzy_infer
|
38
|
+
* randomize names of all added columns
|
39
|
+
* use arel to generate sql(?)
|
40
|
+
|
41
|
+
## Database compatibility
|
42
|
+
|
43
|
+
* mysql
|
44
|
+
* postgresql
|
45
|
+
|
46
|
+
## Copyright
|
47
|
+
|
48
|
+
Copyright 2012 Brighter Planet, Inc.
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/testtask'
|
6
|
+
Rake::TestTask.new(:test) do |test|
|
7
|
+
test.libs << 'lib' << 'test'
|
8
|
+
test.pattern = 'test/**/test_*.rb'
|
9
|
+
test.verbose = true
|
10
|
+
end
|
11
|
+
|
12
|
+
task :default => :test
|
data/fuzzy_infer.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/fuzzy_infer/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Seamus Abshere", "Ian Hough", "Matt Kling"]
|
6
|
+
gem.email = ["seamus@abshere.net", 'ijhough@gmail.com', 'mattkling@gmail.com']
|
7
|
+
desc = %q{Use fuzzy set analysis to infer missing values. You provide a sigma function, a membership function, and a kernel.}
|
8
|
+
gem.description = desc
|
9
|
+
gem.summary = desc
|
10
|
+
gem.homepage = "https://github.com/seamusabshere/fuzzy_infer"
|
11
|
+
|
12
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
13
|
+
gem.files = `git ls-files`.split("\n")
|
14
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
gem.name = "fuzzy_infer"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = FuzzyInfer::VERSION
|
18
|
+
|
19
|
+
gem.add_runtime_dependency 'activesupport', '>=3'
|
20
|
+
gem.add_runtime_dependency 'activerecord', '>=3'
|
21
|
+
gem.add_runtime_dependency 'hashie'
|
22
|
+
end
|
data/lib/fuzzy_infer.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
|
3
|
+
require "fuzzy_infer/version"
|
4
|
+
require 'fuzzy_infer/registry'
|
5
|
+
require 'fuzzy_infer/active_record_class_methods'
|
6
|
+
require 'fuzzy_infer/active_record_instance_methods'
|
7
|
+
require 'fuzzy_infer/fuzzy_inference_machine'
|
8
|
+
|
9
|
+
module FuzzyInfer
|
10
|
+
# Your code goes here...
|
11
|
+
end
|
12
|
+
|
13
|
+
ActiveRecord::Base.send :include, FuzzyInfer::ActiveRecordInstanceMethods
|
14
|
+
ActiveRecord::Base.extend FuzzyInfer::ActiveRecordClassMethods
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'hashie/mash'
|
2
|
+
|
3
|
+
module FuzzyInfer
|
4
|
+
module ActiveRecordClassMethods
|
5
|
+
# Configure fuzzy inferences
|
6
|
+
# see test/helper.rb for an example
|
7
|
+
def fuzzy_infer(options = {})
|
8
|
+
options = ::Hashie::Mash.new options
|
9
|
+
options.target.each do |target|
|
10
|
+
Registry.instance[name] ||= {}
|
11
|
+
Registry.instance[name][target] = options
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module FuzzyInfer
|
2
|
+
module ActiveRecordInstanceMethods
|
3
|
+
# Returns a new FuzzyInferenceMachine instance that can infer this target (field)
|
4
|
+
def fuzzy_inference_machine(target)
|
5
|
+
target = target.to_sym
|
6
|
+
FuzzyInferenceMachine.new self, target, Registry.config_for(self.class.name, target)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Shortcut to creating a FIM and immediately calling it
|
10
|
+
def fuzzy_infer(target)
|
11
|
+
fuzzy_inference_machine(target).infer
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module FuzzyInfer
|
2
|
+
class FuzzyInferenceMachine
|
3
|
+
|
4
|
+
attr_reader :kernel
|
5
|
+
attr_reader :target
|
6
|
+
attr_reader :config
|
7
|
+
|
8
|
+
def initialize(kernel, target, config)
|
9
|
+
@kernel = kernel
|
10
|
+
@target = target
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def infer
|
15
|
+
calculate_table!
|
16
|
+
retval = select_value(%{SELECT SUM(fuzzy_weighted_value)/SUM(fuzzy_membership) FROM #{table_name}}).to_f
|
17
|
+
execute %{DROP TABLE #{table_name}}
|
18
|
+
retval
|
19
|
+
end
|
20
|
+
|
21
|
+
# TODO technically I could use this to generate the SQL
|
22
|
+
def arel_table
|
23
|
+
calculate_table!
|
24
|
+
Arel::Table.new table_name
|
25
|
+
end
|
26
|
+
|
27
|
+
def basis
|
28
|
+
@basis ||= kernel.attributes.symbolize_keys.slice(*config.basis).reject { |k, v| v.nil? }
|
29
|
+
end
|
30
|
+
|
31
|
+
def sigma
|
32
|
+
@sigma ||= basis.inject({}) do |memo, (k, v)|
|
33
|
+
memo[k] = select_value(%{SELECT #{sigma_sql(k, v)} FROM #{kernel.class.quoted_table_name} WHERE #{target_not_null_sql} AND #{basis_not_null_sql}}).to_f
|
34
|
+
memo
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def membership
|
39
|
+
return @membership if @membership
|
40
|
+
sql = kernel.send(config.membership, basis).dup
|
41
|
+
basis.keys.each do |k|
|
42
|
+
sql.gsub! ":#{k}_n_w", quote_column_name("#{k}_n_w")
|
43
|
+
end
|
44
|
+
@membership = sql
|
45
|
+
end
|
46
|
+
|
47
|
+
# In case you want to `cache_method :infer` with https://github.com/seamusabshere/cache_method
|
48
|
+
def method_cache_hash
|
49
|
+
[kernel.class.name, basis, target, config].hash
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def calculate_table!
|
55
|
+
return if table_exists?(table_name)
|
56
|
+
execute %{CREATE TEMPORARY TABLE #{table_name} AS SELECT * FROM #{kernel.class.quoted_table_name} WHERE #{target_not_null_sql} AND #{basis_not_null_sql}}
|
57
|
+
execute %{ALTER TABLE #{table_name} #{weight_create_columns_sql}}
|
58
|
+
execute %{ALTER TABLE #{table_name} ADD COLUMN fuzzy_membership FLOAT default null}
|
59
|
+
execute %{ALTER TABLE #{table_name} ADD COLUMN fuzzy_weighted_value FLOAT default null}
|
60
|
+
execute %{UPDATE #{table_name} SET #{weight_calculate_sql}}
|
61
|
+
weight_normalize_frags.each do |sql|
|
62
|
+
execute sql
|
63
|
+
end
|
64
|
+
execute %{UPDATE #{table_name} SET fuzzy_membership = #{membership_sql}}
|
65
|
+
execute %{UPDATE #{table_name} SET fuzzy_weighted_value = fuzzy_membership * #{quote_column_name(target)}}
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def membership_sql
|
70
|
+
if config.weight
|
71
|
+
"(#{membership}) * #{quote_column_name(config.weight.to_s)}"
|
72
|
+
else
|
73
|
+
membership
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def weight_normalize_frags
|
78
|
+
basis.keys.map do |k|
|
79
|
+
max = select_value("SELECT MAX(#{quote_column_name("#{k}_w")}) FROM #{table_name}").to_f
|
80
|
+
"UPDATE #{table_name} SET #{quote_column_name("#{k}_n_w")} = #{quote_column_name("#{k}_w")} / #{max}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def weight_calculate_sql
|
85
|
+
basis.keys.map do |k|
|
86
|
+
"#{quote_column_name("#{k}_w")} = 1.0 / (#{sigma[k]}*SQRT(2*PI())) * EXP(-(POW(#{quote_column_name(k)} - #{basis[k]},2))/(2*POW(#{sigma[k]},2)))"
|
87
|
+
end.join(', ')
|
88
|
+
end
|
89
|
+
|
90
|
+
def sigma_sql(column_name, value)
|
91
|
+
sql = config.sigma.dup
|
92
|
+
sql.gsub! ':column', quote_column_name(column_name)
|
93
|
+
sql.gsub! ':value', value.to_f.to_s
|
94
|
+
sql
|
95
|
+
end
|
96
|
+
|
97
|
+
def table_name
|
98
|
+
@table_name ||= "fuzzy_infer_#{Time.now.strftime('%Y_%m_%d_%H_%M_%S')}_#{Kernel.rand(1e11)}"
|
99
|
+
end
|
100
|
+
|
101
|
+
def weight_create_columns_sql
|
102
|
+
basis.keys.inject([]) do |memo, k|
|
103
|
+
memo << "ADD COLUMN #{quote_column_name("#{k}_w")} FLOAT default null"
|
104
|
+
memo << "ADD COLUMN #{quote_column_name("#{k}_n_w")} FLOAT default null"
|
105
|
+
memo
|
106
|
+
end.flatten.join ', '
|
107
|
+
end
|
108
|
+
|
109
|
+
def basis_not_null_sql
|
110
|
+
basis.keys.map do |basis|
|
111
|
+
"#{quote_column_name(basis)} IS NOT NULL"
|
112
|
+
end.join ' AND '
|
113
|
+
end
|
114
|
+
|
115
|
+
def target_not_null_sql
|
116
|
+
"#{quote_column_name(target)} IS NOT NULL"
|
117
|
+
end
|
118
|
+
|
119
|
+
def connection
|
120
|
+
kernel.connection
|
121
|
+
end
|
122
|
+
|
123
|
+
delegate :execute, :quote_column_name, :select_value, :table_exists?, :to => :connection
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module FuzzyInfer
|
4
|
+
class Registry < ::Hash
|
5
|
+
class << self
|
6
|
+
def config_for(class_name, target)
|
7
|
+
raise %{[fuzzy_infer] Zero machines are defined on #{class_name}.} unless instance.has_key?(class_name)
|
8
|
+
raise %{[fuzzy_infer] Target #{target.inspect} is not available on #{class_name}.} unless instance[class_name].has_key?(target)
|
9
|
+
instance[class_name][target]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
include ::Singleton
|
14
|
+
end
|
15
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
require 'active_record'
|
4
|
+
case ENV['DB_ADAPTER']
|
5
|
+
when 'postgresql'
|
6
|
+
adapter = 'postgresql'
|
7
|
+
username = ENV['POSTGRES_USERNAME'] || `whoami`.chomp
|
8
|
+
password = ENV['POSTGRES_PASSWORD']
|
9
|
+
database = ENV['POSTGRES_DATABASE'] || 'test_fuzzy_infer'
|
10
|
+
else
|
11
|
+
adapter = 'mysql2'
|
12
|
+
database = 'test_fuzzy_infer'
|
13
|
+
username = 'root'
|
14
|
+
password = 'password'
|
15
|
+
end
|
16
|
+
config = {
|
17
|
+
'encoding' => 'utf8',
|
18
|
+
'adapter' => adapter,
|
19
|
+
'database' => database,
|
20
|
+
}
|
21
|
+
config['username'] = username if username
|
22
|
+
config['password'] = password if password
|
23
|
+
ActiveRecord::Base.establish_connection config
|
24
|
+
require 'logger'
|
25
|
+
ActiveRecord::Base.logger = Logger.new $stderr
|
26
|
+
ActiveRecord::Base.logger.level = Logger::DEBUG
|
27
|
+
|
28
|
+
require 'earth'
|
29
|
+
if ENV['RUN_DATA_MINER'] == 'true'
|
30
|
+
Earth.init :hospitality, :load_data_miner => true
|
31
|
+
ActiveRecord::Base.logger.level = Logger::INFO
|
32
|
+
CommercialBuildingEnergyConsumptionSurveyResponse.run_data_miner!
|
33
|
+
$stderr.puts "Done!"
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
|
37
|
+
Earth.init :hospitality
|
38
|
+
|
39
|
+
require 'minitest/spec'
|
40
|
+
require 'minitest/autorun'
|
41
|
+
require 'minitest/reporters'
|
42
|
+
MiniTest::Unit.runner = MiniTest::SuiteRunner.new
|
43
|
+
MiniTest::Unit.runner.reporters << MiniTest::Reporters::SpecReporter.new
|
44
|
+
|
45
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
46
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
47
|
+
require 'fuzzy_infer'
|
48
|
+
# class MiniTest::Spec
|
49
|
+
# end
|
50
|
+
|
51
|
+
CBECS = CommercialBuildingEnergyConsumptionSurveyResponse
|
52
|
+
class CBECS < ActiveRecord::Base
|
53
|
+
fuzzy_infer :target => [:electricity_per_room_night, :natural_gas_per_room_night,
|
54
|
+
:fuel_oil_per_room_night, :district_heat_per_room_night], # list of columns that this model is designed to infer
|
55
|
+
:basis => [:lodging_rooms, :construction_year, :heating_degree_days,
|
56
|
+
:cooling_degree_days, :floors, :ac_coverage], # list of columns that are believed to affect energy use (aka MU)
|
57
|
+
:sigma => "(STDDEV_SAMP(:column)/5)+(ABS(AVG(:column)-:value)/3)", # empirically determined formula (SQL!) that captures the desired sample size once all the weights are compiled, across the full range of possible mu values
|
58
|
+
:membership => :energy_use_membership, # name of instance method to be called on kernel
|
59
|
+
:weight => :weighting # (optional) a pre-existing row weighting, if any, provided by the dataset authors
|
60
|
+
|
61
|
+
# empirically determined formula that minimizes variance between real and predicted energy use
|
62
|
+
# SQL! - :heating_degree_days_n_w will be replaced with, for example, `tmp_table_9301293.hdd_normalized_weight`
|
63
|
+
def energy_use_membership(basis)
|
64
|
+
keys = basis.keys
|
65
|
+
|
66
|
+
formula = "(POW(:heating_degree_days_n_w, 0.8) + POW(:cooling_degree_days_n_w, 0.8))"
|
67
|
+
|
68
|
+
formula += if keys.include? :lodging_rooms and keys.include? :floors
|
69
|
+
" * (POW(:lodging_rooms_n_w, 0.8) + POW(:floors_n_w, 0.8))"
|
70
|
+
elsif keys.include? :lodging_rooms
|
71
|
+
" * POW(:lodging_rooms_n_w, 0.8)"
|
72
|
+
elsif keys.include? :floors
|
73
|
+
" * POW(:floors_n_w, 0.8)"
|
74
|
+
else
|
75
|
+
""
|
76
|
+
end
|
77
|
+
|
78
|
+
formula += " * POW(:percent_cooled_n_w, 0.8)" if keys.include? :percent_cooled
|
79
|
+
formula += " * POW(:construction_year_n_w, 0.8)" if keys.include? :construction_year
|
80
|
+
|
81
|
+
formula
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
describe FuzzyInfer do
|
5
|
+
describe FuzzyInfer::ActiveRecordClassMethods do
|
6
|
+
it 'adds a way to configure a FuzzyInferenceMachine' do
|
7
|
+
CBECS.respond_to?(:fuzzy_infer).must_equal true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe FuzzyInfer::ActiveRecordInstanceMethods do
|
12
|
+
it 'adds a way to infer a particular target (field)' do
|
13
|
+
CBECS.new.respond_to?(:fuzzy_infer).must_equal true
|
14
|
+
end
|
15
|
+
it 'adds a way to get a FIM object' do
|
16
|
+
CBECS.new.respond_to?(:fuzzy_inference_machine).must_equal true
|
17
|
+
end
|
18
|
+
it "creates a new FIM object" do
|
19
|
+
e = CBECS.new.fuzzy_inference_machine(:electricity_per_room_night)
|
20
|
+
e.must_be_instance_of FuzzyInfer::FuzzyInferenceMachine
|
21
|
+
end
|
22
|
+
end
|
23
|
+
# CBECS.new(:heating_degree_days => 2778, :lodging_rooms => 20).fuzzy_infer(:electricity_per_room_night)
|
24
|
+
|
25
|
+
describe FuzzyInfer::FuzzyInferenceMachine do
|
26
|
+
before do
|
27
|
+
@kernel = CBECS.new(:heating_degree_days => 2778, :cooling_degree_days => 400, :lodging_rooms => 20, :principal_activity => 'Partying')
|
28
|
+
@e = @kernel.fuzzy_inference_machine(:electricity_per_room_night)
|
29
|
+
end
|
30
|
+
describe '#basis' do
|
31
|
+
it "is the union of the kernel's attributes with the basis" do
|
32
|
+
@e.basis.must_equal :lodging_rooms => 20, :heating_degree_days => 2778.0, :cooling_degree_days => 400.0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
describe "the temp table" do
|
36
|
+
it "excludes rows from the original table where basis or target is nil, but includes rows where they are 0" do
|
37
|
+
ActiveRecord::Base.connection.select_value(@e.arel_table.project('COUNT(*)').to_sql).to_f.must_equal 192
|
38
|
+
end
|
39
|
+
end
|
40
|
+
describe '#sigma' do
|
41
|
+
it "is calculated from the original table, but only those rows that are also in the temp table" do
|
42
|
+
@e.sigma[:heating_degree_days].must_be_close_to 411.9, 0.1
|
43
|
+
@e.sigma[:cooling_degree_days].must_be_close_to 267.6, 0.1
|
44
|
+
@e.sigma[:lodging_rooms].must_be_close_to 55.0, 0.1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
describe '#membership' do
|
48
|
+
it 'depends on the kernel' do
|
49
|
+
@e.membership.must_match %r{\(POW\(.heating_degree_days_n_w.,\ 0\.8\)\ \+\ POW\(.cooling_degree_days_n_w.,\ 0\.8\)\)\ \*\ POW\(.lodging_rooms_n_w.,\ 0\.8\)}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
describe '#infer' do
|
53
|
+
it 'guesses!' do
|
54
|
+
@e.infer.must_be_close_to 17.75, 0.01
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fuzzy_infer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Seamus Abshere
|
9
|
+
- Ian Hough
|
10
|
+
- Matt Kling
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2012-02-21 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: activesupport
|
18
|
+
requirement: &2153031100 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '3'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *2153031100
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activerecord
|
29
|
+
requirement: &2153029920 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '3'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *2153029920
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: hashie
|
40
|
+
requirement: &2153029260 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
type: :runtime
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *2153029260
|
49
|
+
description: Use fuzzy set analysis to infer missing values. You provide a sigma function,
|
50
|
+
a membership function, and a kernel.
|
51
|
+
email:
|
52
|
+
- seamus@abshere.net
|
53
|
+
- ijhough@gmail.com
|
54
|
+
- mattkling@gmail.com
|
55
|
+
executables: []
|
56
|
+
extensions: []
|
57
|
+
extra_rdoc_files: []
|
58
|
+
files:
|
59
|
+
- .gitignore
|
60
|
+
- Gemfile
|
61
|
+
- LICENSE
|
62
|
+
- README.markdown
|
63
|
+
- Rakefile
|
64
|
+
- fuzzy_infer.gemspec
|
65
|
+
- lib/fuzzy_infer.rb
|
66
|
+
- lib/fuzzy_infer/active_record_class_methods.rb
|
67
|
+
- lib/fuzzy_infer/active_record_instance_methods.rb
|
68
|
+
- lib/fuzzy_infer/fuzzy_inference_machine.rb
|
69
|
+
- lib/fuzzy_infer/registry.rb
|
70
|
+
- lib/fuzzy_infer/version.rb
|
71
|
+
- test/helper.rb
|
72
|
+
- test/test_fuzzy_infer.rb
|
73
|
+
homepage: https://github.com/seamusabshere/fuzzy_infer
|
74
|
+
licenses: []
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.8.15
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: Use fuzzy set analysis to infer missing values. You provide a sigma function,
|
97
|
+
a membership function, and a kernel.
|
98
|
+
test_files:
|
99
|
+
- test/helper.rb
|
100
|
+
- test/test_fuzzy_infer.rb
|
101
|
+
has_rdoc:
|