kevintyll-ofac 1.1.10 → 1.1.11

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -58,9 +58,15 @@
58
58
  in the ofac_sdn database. This method ignores address and city and does not produce a score.
59
59
  Usage: Ofac.new({:name => 'Oscar Hernandez', :city => 'Clearwater', :address => '123 somewhere ln'}).db_hit?
60
60
 
61
-
62
61
  == 1.1.10 2009-07-28
63
62
 
64
63
  * 1 minor enhancement:
65
64
  * Modified the select in OfacSdn to use the city to pull records from the database. This is another compromise to improve performance,
66
- but still get a score. The db_hit? method is still faster, but this will still calculate a score for accuracy.
65
+ but still get a score. The db_hit? method is still faster, but this will still calculate a score for accuracy.
66
+
67
+ == 1.1.11 2009-07-29
68
+
69
+ * 1 minor enhancement:
70
+ * Removed the changes from 1.1.10. 1.1.10 produced a score of 0 when a higher score was more accurate.
71
+ Changed the scoring algorithm to not include partial matches on sounds like. This code has little impact on score, and
72
+ has a very high overhead on performance.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 1
3
- :patch: 10
3
+ :patch: 11
4
4
  :major: 1
@@ -147,20 +147,12 @@ class Ofac
147
147
  sql_alt_name_partial = name_array.collect {|partial_name| ["alternate_identity_name like ?", "%#{partial_name}%"]}
148
148
  conditions = sql_name_partial + sql_alt_name_partial
149
149
  conditions = conditions.transpose
150
- unless @identity[:city].blank?
151
- city_condition = ' and (city like ? or city is null)'
152
- end
153
- name_values = conditions.second
154
- conditions = conditions.first.join(' or ')
155
- conditions = "(#{conditions})"
156
- conditions += city_condition if city_condition
157
- condition_array = [conditions] + name_values
158
- condition_array += ["%#{@identity[:city]}%"] if city_condition
159
-
160
- possible_sdns = OfacSdn.find_all_by_sdn_type('individual',:select => 'name, alternate_identity_name, address, city', :conditions => condition_array)
150
+ conditions = [conditions.first.join(' or ')] + conditions.second
151
+
152
+ possible_sdns = OfacSdn.find_all_by_sdn_type('individual',:select => 'name, alternate_identity_name, address, city', :conditions => conditions)
161
153
  possible_sdns = possible_sdns.collect {|sdn|{:name => "#{sdn['name']}|#{sdn['alternate_identity_name']}", :city => sdn['city'], :address => sdn['address']}}
162
154
 
