Skip to content

Commit

Permalink
Merge pull request #454 from great-expectations/feature/distributiona…
Browse files Browse the repository at this point in the history
…l_tests

Feature/distributional tests
  • Loading branch information
jcampbell committed May 15, 2019
2 parents 556b9bc + 81955bf commit 7c66187
Show file tree
Hide file tree
Showing 14 changed files with 1,929 additions and 1,253 deletions.
18 changes: 14 additions & 4 deletions great_expectations/dataset/pandas_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -1241,9 +1241,13 @@ def expect_column_bootstrapped_ks_test_p_value_to_be_greater_than(self, column,
if not is_valid_continuous_partition_object(partition_object):
raise ValueError("Invalid continuous partition object.")

# TODO: consider changing this into a check that tail_weights does not exist exclusively, by moving this check into is_valid_continuous_partition_object
if (partition_object['bins'][0] == -np.inf) or (partition_object['bins'][-1] == np.inf):
raise ValueError("Partition endpoints must be finite.")

if "tail_weights" in partition_object and np.sum(partition_object["tail_weights"]) > 0:
raise ValueError("Partition cannot have tail weights -- endpoints must be finite.")

test_cdf = np.append(np.array([0]), np.cumsum(
partition_object['weights']))

Expand Down Expand Up @@ -1344,7 +1348,7 @@ def expect_column_kl_divergence_to_be_less_than(self, column, partition_object=N
raise ValueError(
"internal_weight_holdout must be between zero and one.")

if(tail_weight_holdout != 0 and "tail_weights" in partition_object):
if (tail_weight_holdout != 0 and "tail_weights" in partition_object):
raise ValueError(
"tail_weight_holdout must be 0 when using tail_weights in partition object")

Expand Down Expand Up @@ -1413,6 +1417,11 @@ def expect_column_kl_divergence_to_be_less_than(self, column, partition_object=N
observed_weights = np.array(hist)/len(column)

#Adjust expected_weights to account for tail_weight and internal_weight
if "tail_weights" in partition_object:
partition_tail_weight_holdout = np.sum(partition_object["tail_weights"])
else:
partition_tail_weight_holdout = 0

expected_weights = np.array(
partition_object['weights']) * (1 - tail_weight_holdout - internal_weight_holdout)

Expand Down Expand Up @@ -1479,9 +1488,10 @@ def expect_column_kl_divergence_to_be_less_than(self, column, partition_object=N
if "tail_weights" in partition_object:
tail_weights=partition_object["tail_weights"]
comb_expected_weights=np.concatenate(([tail_weights[0]],expected_weights,[tail_weights[1]])) #Tack on tail weights
expected_tail_weights=tail_weights #Tail weights are just tail_weights
comb_expected_weights=np.concatenate(([tail_weight_holdout / 2],expected_weights,[tail_weight_holdout / 2]))
expected_tail_weights=np.concatenate(([tail_weight_holdout / 2],[tail_weight_holdout / 2])) #Tail weights are just tail_weight holdout divided eaually to both tails
expected_tail_weights=np.array(tail_weights) #Tail weights are just tail_weights
else:
comb_expected_weights=np.concatenate(([tail_weight_holdout / 2],expected_weights,[tail_weight_holdout / 2]))
expected_tail_weights=np.concatenate(([tail_weight_holdout / 2],[tail_weight_holdout / 2])) #Tail weights are just tail_weight holdout divided eaually to both tails

comb_observed_weights=np.concatenate(([below_partition/len(column)],observed_weights, [above_partition/len(column)]))
observed_tail_weights=np.concatenate(([below_partition],[above_partition]))/len(column) #Tail weights are just the counts on either side of the partition
Expand Down
5 changes: 5 additions & 0 deletions great_expectations/dataset/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ def is_valid_continuous_partition_object(partition_object):
comb_weights=partition_object["tail_weights"]+partition_object["weights"]
else:
comb_weights=partition_object["weights"]

## TODO: Consider adding this check to migrate to the tail_weights structure of partition objects
# if (partition_object['bins'][0] == -np.inf) or (partition_object['bins'][-1] == np.inf):
# return False

# Expect one more bin edge than weight; all bin edges should be monotonically increasing; weights should sum to one
if (len(partition_object['bins']) == (len(partition_object['weights']) + 1)) and \
np.all(np.diff(partition_object['bins']) > 0) and \
Expand Down

This file was deleted.

9 changes: 9 additions & 0 deletions tests/test_dataset_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,15 @@ def test_is_valid_partition_object_fails_length(self):
def test_is_valid_partition_object_fails_weights(self):
self.assertFalse(ge.dataset.util.is_valid_partition_object(
{'bins': [0, 1, 2], 'weights': [0.5, 0.6]}))
# weights don't add
continuous_partition_object={"weights":[0.3,0.15,0.0,0.10,0.16],
"bins":[-3,-2,-1,0,1,2], "tail_weights":[0.15,0.15]}
self.assertFalse(ge.dataset.util.is_valid_continuous_partition_object(continuous_partition_object))

def test_is_valid_partition_object_only_one_tail_weight(self):
continuous_partition_object={"weights":[0.3,0.15,0.0,0.10,0.30],
"bins":[-3,-2,-1,0,1,2], "tail_weights":[0.15]}
self.assertFalse(ge.dataset.util.is_valid_continuous_partition_object(continuous_partition_object))

def test_is_valid_partition_object_fails_structure(self):
self.assertFalse(ge.dataset.util.is_valid_partition_object(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
{
"expectation_type" : "expect_column_chisquare_test_p_value_to_be_greater_than",
"datasets" : [{
"data" : {
"categorical_fixed": ["A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C"]
},
"tests" : [{
"title": "categorical_fixed partition object",
"exact_match_out": false,
"in": {
"column": "categorical_fixed",
"partition_object": {
"values": ["A", "B", "C"],
"weights": [0.54, 0.32, 0.14]
},
"p": 0.05
},
"out": {
"success": true,
"observed_value": 1
}
},
{
"title": "categorical_fixed_alternate partition object",
"exact_match_out": false,
"in": {
"column": "categorical_fixed",
"partition_object": {
"values": ["A", "B", "C"],
"weights": [0.3333333333333333, 0.3333333333333333, 0.3333333333333333]
},
"p": 0.05
},
"out": {
"success": false,
"observed_value": 5.1397782097623862e-53
}
},
{
"title": "categorical_fixed_alternate partition object; exact match",
"exact_match_out": true,
"in": {
"column": "categorical_fixed",
"partition_object": {
"values": ["A", "B", "C"],
"weights": [0.3333333333333333, 0.3333333333333333, 0.3333333333333333]
},
"p": 0.05,
"result_format": "SUMMARY"
},
"out": {
"success": false,
"result": {
"observed_value": 5.1397782097623862e-53,
"element_count": 1000,
"missing_count": 0,
"missing_percent": 0,
"details": {
"observed_partition": {
"values": ["A", "B", "C"],
"weights": [540, 320, 140]
},
"expected_partition": {
"values": ["A", "B", "C"],
"weights": [333.3333333333333, 333.3333333333333, 333.3333333333333]
}
}
}
}
}]
},
{
"data": {
"categorical_list": ["A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D"]
},
"tests": [
{
"title": "categorical_fixed_alternate; new categorical vals; no holdout",
"exact_match_out": false,
"in": {
"column": "categorical_list",
"partition_object": {
"values": ["A", "B", "C"],
"weights": [0.3333333333333333, 0.3333333333333333, 0.3333333333333333]
},
"p": 0.05
},
"out": {
"success": false
}
},
{
"title": "categorical_fixed_alternate; new categorical vals; holdout",
"exact_match_out": false,
"in": {
"column": "categorical_list",
"partition_object": {
"values": ["A", "B", "C"],
"weights": [0.3333333333333333, 0.3333333333333333, 0.3333333333333333]
},
"p": 0.05,
"tail_weight_holdout": 0.25
},
"out": {
"success": true
}
}
]
},
{
"data": {
"categorical_list": ["A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B"]
},
"tests": [
{
"title": "categorical_fixed; missing categorical vals; no holdout",
"exact_match_out": false,
"in": {
"column": "categorical_list",
"partition_object": {"weights": [0.54, 0.32, 0.14], "values": ["A", "B", "C"]},
"p": 0.05
},
"out": {
"success": false
}
},
{
"title": "continuous partition should fail",
"exact_match_out": false,
"in": {
"column": "categorical_list",
"partition_object": {
"bins": [ -3.2412673400690726, -2.987910238971794, -2.734553137874516, -2.481196036777238, -2.2278389356799595, -1.974481834582681, -1.7211247334854027, -1.4677676323881244, -1.214410531290846, -0.9610534301935676, -0.7076963290962892, -0.45433922799901083, -0.2009821269017329, 0.05237497419554549, 0.30573207529282387, 0.5590891763901022, 0.8124462774873806, 1.065803378584659, 1.3191604796819374, 1.5725175807792158, 1.8258746818764942, 2.0792317829737725, 2.332588884071051, 2.5859459851683293, 2.839303086265607, 3.092660187362885, 3.3460172884601636, 3.599374389557442, 3.852731490654721 ],
"weights": [ 0.001, 0.0, 0.003, 0.003, 0.011, 0.013, 0.029, 0.046, 0.053, 0.07, 0.103, 0.087, 0.093, 0.11, 0.089, 0.086, 0.064, 0.04, 0.038, 0.023, 0.017, 0.011, 0.006, 0.002, 0.001, 0.0, 0.0, 0.001 ]
},
"p": 0.05,
"catch_exceptions": true
},
"out": {
"traceback_substring": "ValueError"
}
}
]
}]
}
Loading

0 comments on commit 7c66187

Please sign in to comment.