Repository: great-expectations/great_expectations

Issue:
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`


Discussion:
Done inline during improve_partitions push.

Resolving patch:
diff --git a/great_expectations/rule_based_profiler/parameter_builder/numeric_metric_range_multi_batch_parameter_builder.py b/great_expectations/rule_based_profiler/parameter_builder/numeric_metric_range_multi_batch_parameter_builder.py
--- a/great_expectations/rule_based_profiler/parameter_builder/numeric_metric_range_multi_batch_parameter_builder.py
+++ b/great_expectations/rule_based_profiler/parameter_builder/numeric_metric_range_multi_batch_parameter_builder.py
@@ -1,9 +1,7 @@
-from dataclasses import make_dataclass
 from numbers import Number
-from typing import Any, Callable, Dict, List, Optional, Union
+from typing import Any, Dict, List, Optional, Union
 
 import numpy as np
-from scipy import special
 
 import great_expectations.exceptions as ge_exceptions
 from great_expectations import DataContext
@@ -15,29 +13,26 @@
 )
 from great_expectations.rule_based_profiler.util import (
     NP_EPSILON,
+    compute_bootstrap_quantiles,
+    compute_quantiles,
     get_parameter_value_and_validate_return_type,
-    import_scipy_stats_bootstrap_function,
 )
 from great_expectations.util import is_numeric
 from great_expectations.validator.validator import Validator
 
-bootstrap: Optional[Callable] = import_scipy_stats_bootstrap_function()
-
-NP_SQRT_2: np.float64 = np.sqrt(2.0)
-
 MAX_DECIMALS: int = 9
 
-ConfidenceInterval = make_dataclass("ConfidenceInterval", ["low", "high"])
+DEFAULT_BOOTSTRAP_NUM_RESAMPLES: int = 9999
 
 
 class NumericMetricRangeMultiBatchParameterBuilder(ParameterBuilder):
     """
     A Multi-Batch implementation for obtaining the range estimation bounds for a resolved (evaluated) numeric metric,
-    using domain_kwargs, value_kwargs, metric_name, and confidence_level (tolerance) as arguments.
+    using domain_kwargs, value_kwargs, metric_name, and false_positive_rate (tolerance) as arguments.
 
     This Multi-Batch ParameterBuilder is general in the sense that any metric that computes numbers can be accommodated.
     On the other hand, it is specific in the sense that the parameter names will always have the semantics of numeric
-    ranges, which will incorporate the requirements, imposed by the configured confidence_level tolerances.
+    ranges, which will incorporate the requirements, imposed by the configured false_positive_rate tolerances.
 
     The implementation supports two methods of estimating parameter values from data:
     * bootstrapped (default) -- a statistical technique (see "https://en.wikipedia.org/wiki/Bootstrapping_(statistics)")
@@ -64,14 +59,14 @@ def __init__(
         sampling_method: Optional[str] = "bootstrap",
         enforce_numeric_metric: Optional[Union[str, bool]] = True,
         replace_nan_with_zero: Optional[Union[str, bool]] = True,
-        confidence_level: Optional[Union[float, str]] = 9.5e-1,
-        num_bootstrap_samples: Optional[Union[int, str]] = None,
-        round_decimals: Optional[Union[int, str]] = None,
+        false_positive_rate: Optional[Union[str, float]] = 5.0e-2,
+        num_bootstrap_samples: Optional[Union[str, int]] = None,
+        round_decimals: Optional[Union[str, int]] = None,
         truncate_values: Optional[
-            Union[Dict[str, Union[Optional[int], Optional[float]]], str]
+            Union[str, Dict[str, Union[Optional[int], Optional[float]]]]
         ] = None,
         data_context: Optional[DataContext] = None,
-        batch_request: Optional[Union[dict, str]] = None,
+        batch_request: Optional[Union[str, dict]] = None,
     ):
         """
         Args:
@@ -85,7 +80,8 @@ def __init__(
             enforce_numeric_metric: used in MetricConfiguration to insure that metric computations return numeric values
             replace_nan_with_zero: if False, then if the computed metric gives NaN, then exception is raised; otherwise,
             if True (default), then if the computed metric gives NaN, then it is converted to the 0.0 (float) value.
-            confidence_level: user-configured fraction between 0 and 1
+            false_positive_rate: user-configured fraction between 0 and 1 expressing desired false positive rate for
+            identifying unexpected values as judged by the upper- and lower- quantiles of the observed metric data.
             num_bootstrap_samples: Applicable only for the "bootstrap" sampling method -- if omitted (default), then
             9999 is used (default in "https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.bootstrap.html").
             round_decimals: user-configured non-negative integer indicating the number of decimals of the
@@ -111,7 +107,7 @@ def __init__(
         self._enforce_numeric_metric = enforce_numeric_metric
         self._replace_nan_with_zero = replace_nan_with_zero
 
-        self._confidence_level = confidence_level
+        self._false_positive_rate = false_positive_rate
 
         self._num_bootstrap_samples = num_bootstrap_samples
 
@@ -129,7 +125,8 @@ def __init__(
         ):
             raise ge_exceptions.ProfilerExecutionError(
                 message=f"""Unrecognized truncate_values key(s) in {self.__class__.__name__}:
-"{str(truncate_values_keys - NumericMetricRangeMultiBatchParameterBuilder.RECOGNIZED_TRUNCATE_DISTRIBUTION_KEYS)}" detected.
+"{str(truncate_values_keys - NumericMetricRangeMultiBatchParameterBuilder.RECOGNIZED_TRUNCATE_DISTRIBUTION_KEYS)}" \
+detected.
 """
             )
         self._truncate_values = truncate_values
@@ -160,49 +157,13 @@ def _build_parameters(
          Steps 8 -- 10 are for the "oneshot" sampling method only (the "bootstrap" method achieves same automatically):
          8. Compute the mean and the standard deviation of the metric (aggregated over all the gathered Batch objects).
          9. Compute number of standard deviations (as floating point) needed (around the mean) to achieve the specified
-            confidence_level (note that confidence_level of 1.0 would result in infinite number of standard deviations,
-            hence it is "nudged" by small quantity "epsilon" below 1.0 if confidence_level of 1.0 appears as argument).
+            false_positive_rate (note that false_positive_rate of 0.0 would result in infinite number of standard deviations,
+            hence it is "nudged" by small quantity "epsilon" above 0.0 if false_positive_rate of 0.0 appears as argument).
             (Please refer to "https://en.wikipedia.org/wiki/Normal_distribution" and references therein for background.)
         10. Compute the "band" around the mean as the min_value and max_value (to be used in ExpectationConfiguration).
-        11. Return ConfidenceInterval([low, high]) for the desired metric as estimated by the specified sampling method.
+        11. Return [low, high] for the desired metric as estimated by the specified sampling method.
         12. Set up the arguments and call build_parameter_container() to store the parameter as part of "rule state".
         """
-        # Obtain sampling_method directive from rule state (i.e., variables and parameters); from instance variable otherwise.
-        sampling_method: str = get_parameter_value_and_validate_return_type(
-            domain=domain,
-            parameter_reference=self._sampling_method,
-            expected_return_type=str,
-            variables=variables,
-            parameters=parameters,
-        )
-        if not (
-            sampling_method
-            in NumericMetricRangeMultiBatchParameterBuilder.RECOGNIZED_SAMPLING_METHOD_NAMES
-        ):
-            raise ge_exceptions.ProfilerExecutionError(
-                message=f"""The directive "sampling_method" for {self.__class__.__name__} can be only one of 
-{NumericMetricRangeMultiBatchParameterBuilder.RECOGNIZED_SAMPLING_METHOD_NAMES} ("{sampling_method}" was detected).
-"""
-            )
-
-        # Obtain confidence_level from rule state (i.e., variables and parameters); from instance variable otherwise.
-        confidence_level: Union[
-            Any, str
-        ] = get_parameter_value_and_validate_return_type(
-            domain=domain,
-            parameter_reference=self._confidence_level,
-            expected_return_type=(int, float),
-            variables=variables,
-            parameters=parameters,
-        )
-        if not (0.0 <= confidence_level <= 1.0):
-            raise ge_exceptions.ProfilerExecutionError(
-                message=f"False-Positive Rate for {self.__class__.__name__} is outside of [0.0, 1.0] closed interval."
-            )
-
-        if np.isclose(confidence_level, 1.0):
-            confidence_level = confidence_level - NP_EPSILON
-
         validator: Validator = self.get_validator(
             domain=domain,
             variables=variables,
@@ -235,19 +196,50 @@ def _build_parameters(
         )
         metric_values: Union[
             np.ndarray, List[Union[Any, Number]]
-        ] = metric_computation_result["value"]
+        ] = metric_computation_result["metric_values"]
         details: Dict[str, Any] = metric_computation_result["details"]
 
-        truncate_values: Dict[
-            str, Union[Optional[int], Optional[float]]
-        ] = self._get_truncate_values_using_heuristics(
+        # Obtain sampling_method directive from rule state (i.e., variables and parameters); from instance variable otherwise.
+        sampling_method: str = get_parameter_value_and_validate_return_type(
+            domain=domain,
+            parameter_reference=self._sampling_method,
+            expected_return_type=str,
+            variables=variables,
+            parameters=parameters,
+        )
+        if not (
+            sampling_method
+            in NumericMetricRangeMultiBatchParameterBuilder.RECOGNIZED_SAMPLING_METHOD_NAMES
+        ):
+            raise ge_exceptions.ProfilerExecutionError(
+                message=f"""The directive "sampling_method" for {self.__class__.__name__} can be only one of
+{NumericMetricRangeMultiBatchParameterBuilder.RECOGNIZED_SAMPLING_METHOD_NAMES} ("{sampling_method}" was detected).
+"""
+            )
+
+        # Obtain false_positive_rate from rule state (i.e., variables and parameters); from instance variable otherwise.
+        false_positive_rate: Union[
+            Any, str
+        ] = get_parameter_value_and_validate_return_type(
+            domain=domain,
+            parameter_reference=self._false_positive_rate,
+            expected_return_type=float,
+            variables=variables,
+            parameters=parameters,
+        )
+        if not (0.0 <= false_positive_rate <= 1.0):
+            raise ge_exceptions.ProfilerExecutionError(
+                message=f"The confidence level for {self.__class__.__name__} is outside of [0.0, 1.0] closed interval."
+            )
+
+        truncate_values: Dict[str, Number] = self._get_truncate_values_using_heuristics(
             metric_values=metric_values,
             domain=domain,
             variables=variables,
             parameters=parameters,
         )
-        lower_bound: Optional[Union[int, float]] = truncate_values.get("lower_bound")
-        upper_bound: Optional[Union[int, float]] = truncate_values.get("upper_bound")
+        lower_bound: Optional[float] = truncate_values.get("lower_bound")
+        upper_bound: Optional[float] = truncate_values.get("upper_bound")
 
         round_decimals: int = self._get_round_decimals_using_heuristics(
             metric_values=metric_values,
@@ -258,27 +250,35 @@ def _build_parameters(
 
         metric_values = np.array(metric_values, dtype=np.float64)
 
-        confidence_interval: ConfidenceInterval
-        if sampling_method == "bootstrap":
-            confidence_interval = self._get_bootstrap_confidence_interval(
+        lower_quantile: Union[Number, float]
+        upper_quantile: Union[Number, float]
+
+        if np.all(np.isclose(metric_values, metric_values[0])):
+            # Computation is unnecessary if distribution is degenerate.
+            lower_quantile = upper_quantile = metric_values[0]
+        elif sampling_method == "bootstrap":
+            lower_quantile, upper_quantile = self._get_bootstrap_estimate(
                 metric_values=metric_values,
-                confidence_level=confidence_level,
+                false_positive_rate=false_positive_rate,
                 domain=domain,
                 variables=variables,
                 parameters=parameters,
             )
         else:
-            confidence_interval = self._get_oneshot_confidence_interval(
+            lower_quantile, upper_quantile = compute_quantiles(
                 metric_values=metric_values,
-                confidence_level=confidence_level,
+                false_positive_rate=false_positive_rate,
             )
 
+        min_value: Union[Number, float]
+        max_value: Union[Number, float]
+
         if round_decimals == 0:
-            min_value = round(confidence_interval.low)
-            max_value = round(confidence_interval.high)
+            min_value = round(float(lower_quantile))
+            max_value = round(float(upper_quantile))
         else:
-            min_value = round(confidence_interval.low, round_decimals)
-            max_value = round(confidence_interval.high, round_decimals)
+            min_value = round(float(lower_quantile), round_decimals)
+            max_value = round(float(upper_quantile), round_decimals)
 
         if lower_bound is not None:
             min_value = max(min_value, lower_bound)
@@ -299,18 +299,15 @@ def _build_parameters(
             parameter_container=parameter_container, parameter_values=parameter_values
         )
 
-    def _get_bootstrap_confidence_interval(
+    def _get_bootstrap_estimate(
         self,
-        metric_values: Union[
-            np.ndarray,
-            List[Union[int, np.int32, np.int64, float, np.float32, np.float64]],
-        ],
-        confidence_level: np.float64,
+        metric_values: np.ndarray,
+        false_positive_rate: np.float64,
         domain: Domain,
         *,
         variables: Optional[ParameterContainer] = None,
         parameters: Optional[Dict[str, ParameterContainer]] = None,
-    ):
+    ) -> tuple:
         # Obtain num_bootstrap_samples override from rule state (i.e., variables and parameters); from instance variable otherwise.
         num_bootstrap_samples: Optional[
             int
@@ -321,109 +318,21 @@ def _get_bootstrap_confidence_interval(
             variables=variables,
             parameters=parameters,
         )
-
-        rng: np.random.Generator = np.random.default_rng()
-        bootstrap_samples: tuple = (
-            metric_values,
-        )  # bootstrap samples must be in a sequence
-
-        # noinspection PyPep8Naming
-        BootstrapResult = make_dataclass(
-            "BootstrapResult", ["confidence_interval", "standard_error"]
-        )
-
-        bootstrap_result: BootstrapResult
+        n_resamples: int
         if num_bootstrap_samples is None:
-            bootstrap_result = bootstrap(
-                bootstrap_samples,
-                np.mean,
-                vectorized=False,
-                confidence_level=confidence_level,
-                random_state=rng,
-                method="basic",
-            )
+            n_resamples = DEFAULT_BOOTSTRAP_NUM_RESAMPLES
         else:
-            bootstrap_result = bootstrap(
-                bootstrap_samples,
-                np.mean,
-                vectorized=False,
-                confidence_level=confidence_level,
-                n_resamples=num_bootstrap_samples,
-                random_state=rng,
-                method="basic",
-            )
-
-        confidence_interval: ConfidenceInterval = bootstrap_result.confidence_interval
-
-        confidence_interval_low: np.float64 = confidence_interval.low
-        confidence_interval_high: np.float64 = confidence_interval.high
-
-        std: Union[np.ndarray, np.float64] = bootstrap_result.standard_error
+            n_resamples = num_bootstrap_samples
 
-        stds_multiplier: np.float64 = NP_SQRT_2 * special.erfinv(confidence_level)
-        margin_of_error: np.float64 = stds_multiplier * std
-
-        confidence_interval_low -= margin_of_error
-        confidence_interval_high += margin_of_error
-
-        return ConfidenceInterval(
-            low=confidence_interval_low, high=confidence_interval_high
-        )
-
-    def _get_oneshot_confidence_interval(
-        self,
-        metric_values: Union[
-            np.ndarray,
-            List[Union[int, np.int32, np.int64, float, np.float32, np.float64]],
-        ],
-        confidence_level: np.float64,
-    ):
-        mean: Union[np.ndarray, np.float64] = np.mean(metric_values)
-        std: Union[np.ndarray, np.float64] = self._standard_error(samples=metric_values)
-
-        stds_multiplier: np.float64 = NP_SQRT_2 * special.erfinv(confidence_level)
-        margin_of_error: np.float64 = stds_multiplier * std
-
-        confidence_interval_low: np.float64 = mean - margin_of_error
-        confidence_interval_high: np.float64 = mean + margin_of_error
-
-        return ConfidenceInterval(
-            low=confidence_interval_low, high=confidence_interval_high
-        )
-
-    def _standard_error(
-        self,
-        samples: np.ndarray,
-    ) -> np.float64:
-        standard_variance: np.float64 = self._standard_variance_unbiased(
-            samples=samples
+        return compute_bootstrap_quantiles(
+            metric_values=metric_values,
+            false_positive_rate=false_positive_rate,
+            n_resamples=n_resamples,
         )
 
-        if np.isclose(standard_variance, 0.0):
-            standard_variance = np.float64(0.0)
-
-        return np.sqrt(standard_variance)
-
-    def _standard_variance_unbiased(
-        self,
-        samples: np.ndarray,
-    ) -> np.float64:
-        num_samples: int = samples.size
-        if num_samples < 2:
-            raise ValueError(
-                f"""Number of samples in {self.__class__.__name__} must be an integer greater than 1 \
-(the value {num_samples} was encountered).
-"""
-            )
-
-        return num_samples * (np.var(samples) + NP_EPSILON) / (num_samples - 1)
-
     def _get_truncate_values_using_heuristics(
         self,
-        metric_values: Union[
-            np.ndarray,
-            List[Union[int, np.int32, np.int64, float, np.float32, np.float64]],
-        ],
+        metric_values: Union[np.ndarray, List[Number]],
         domain: Domain,
         *,
         variables: Optional[ParameterContainer] = None,
@@ -431,7 +340,7 @@ def _get_truncate_values_using_heuristics(
     ) -> Dict[str, Union[Optional[int], Optional[float]]]:
         # Obtain truncate_values directive from rule state (i.e., variables and parameters); from instance variable otherwise.
         truncate_values: Dict[
-            str, Union[Optional[int], Optional[float]]
+            str, Optional[Number]
         ] = get_parameter_value_and_validate_return_type(
             domain=domain,
             parameter_reference=self._truncate_values,
@@ -455,9 +364,9 @@ def _get_truncate_values_using_heuristics(
 """
             )
 
-        lower_bound: Optional[Union[int, float]] = truncate_values.get("lower_bound")
-        upper_bound: Optional[Union[int, float]] = truncate_values.get("upper_bound")
-        metric_value: Union[int, np.int32, np.int64, float, np.float32, np.float64]
+        lower_bound: Optional[Number] = truncate_values.get("lower_bound")
+        upper_bound: Optional[Number] = truncate_values.get("upper_bound")
+        metric_value: Union[Number, np.float64]
         if lower_bound is None and all(
             [metric_value > NP_EPSILON for metric_value in metric_values]
         ):
@@ -474,10 +383,7 @@ def _get_truncate_values_using_heuristics(
 
     def _get_round_decimals_using_heuristics(
         self,
-        metric_values: Union[
-            np.ndarray,
-            List[Union[int, np.int32, np.int64, float, np.float32, np.float64]],
-        ],
+        metric_values: Union[np.ndarray, List[Number]],
         domain: Domain,
         *,
         variables: Optional[ParameterContainer] = None,
@@ -501,7 +407,7 @@ def _get_round_decimals_using_heuristics(
 positive integer, or must be omitted (or set to None).
 """
             )
-        metric_value: Union[int, np.int32, np.int64, float, np.float32, np.float64]
+        metric_value: Number
         if all(
             [
                 np.issubdtype(type(metric_value), np.integer)
diff --git a/great_expectations/rule_based_profiler/parameter_builder/parameter_builder.py b/great_expectations/rule_based_profiler/parameter_builder/parameter_builder.py
--- a/great_expectations/rule_based_profiler/parameter_builder/parameter_builder.py
+++ b/great_expectations/rule_based_profiler/parameter_builder/parameter_builder.py
@@ -300,7 +300,7 @@ def get_metrics(
             metric_values.append(metric_value)
 
         return {
-            "value": metric_values,
+            "metric_values": metric_values,
             "details": {
                 "metric_configuration": {
                     "metric_name": metric_name,
@@ -308,7 +308,7 @@ def get_metrics(
                     "metric_value_kwargs": metric_value_kwargs,
                     "metric_dependencies": None,
                 },
-                "num_batches": len(batch_ids),
+                "num_batches": len(metric_values),
             },
         }
 
diff --git a/great_expectations/rule_based_profiler/util.py b/great_expectations/rule_based_profiler/util.py
--- a/great_expectations/rule_based_profiler/util.py
+++ b/great_expectations/rule_based_profiler/util.py
@@ -1,7 +1,7 @@
 import copy
 import uuid
-from types import ModuleType
-from typing import Any, Callable, Dict, List, Optional, Union
+from numbers import Number
+from typing import Any, Dict, List, Optional, Union
 
 import numpy as np
 
@@ -13,10 +13,9 @@
     ParameterContainer,
     get_parameter_value_by_fully_qualified_parameter_name,
 )
-from great_expectations.util import import_library_module, is_library_loadable
 from great_expectations.validator.validator import Validator
 
-NP_EPSILON: np.float64 = np.finfo(float).eps
+NP_EPSILON: Union[Number, np.float64] = np.finfo(float).eps
 
 
 def get_validator(
@@ -195,21 +194,47 @@ def get_parameter_value(
     return parameter_reference
 
 
-def import_scipy_stats_bootstrap_function() -> Optional[Callable]:
-    if not is_library_loadable(library_name="scipy.stats"):
-        return None
-
-    scipy_stats: Optional[ModuleType] = import_library_module(module_name="scipy.stats")
-    bootstrap: Optional[Callable] = None
-    if (
-        scipy_stats
-        and hasattr(scipy_stats, "bootstrap")
-        and isinstance(scipy_stats.bootstrap, Callable)
-    ):
-        bootstrap = scipy_stats.bootstrap
-
-    return bootstrap
+def compute_quantiles(
+    metric_values: Union[np.ndarray, List[Number]],
+    false_positive_rate: np.float64,
+) -> tuple:
+    lower_quantile = np.quantile(
+        metric_values,
+        q=(false_positive_rate / 2),
+        axis=0,
+        interpolation="linear",  # can be omitted ("linear" is default)
+    )
+    upper_quantile = np.quantile(
+        metric_values,
+        q=1.0 - (false_positive_rate / 2),
+        axis=0,
+        interpolation="linear",  # can be omitted ("linear" is default)
+    )
+    return lower_quantile, upper_quantile
 
 
-def is_scipy_stats_bootstrap_loadable() -> bool:
-    return import_scipy_stats_bootstrap_function() is not None
+def compute_bootstrap_quantiles(
+    metric_values: np.ndarray,
+    false_positive_rate: np.float64,
+    n_resamples: int,
+) -> tuple:
+    bootstraps: np.ndarray = np.random.choice(
+        metric_values, size=(n_resamples, metric_values.size)
+    )
+    lower_quantile = np.mean(
+        np.quantile(
+            bootstraps,
+            q=false_positive_rate / 2,
+            axis=1,
+            interpolation="linear",  # can be omitted ("linear" is default)
+        )
+    )
+    upper_quantile = np.mean(
+        np.quantile(
+            bootstraps,
+            q=1.0 - (false_positive_rate / 2),
+            axis=1,
+            interpolation="linear",  # can be omitted ("linear" is default)
+        )
+    )
+    return lower_quantile, upper_quantile


Test patch:
diff --git a/tests/rule_based_profiler/bobby_user_workflow_fixture.py b/tests/rule_based_profiler/bobby_user_workflow_fixture.py
--- a/tests/rule_based_profiler/bobby_user_workflow_fixture.py
+++ b/tests/rule_based_profiler/bobby_user_workflow_fixture.py
@@ -29,7 +29,7 @@ def bobby_columnar_table_multi_batch():
     ] = [
         ExpectationConfiguration(
             **{
-                "kwargs": {"min_value": 6179, "max_value": 9821, "mostly": 1.0},
+                "kwargs": {"min_value": 7505, "max_value": 8495},
                 "expectation_type": "expect_table_row_count_to_be_between",
                 "meta": {
                     "profiler_details": {
@@ -49,661 +49,601 @@ def bobby_columnar_table_multi_batch():
     ] = [
         ExpectationConfiguration(
             **{
-                "kwargs": {
-                    "column": "VendorID",
-                    "min_value": 1,
-                    "max_value": 1,
-                    "mostly": 1.0,
-                },
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "VendorID",
-                            },
+                            "domain_kwargs": {"column": "VendorID"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "VendorID",
-                    "min_value": 4,
-                    "max_value": 4,
+                    "min_value": 1,
+                    "max_value": 1,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "VendorID",
-                            },
+                            "domain_kwargs": {"column": "VendorID"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "passenger_count",
-                    "min_value": -1,
-                    "max_value": 2,
+                    "column": "VendorID",
+                    "min_value": 4,
+                    "max_value": 4,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "passenger_count",
-                            },
+                            "domain_kwargs": {"column": "passenger_count"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "passenger_count",
-                    "min_value": 6,
-                    "max_value": 6,
+                    "min_value": 0,
+                    "max_value": 1,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "passenger_count",
-                            },
+                            "domain_kwargs": {"column": "passenger_count"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "trip_distance",
-                    "min_value": 0.0,
-                    "max_value": 0.0,
+                    "column": "passenger_count",
+                    "min_value": 6,
+                    "max_value": 6,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "trip_distance",
-                            },
+                            "domain_kwargs": {"column": "trip_distance"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "trip_distance",
-                    "min_value": 10.52,
-                    "max_value": 84.95,
+                    "min_value": 0.0,
+                    "max_value": 0.0,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "trip_distance",
-                            },
+                            "domain_kwargs": {"column": "trip_distance"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "RatecodeID",
-                    "min_value": 1,
-                    "max_value": 1,
+                    "column": "trip_distance",
+                    "min_value": 37.62,
+                    "max_value": 57.85,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "RatecodeID",
-                            },
+                            "domain_kwargs": {"column": "RatecodeID"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "RatecodeID",
-                    "min_value": 4,
-                    "max_value": 7,
+                    "min_value": 1,
+                    "max_value": 1,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "RatecodeID",
-                            },
+                            "domain_kwargs": {"column": "RatecodeID"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "PULocationID",
-                    "min_value": 1,
-                    "max_value": 1,
+                    "column": "RatecodeID",
+                    "min_value": 5,
+                    "max_value": 6,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "PULocationID",
-                            },
+                            "domain_kwargs": {"column": "PULocationID"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "PULocationID",
-                    "min_value": 265,
-                    "max_value": 265,
+                    "min_value": 1,
+                    "max_value": 1,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "PULocationID",
-                            },
+                            "domain_kwargs": {"column": "PULocationID"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "DOLocationID",
-                    "min_value": 1,
-                    "max_value": 1,
+                    "column": "PULocationID",
+                    "min_value": 265,
+                    "max_value": 265,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "DOLocationID",
-                            },
+                            "domain_kwargs": {"column": "DOLocationID"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "DOLocationID",
-                    "min_value": 265,
-                    "max_value": 265,
+                    "min_value": 1,
+                    "max_value": 1,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "DOLocationID",
-                            },
+                            "domain_kwargs": {"column": "DOLocationID"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "payment_type",
-                    "min_value": 1,
-                    "max_value": 1,
+                    "column": "DOLocationID",
+                    "min_value": 265,
+                    "max_value": 265,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "payment_type",
-                            },
+                            "domain_kwargs": {"column": "payment_type"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "payment_type",
-                    "min_value": 4,
-                    "max_value": 4,
+                    "min_value": 1,
+                    "max_value": 1,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "payment_type",
-                            },
+                            "domain_kwargs": {"column": "payment_type"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "fare_amount",
-                    "min_value": -92.96,
-                    "max_value": 0.0,
+                    "column": "payment_type",
+                    "min_value": 4,
+                    "max_value": 4,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "fare_amount",
-                            },
+                            "domain_kwargs": {"column": "fare_amount"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "fare_amount",
-                    "min_value": 0.0,
-                    "max_value": 6689.35,
+                    "min_value": -51.84,
+                    "max_value": -21.16,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "fare_amount",
-                            },
+                            "domain_kwargs": {"column": "fare_amount"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "extra",
-                    "min_value": -83.9,
-                    "max_value": 0.0,
+                    "column": "fare_amount",
+                    "min_value": 228.94,
+                    "max_value": 2990.05,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "extra",
-                            },
+                            "domain_kwargs": {"column": "extra"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "extra",
-                    "min_value": 1.2,
-                    "max_value": 10.3,
+                    "min_value": -36.53,
+                    "max_value": -1.18,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "extra",
-                            },
+                            "domain_kwargs": {"column": "extra"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "mta_tax",
-                    "min_value": -0.5,
-                    "max_value": -0.5,
+                    "column": "extra",
+                    "min_value": 4.51,
+                    "max_value": 6.99,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "mta_tax",
-                            },
+                            "domain_kwargs": {"column": "mta_tax"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "mta_tax",
-                    "min_value": 0.0,
-                    "max_value": 86.41,
+                    "min_value": -0.5,
+                    "max_value": -0.5,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "mta_tax",
-                            },
+                            "domain_kwargs": {"column": "mta_tax"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "tip_amount",
-                    "min_value": 0.0,
-                    "max_value": 0.0,
+                    "column": "mta_tax",
+                    "min_value": 0.69,
+                    "max_value": 37.32,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "tip_amount",
-                            },
+                            "domain_kwargs": {"column": "tip_amount"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "tip_amount",
-                    "min_value": 9.3,
-                    "max_value": 112.4,
+                    "min_value": 0.0,
+                    "max_value": 0.0,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "tip_amount",
-                            },
+                            "domain_kwargs": {"column": "tip_amount"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "tolls_amount",
-                    "min_value": 0.0,
-                    "max_value": 0.0,
+                    "column": "tip_amount",
+                    "min_value": 46.84,
+                    "max_value": 74.86,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "tolls_amount",
-                            },
+                            "domain_kwargs": {"column": "tolls_amount"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "tolls_amount",
                     "min_value": 0.0,
-                    "max_value": 1129.07,
+                    "max_value": 0.0,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "tolls_amount",
-                            },
+                            "domain_kwargs": {"column": "tolls_amount"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "improvement_surcharge",
-                    "min_value": -0.3,
-                    "max_value": -0.3,
+                    "column": "tolls_amount",
+                    "min_value": 26.4,
+                    "max_value": 497.67,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "improvement_surcharge",
-                            },
+                            "domain_kwargs": {"column": "improvement_surcharge"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "improvement_surcharge",
-                    "min_value": 0.3,
-                    "max_value": 0.3,
+                    "min_value": -0.3,
+                    "max_value": -0.3,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "improvement_surcharge",
-                            },
+                            "domain_kwargs": {"column": "improvement_surcharge"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "total_amount",
-                    "min_value": -90.46,
-                    "max_value": 0.0,
+                    "column": "improvement_surcharge",
+                    "min_value": 0.3,
+                    "max_value": 0.3,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "total_amount",
-                            },
+                            "domain_kwargs": {"column": "total_amount"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "total_amount",
-                    "min_value": 0.0,
-                    "max_value": 6264.59,
+                    "min_value": -52.66,
+                    "max_value": -24.44,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "total_amount",
-                            },
+                            "domain_kwargs": {"column": "total_amount"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
-                    "column": "congestion_surcharge",
-                    "min_value": -5.8,
-                    "max_value": 3.3,
+                    "column": "total_amount",
+                    "min_value": 550.18,
+                    "max_value": 2992.47,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_min_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.min",
-                            "domain_kwargs": {
-                                "column": "congestion_surcharge",
-                            },
+                            "domain_kwargs": {"column": "congestion_surcharge"},
                         },
                         "num_batches": 2,
-                    },
+                    }
                 },
-            }
-        ),
-        ExpectationConfiguration(
-            **{
                 "kwargs": {
                     "column": "congestion_surcharge",
-                    "min_value": -3.3,
-                    "max_value": 5.8,
+                    "min_value": -2.49,
+                    "max_value": -0.01,
                     "mostly": 1.0,
                 },
+            },
+        ),
+        ExpectationConfiguration(
+            **{
                 "expectation_type": "expect_column_max_to_be_between",
                 "meta": {
                     "profiler_details": {
                         "metric_configuration": {
                             "metric_name": "column.max",
-                            "domain_kwargs": {
-                                "column": "congestion_surcharge",
-                            },
+                            "domain_kwargs": {"column": "congestion_surcharge"},
                         },
                         "num_batches": 2,
-                    },
+                    }
+                },
+                "kwargs": {
+                    "column": "congestion_surcharge",
+                    "min_value": 0.01,
+                    "max_value": 2.49,
+                    "mostly": 1.0,
                 },
             },
         ),
diff --git a/tests/rule_based_profiler/bobby_user_workflow_verbose_profiler_config.yml b/tests/rule_based_profiler/bobby_user_workflow_verbose_profiler_config.yml
--- a/tests/rule_based_profiler/bobby_user_workflow_verbose_profiler_config.yml
+++ b/tests/rule_based_profiler/bobby_user_workflow_verbose_profiler_config.yml
@@ -9,7 +9,7 @@ variables:
     data_connector_query:
       index: ":-1"
   sampling_method: oneshot  # Choices: bootstrap (default) or oneshot (inaccurate -- should be used only for testing).
-  confidence_level: 9.9e-1
+  false_positive_rate: 1.0e-2
   mostly: 1.0
 
 rules:
@@ -22,7 +22,7 @@ rules:
         batch_request: $variables.jan_feb_2019_monthly_trip_data_batch_request
         metric_name: table.row_count
         sampling_method: $variables.sampling_method
-        confidence_level: $variables.confidence_level
+        false_positive_rate: $variables.false_positive_rate
         round_decimals: 0
         truncate_values:
           lower_bound: 0
@@ -32,7 +32,6 @@ rules:
         module_name: great_expectations.rule_based_profiler.expectation_configuration_builder
         min_value: $parameter.row_count_range.value.min_value
         max_value: $parameter.row_count_range.value.max_value
-        mostly: $variables.mostly
         meta:
           profiler_details: $parameter.row_count_range.details
   column_ranges_rule:
@@ -54,7 +53,7 @@ rules:
         metric_name: column.min
         metric_domain_kwargs: $domain.domain_kwargs
         sampling_method: $variables.sampling_method
-        confidence_level: $variables.confidence_level
+        false_positive_rate: $variables.false_positive_rate
         round_decimals: 2
       - parameter_name: max_range
         class_name: NumericMetricRangeMultiBatchParameterBuilder
@@ -62,7 +61,7 @@ rules:
         metric_name: column.max
         metric_domain_kwargs: $domain.domain_kwargs
         sampling_method: $variables.sampling_method
-        confidence_level: $variables.confidence_level
+        false_positive_rate: $variables.false_positive_rate
         round_decimals: 2
     expectation_configuration_builders:
       - expectation_type: expect_column_min_to_be_between
diff --git a/tests/rule_based_profiler/bobster_user_workflow_verbose_profiler_config.yml b/tests/rule_based_profiler/bobster_user_workflow_verbose_profiler_config.yml
--- a/tests/rule_based_profiler/bobster_user_workflow_verbose_profiler_config.yml
+++ b/tests/rule_based_profiler/bobster_user_workflow_verbose_profiler_config.yml
@@ -8,7 +8,7 @@ variables:
     data_asset_name: my_reports
     data_connector_query:
       index: ":-1"
-  confidence_level: 9.5e-1
+  false_positive_rate: 5.0e-2
 
 rules:
   row_count_range_rule:
@@ -19,7 +19,7 @@ rules:
         class_name: NumericMetricRangeMultiBatchParameterBuilder
         batch_request: $variables.jan_2018_thru_nov_2020_monthly_trip_data_batch_request
         metric_name: table.row_count
-        confidence_level: $variables.confidence_level
+        false_positive_rate: $variables.false_positive_rate
         round_decimals: 0
         truncate_values:
           lower_bound: 0
diff --git a/tests/rule_based_profiler/parameter_builder/test_parameter_computations.py b/tests/rule_based_profiler/parameter_builder/test_parameter_computations.py
--- a/tests/rule_based_profiler/parameter_builder/test_parameter_computations.py
+++ b/tests/rule_based_profiler/parameter_builder/test_parameter_computations.py
@@ -1,24 +1,55 @@
+from typing import Dict, Optional, Union
+
 import numpy as np
-from scipy import special
+import pandas as pd
+import scipy.stats as stats
 
 from great_expectations.rule_based_profiler.parameter_builder.numeric_metric_range_multi_batch_parameter_builder import (
-    NP_SQRT_2,
+    DEFAULT_BOOTSTRAP_NUM_RESAMPLES,
 )
+from great_expectations.rule_based_profiler.util import compute_bootstrap_quantiles
 
 
-# Please refer to "https://en.wikipedia.org/wiki/Normal_distribution" and references therein for background.
-def test_standard_deviation_band_around_mean_rule():
-    confidence_level: float
-    stds_multiplier: float
-
-    confidence_level = 0.0
-    stds_multiplier = NP_SQRT_2 * special.erfinv(confidence_level)
-    assert np.isclose(stds_multiplier, 0.0)
+def _generate_distribution_samples(size: Optional[int] = 36) -> pd.DataFrame:
+    data: Dict[str, np.ndarray] = {
+        "normal": np.around(stats.norm.rvs(5000, 1000, size=size)),
+        "uniform": np.around(stats.uniform.rvs(4000, 6000, size=size)),
+        "bimodal": np.around(
+            np.concatenate(
+                [
+                    stats.norm.rvs(4000, 500, size=size // 2),
+                    stats.norm.rvs(6000, 500, size=size // 2),
+                ]
+            )
+        ),
+        "exponential": np.around(
+            stats.gamma.rvs(a=1.5, loc=5000, scale=1000, size=size)
+        ),
+    }
+    return pd.DataFrame(data)
 
-    confidence_level = 9.54499736104e-1
-    stds_multiplier = NP_SQRT_2 * special.erfinv(confidence_level)
-    assert np.isclose(stds_multiplier, 2.0)
 
-    confidence_level = 9.97300203937e-1
-    stds_multiplier = NP_SQRT_2 * special.erfinv(confidence_level)
-    assert np.isclose(stds_multiplier, 3.0)
+def test_custom_bootstrap_efficacy():
+    df: pd.DataFrame = _generate_distribution_samples(size=1000)
+    false_positive_rate: np.float64 = np.float64(0.01)
+    columns: pd.Index = df.columns
+    column: str
+    lower_quantile: np.float64
+    upper_quantile: np.float64
+    actual_false_positive_rates: Dict[str, Union[float, np.float64]] = {}
+    for column in columns:
+        (lower_quantile, upper_quantile,) = compute_bootstrap_quantiles(
+            metric_values=df[column],
+            false_positive_rate=false_positive_rate,
+            n_resamples=DEFAULT_BOOTSTRAP_NUM_RESAMPLES,
+        )
+        actual_false_positive_rates[column] = (
+            1.0
+            - np.sum(df[column].between(lower_quantile, upper_quantile)) / df.shape[0]
+        )
+        # Actual false-positives must be within 1% of desired (configured) false_positive_rate parameter value.
+        assert (
+            false_positive_rate - 0.01
+            <= actual_false_positive_rates[column]
+            <= false_positive_rate + 0.01
+        )
diff --git a/tests/rule_based_profiler/test_profiler_user_workflows.py b/tests/rule_based_profiler/test_profiler_user_workflows.py
--- a/tests/rule_based_profiler/test_profiler_user_workflows.py
+++ b/tests/rule_based_profiler/test_profiler_user_workflows.py
@@ -1,9 +1,11 @@
 import datetime
 from typing import Any, Dict, List, cast
 
+import numpy as np
 import pandas as pd
 import pytest
 from freezegun import freeze_time
+from packaging import version
 from ruamel.yaml import YAML
 
 from great_expectations import DataContext
@@ -11,9 +13,6 @@
 from great_expectations.core.batch import BatchRequest
 from great_expectations.datasource import DataConnector, Datasource
 from great_expectations.rule_based_profiler.profiler import Profiler
-from great_expectations.rule_based_profiler.util import (
-    is_scipy_stats_bootstrap_loadable,
-)
 from great_expectations.validator.validation_graph import MetricConfiguration
 from great_expectations.validator.validator import Validator
 
@@ -171,6 +170,10 @@ def test_bobby_columnar_table_multi_batch_batches_are_accessible(
     assert month == 3
 
 
+@pytest.mark.skipif(
+    version.parse(np.version.version) < version.parse("1.21.0"),
+    reason="requires numpy version 1.21.0 or newer",
+)
 @freeze_time("09/26/2019 13:42:41")
 def test_bobby_profiler_user_workflow_multi_batch_row_count_range_rule_and_column_ranges_rule_oneshot_sampling_method(
     bobby_columnar_table_multi_batch_deterministic_data_context,
@@ -208,8 +211,8 @@ def test_bobby_profiler_user_workflow_multi_batch_row_count_range_rule_and_colum
 
 
 @pytest.mark.skipif(
-    not is_scipy_stats_bootstrap_loadable(),
-    reason='requires "scipy.stats.bootstrap" to be installed',
+    version.parse(np.version.version) < version.parse("1.21.0"),
+    reason="requires numpy version 1.21.0 or newer",
 )
 def test_bobster_profiler_user_workflow_multi_batch_row_count_range_rule_bootstrap_sampling_method(
     bobster_columnar_table_multi_batch_normal_mean_5000_stdev_1000_data_context,