Module: FuzzyRealty
- Defined in:
- lib/fuzzy_realty.rb,
lib/classes.rb,
lib/weights.rb,
lib/rulebase.rb,
lib/scores_table.rb
Overview
If set this flag will turn on debugging printouts $debug = true;
Defined Under Namespace
Classes: ExpertSystem, Listing, Parameter, Query
Constant Summary collapse
- WEIGHTS =
class Parameter uses this hash to determine what is a valid type.
-
This must be matched by a rule in rulebase.rb
-
{ :sqft => 15, :price => 10, :location => 25, :style => 18 }
- RULES =
lambda do rules = { # Not yet implemented #:bathrooms => , #:bedrooms => , #:garage => , #:deck => , # Price is match when desired is 90-105% of actual. Otherwise give a # reduced factor. :price => lambda do |listing,desired| puts "Called price" if $debug actual = listing.price.to_f result = if (desired*0.90..desired*1.05) === actual 1.0 else 1 - ((desired - actual) / actual).abs end puts result if $debug result end, # Location calc. does lookup to find score for desired and actual ## Currently just return 1 if exact, 0 otherwise :location => lambda do |listing,desired| puts "Called location" if $debug # Perform a quick lookup (i.e. FuzzyRealty::LOCN[:A][:A] => 1.0) puts FuzzyRealty::LOCN[desired.to_sym][listing.location.to_sym] if $debug FuzzyRealty::LOCN[desired.to_sym][listing.location.to_sym] end, :sqft => lambda do |listing,desired| puts "Called sqft" if $debug actual = listing.sqft result = if (actual + 50) >= desired 1.0 elsif (actual + 150) >= desired 0.8 elsif (actual + 300) >= desired 0.5 else 0.0 end puts result if $debug result end, # Style's follow lookup table similar to Location :style => lambda do |listing,desired| puts "Called style" if $debug desired = FuzzyRealty::STYLE[:Symbol][desired] actual = FuzzyRealty::STYLE[:Symbol][listing.style] puts FuzzyRealty::STYLE[desired][actual] if $debug FuzzyRealty::STYLE[desired][actual] end } rules.default = lambda {|a,b| raise "Invalid type used in rule lookup"} rules end.call
- LOCN =
Table for looking up score of relative locations
A is a high-class suburb B is a middle-class area C is an older middle-class area D is a “ghetto”
A B C D
A 1.0 0.75 0.2 0.0 B 0.75 1.00 0.4 0.1 C 0.2 0.4 1.0 0.6 D 0.0 0.1 0.6 1.0
Hash.new(0).merge({ :A => {:A => 1.0, :B => 0.75, :C => 0.2, :D => 0.0}, :B => {:A => 0.75, :B => 1.0, :C => 0.4, :D => 0.1}, :C => {:A => 0.2, :B => 0.4, :C => 1.0, :D => 0.6}, :D => {:A => 0.0, :B => 0.1, :C => 0.6, :D => 1.0} })
- STYLE =
Table for lookup of score of desired and actual styles
-
Arbitrary values provied by my wife, at present the leanings aren’t quite right
Bu = Bungalow, Bi = Bilevel, Sp = Splitlevel, Tw = Two Story, Co = Condo | | Bu | Sp | Tw | Bi | Co | | Bu | 1 | 0.4 | 0.8 | 0.65 | 0.1 | | Sp | 0.5 | 1 | 0.7 | 0.95 | 0.2 | | Tw | 0.0 | 0.6 | 1 | 0.5 | 0.0 | | Bi | 0.75 | 0.6 | 0.8 | 1 | 0.0 | | Co | 0.7 | 0.0 | 0.0 | 0.0 | 1 |
-
Hash.new(0).merge({ :Symbol => {"Bungalow" => :Bu, "Bi-level" => :Bi, "Split-level" => :Sp, "Two-story" => :Tw, "Condominium" => :Co}, :Bu => { :Bu => 1, :Sp => 0.4, :Tw => 0.8, :Bi => 0.65, :Co => 0.1 }, :Sp => { :Bu => 0.5, :Sp => 1.0, :Tw => 0.7, :Bi => 0.95, :Co => 0.2 }, :Tw => { :Bu => 0.0, :Sp => 0.6, :Tw => 1.0, :Bi => 0.5, :Co => 0.0 }, :Bi => { :Bu => 0.75,:Sp => 0.6, :Tw => 0.8, :Bi => 1.0, :Co => 0.0 }, :Co => { :Bu => 0.7, :Sp => 0.0, :Tw => 0.0, :Bi => 0.0, :Co => 1.0 } })
Class Method Summary collapse
-
.max_score ⇒ Object
Easy way to sum the max score (for testing).
Class Method Details
.max_score ⇒ Object
Easy way to sum the max score (for testing)
17 18 19 |
# File 'lib/weights.rb', line 17 def self.max_score WEIGHTS.inject(0) {|sum,n| sum + n[1]} end |