163
- match = OfacMatch.new({:name => {:weight => 60, :token => "#{name_array.join(' ')}"},
155
+ match = OfacMatch.new({:name => {:weight => 60, :token => "#{name_array.join(', ')}"},
164
156
  :address => {:weight => 10, :token => @identity[:address]},
165
157
  :city => {:weight => 30, :token => @identity[:city]}})
166
158
 
@@ -175,10 +167,10 @@ class Ofac
175
167
  def process_name
176
168
  #you can pass in a full name, or specify the first and last name
177
169
  if @identity[:name].kind_of?(Hash)
178
- name_array = [@identity[:name][:first_name],@identity[:name][:last_name]].compact
170
+ name_array = [@identity[:name][:last_name],@identity[:name][:first_name]].compact
179
171
  else
180
172
  partial_name = @identity[:name].gsub(/\W/,'|')
181
- name_array = partial_name.split('|')
173
+ name_array = partial_name.split('|').reverse
182
174
  end
183
175
  end
184
176
 
@@ -11,7 +11,7 @@ class OfacMatch
11
11
  # :zip => {:weight => 10, :token => '33759', :type => :number}})
12
12
  #
13
13
  # data hash keys:
14
- # * <tt>data[:weight]</tt> - value to apply to the score if there is a match (Default is 100/number of key in the record hash)
14
+ # * <tt>data[:weight]</tt> - value to apply to the score if there is a match (Default is 100/number of keys in the record hash)
15
15
  # * <tt>data[:token]</tt> - string to match
16
16
  # * <tt>data[:match]</tt> - set from records hash
17
17
  # * <tt>data[:score]</tt> - output field
@@ -79,12 +79,20 @@ class OfacMatch
79
79
  value = data[:token] == data[:match] ? 1 : 0
80
80
  else
81
81
  #first see if there is an exact match
82
- value = data[:token] == data[:match] ? 1 : 0
82
+ value = data[:match].split('|').include?(data[:token]) ? 1 : 0
83
83
 
84
84
  unless value > 0
85
85
  #do a sounds like with the data as given to see if we get a match
86
86
  #if match on sounds_like, only give .75 of the weight.
87
- value = data[:token].ofac_sounds_like(data[:match],false) ? 0.75 : 0
87
+ data[:match].split('|').each do |separate_value|
88
+ if data[:token].ofac_sounds_like(separate_value,false)
89
+ value = 0.75
90
+ break
91
+ else
92
+ value = 0
93
+ end
94
+ end
95
+
88
96
  end
89
97
 
90
98
  #if no match, then break the data down and see if we can find matches on the
@@ -105,16 +113,6 @@ class OfacMatch
105
113
  #first see if we get an exact match of the partial
106
114
  if success = match_array.include?(partial_token)
107
115
  value += partial_weight
108
- else
109
- #otherwise, see if the partial sounds like any part of the OFAC record
110
- match_array.each do |partial_match|
111
- if partial_match.ofac_sounds_like(partial_token,false)
112
- #give partial value for every part of token that is matched.
113
- value += partial_weight * 0.75
114
- success = true
115
- break
116
- end
117
- end
118
116
  end
119
117
  unless success
120
118
  #if this for :address or :city
data/test/ofac_test.rb CHANGED
@@ -73,20 +73,6 @@ class OfacTest < Test::Unit::TestCase
73
73
  assert_equal 90, Ofac.new({:name => 'Oscar Hernandez', :city => 'Clearwater'}).score
74
74
  end
75
75
 
76
- should "not find a match if the city does not match" do
77
- assert_equal 0, Ofac.new({:name => 'Oscar Hernandez', :city => 'Tampa'}).score
78
- #only name matches
79
- assert_equal 0, Ofac.new({:name => 'Oscar Hernandez', :city => 'no match', :address => 'no match'}).score
80
- end
81
-
82
- should "find a match if the city is not passed in" do
83
- assert_equal 60, Ofac.new({:name => 'Oscar Hernandez'}).score
84
- end
85
-
86
- should "find a match if the city is not in the database" do
87
- assert_equal 60, Ofac.new({:name => 'Raul AGUIAR'}).score
88
- end
89
-
90
76
  should "give a score of 100 if there is a name and city and address match" do
91
77
  assert_equal 100, Ofac.new({:name => 'Oscar Hernandez', :city => 'Clearwater', :address => '123 somewhere ln'}).score
92
78
  end
@@ -96,16 +82,15 @@ class OfacTest < Test::Unit::TestCase
96
82
  #32456 summer lane sounds like 32456 Somewhere ln so is adds 75% of the address weight to the score, or 8.
97
83
  assert_equal 98, Ofac.new({:name => 'Oscar Hernandez', :city => 'Clearwater', :address => '32456 summer lane'}).score
98
84
 
99
- #summer sounds like somewhere, and all numbers sound alike, so 2 of the 3 address elements match by sound.
100
- #Each element is worth 10\3 or 3.33. Exact matches add 2.33 each, and the sounds like adds 2.33 * .75 or 2.5
101
- #because sounds like matches only add 75% of it's weight.
102
- #2.5 + 2.5 = 5
103
- assert_equal 95, Ofac.new({:name => 'Oscar Hernandez', :city => 'Clearwater', :address => '12358 summer blvd'}).score
104
-
85
+ #Louis Eduardo Lopez Mendez sounds like Luis Eduardo Lopez Mendez:
86
+ #:name has a weight of 60, so a sounds like is worth 45
87
+ assert_equal 45, Ofac.new({:name => {:first_name => 'Louis Eduardo', :last_name => 'Lopez Mendez'}, :city => 'Las Vegas', :address => 'no match'}).score
88
+ end
105
89
 
106
- #Louis sounds like Luis, and Lopez is an exact match:
107
- #:name has a weight of 60, so each element is worth 30. A sounds like match is worth 30 * .75
108
- assert_equal 53, Ofac.new({:name => 'Louis Lopez', :city => 'Las Vegas', :address => 'no match'}).score
90
+ should 'not give partial scores if sounds like does not match the entire string' do
91
+ #summer sounds like somewhere, and all numbers sound alike, so 2 of the 3 address elements match by sound
92
+ #but the whole thing does not make a sounds like match so only city matches, subtract 1 for no address match
93
+ assert_equal 89, Ofac.new({:name => 'Oscar Hernandez', :city => 'Clearwater', :address => '12358 summer blvd'}).score
109
94
  end
110
95
 
111
96
  should "return an array of possible hits" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kevintyll-ofac
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.10
4
+ version: 1.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Tyll
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-28 00:00:00 -07:00
12
+ date: 2009-07-29 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15