Skip to content

Commit

Permalink
changed assert_in_epsilon's to assert_in_delta's. replaced arcgis si2…
Browse files Browse the repository at this point in the history
… method with sample_variance and standardized the variables in local morans
  • Loading branch information
keithdoggett committed Mar 9, 2020
1 parent 4f7bfca commit 0900566
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 46 deletions.
18 changes: 11 additions & 7 deletions lib/spatial_stats/local/morans.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# frozen_string_literal: true

# https://pro.arcgis.com/en/pro-app/tool-reference/spatial-statistics/h-how-cluster-and-outlier-analysis-anselin-local-m.htm
# For now, instead of doing neighbor's variance (Si**2), I'm going to use
# the total sample variance. This is how GeoDa does it, but is different
# than arcgis. This shouldn't affect the expectation and variance of I.
module SpatialStats
module Local
class Morans
Expand All @@ -12,20 +15,21 @@ def initialize(scope, field, weights)
attr_accessor :scope, :field, :weights

def i
si2 = si2_calc
si2 = z.sample_variance
w = @weights.full
z_lag = SpatialStats::Utils::Lag.neighbor_sum(w, z)
z_lag = SpatialStats::Utils::Lag.neighbor_average(w, z)
vector = []

z.each_with_index do |z_val, idx|
sum_term = z_lag[idx]
vector << (z_val / si2[idx]) * sum_term
sum_term = z_lag[idx]
vector << (z_val / si2) * sum_term
end
vector
end

def variables
@variables ||= SpatialStats::Queries::Variables.query_field(@scope, @field)
@variables ||= SpatialStats::Queries::Variables
.query_field(@scope, @field).standardize
end

def zbar
Expand All @@ -41,7 +45,7 @@ def z
def si2_calc
n = @weights.keys.size
si2 = []

z.each_with_index do |_z_val, idx|
# add all zs**2 where j != i
numerator = 0
Expand All @@ -54,4 +58,4 @@ def si2_calc
end
end
end
end
end
2 changes: 1 addition & 1 deletion test/enumerable_ext_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_standardize
result = @array.standardize

result.each_with_index do |val, i|
assert_in_epsilon(val, expected[i], 0.0005)
assert_in_delta(val, expected[i], 0.0005)
end
end
end
6 changes: 3 additions & 3 deletions test/global/bivariate_morans_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_i
.new(@poly_scope, :value, :second_value, @weights)
i = moran.i
expected_i = -0.0878410461157883
assert_in_epsilon(expected_i, i, 1e-4)
assert_in_delta(expected_i, i, 1e-4)
end

def test_expectation
Expand All @@ -56,14 +56,14 @@ def test_variance
.new(@poly_scope, :value, :second_value, @weights)
var = moran.variance
expected = 0.0671875
assert_in_epsilon(expected, var, 0.0005)
assert_in_delta(expected, var, 0.0005)
end

def test_z_score
moran = SpatialStats::Global::BivariateMorans
.new(@poly_scope, :value, :second_value, @weights)
var = moran.z_score
expected = 0.14335711
assert_in_epsilon(expected, var, 0.0005)
assert_in_delta(expected, var, 0.0005)
end
end
4 changes: 2 additions & 2 deletions test/global/morans_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ def test_variance
moran = SpatialStats::Global::Morans.new(@poly_scope, :value, @weights)
var = moran.variance
expected = 0.0671875
assert_in_epsilon(expected, var, 0.0005)
assert_in_delta(expected, var, 0.005)
end

def test_z_score
moran = SpatialStats::Global::Morans.new(@poly_scope, :value, @weights)
var = moran.z_score
expected = -3.375
assert_in_epsilon(expected, var, 0.0005)
assert_in_delta(expected, var, 0.05)
end
end
68 changes: 35 additions & 33 deletions test/local/morans_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,32 @@ def setup
def test_variables
moran = SpatialStats::Local::Morans.new(@poly_scope, :value, @weights)
vars = moran.variables
assert_equal(@values, vars)
expected = @values.standardize
assert_equal(expected, vars)
end

def test_zbar
moran = SpatialStats::Local::Morans.new(@poly_scope, :value, @weights)
expected_ybar = 4.0 / 9
ybar = moran.zbar
assert_equal(expected_ybar, ybar)
expected_zbar = 0
zbar = moran.zbar
assert_in_delta(expected_zbar, zbar, 0.0005)
end

def test_z
moran = SpatialStats::Local::Morans.new(@poly_scope, :value, @weights)
z = moran.z
expected_z = [-4.0 / 9, 5.0 / 9, -4.0 / 9, 5.0 / 9,
-4.0 / 9, 5.0 / 9, -4.0 / 9, 5.0 / 9, -4.0 / 9]
expected_z = [-0.8432740427115678, 1.0540925533894598, -0.8432740427115678,
1.0540925533894598, -0.8432740427115678,
1.0540925533894598, -0.8432740427115678,
1.0540925533894598, -0.8432740427115678]
assert_equal(expected_z, z)
end

def test_i
moran = SpatialStats::Local::Morans.new(@poly_scope, :value, @weights)
i = moran.i
i.each do |i_i|
assert i_i < -1
assert i_i.negative?
end
end

Expand All @@ -55,36 +58,35 @@ def test_i_clustered
end

moran = SpatialStats::Local::Morans.new(@poly_scope, :value, @weights)
# these should all be slightly positive, at least.
# with the lowest values being the 0 corners

# these should all be slightly positive, or zero for the corners
# this is the same output as the test from GeoDa
i = moran.i
expected_i = [0.9411764705882355, 1.411764705882353, 0.9411764705882355,
1.5673736818237505e-16, 0.47058823529411775,
1.5673736818237505e-16, 1.1428571428571426,
3.428571428571428, 1.1428571428571426]
expected_i = [0.4444444444444444, 0.4444444444444444, 0.4444444444444444,
0.0, 0.11111111111111112, 0.0, 0.4444444444444444,
0.8888888888888888, 0.4444444444444444]

assert_equal(i, expected_i)
# i.positive?
end

def test_expectation
moran = SpatialStats::Global::Morans.new(@poly_scope, :value, @weights)
expectation = moran.expectation
expected = -1.0 / 8
assert_equal(expected, expectation)
end
# def test_expectation
# moran = SpatialStats::Global::Morans.new(@poly_scope, :value, @weights)
# expectation = moran.expectation
# expected = -1.0 / 8
# assert_equal(expected, expectation)
# end

def test_variance
moran = SpatialStats::Global::Morans.new(@poly_scope, :value, @weights)
var = moran.variance
expected = 0.0671875
assert_in_epsilon(expected, var, 0.0005)
end
# def test_variance
# moran = SpatialStats::Global::Morans.new(@poly_scope, :value, @weights)
# var = moran.variance
# expected = 0.0671875
# assert_in_delta(expected, var, 0.005)
# end

def test_z_score
moran = SpatialStats::Global::Morans.new(@poly_scope, :value, @weights)
var = moran.z_score
expected = -3.375
assert_in_epsilon(expected, var, 0.0005)
end
# def test_z_score
# moran = SpatialStats::Global::Morans.new(@poly_scope, :value, @weights)
# var = moran.z_score
# expected = -3.375
# assert_in_delta(expected, var, 0.05)
# end
end

0 comments on commit 0900566

Please sign in to comment.