Measurements#
This section gives a high-level overview of the measurements that are available in the library. Refer to the Measurement for an explanation of what a measurement is.
The intermediate domains and metrics need to match when chaining. This means you will need to choose a measurement that chains with your aggregator.
Additive Noise Mechanisms#
See the Additive Noise Mechanisms notebook for code examples and more exposition.
Notice that there is a symmetric structure to the additive noise measurements:
Vector Input Metric |
Constructor |
---|---|
|
|
|
In the following sections, scalar-valued and vector-valued versions of each measurement are listed separately.
You can choose whether to construct scalar or vector-valued versions by setting the D
type argument when calling the constructor.
- Scalar:
D=AtomDomain[T]
(default)- Vector:
D=VectorDomain[AtomDomain[T]]
Laplacian Noise#
These algorithms accept sensitivities in terms of the absolute or L2 metrics and measure privacy in terms of epsilon.
Use the opendp.accuracy.laplacian_scale_to_accuracy()
and opendp.accuracy.accuracy_to_laplacian_scale()
functions to convert to/from accuracy estimates.
Measurement |
Input Domain |
Input Metric |
Output Measure |
---|---|---|---|
|
|
|
|
|
|
|
Gaussian Noise#
These algorithms accept sensitivities in terms of the absolute or L2 metrics and measure privacy in terms of rho (zero-concentrated differential privacy).
Use the opendp.accuracy.gaussian_scale_to_accuracy()
and opendp.accuracy.accuracy_to_gaussian_scale()
functions to convert to/from accuracy estimates.
Refer to Measure Casting to convert to approximate DP.
Measurement |
Input Domain |
Input Metric |
Output Measure |
---|---|---|---|
|
|
|
|
|
|
|
Geometric Noise#
The geometric mechanism (make_geometric
) is an alias for the discrete Laplace (make_laplace
).
If you need constant-time execution to protect against timing side-channels, specify bounds!
Noise Addition with Thresholding#
When releasing data grouped by an unknown key-set, it is necessary to use a mechanism that only releases keys which are “stable”. That is, keys which are present among all neighboring datasets.
The stability histogram is used to release a category set and frequency counts, and is useful when the category set is unknown or very large.
make_count_by
is included here because it is currently the only transformation that make_base_laplace_threshold
chains with.
See the Histograms notebook for code examples and more exposition.
Constructor |
Input Domain |
Input Metric |
Output Metric/Measure |
---|---|---|---|
|
|
|
|
|
|
|
Randomized Response#
These measurements are used to randomize an individual’s response to a query in the local-DP model.
See the Randomized Response notebook for code examples and more exposition.
Measurement |
Input Domain |
Input Metric |
Output Measure |
---|---|---|---|
|
|
|
|
|
|
|
Bring Your Own#
Use opendp.measurements.make_user_measurement()
to construct a measurement for your own mechanism.
Note
This requires a looser trust model, as we cannot verify any privacy or stability properties of user-defined functions.
>>> import opendp.prelude as dp
>>> dp.enable_features("honest-but-curious", "contrib")
This example mocks the typical API of the OpenDP library to make the most private DP mechanism ever!
>>> def make_base_constant(constant):
... """Constructs a Measurement that only returns a constant value."""
... def function(_arg: int):
... return constant
...
... def privacy_map(d_in: int) -> float:
... return 0.0
...
... return dp.m.make_user_measurement(
... input_domain=dp.atom_domain(T=int),
... input_metric=dp.absolute_distance(T=int),
... output_measure=dp.max_divergence(T=float),
... function=function,
... privacy_map=privacy_map,
... TO=type(constant), # the expected type of the output
... )
The resulting Measurement may be used interchangeably with those constructed via the library:
>>> meas = (
... (dp.vector_domain(dp.atom_domain((0, 10))), dp.symmetric_distance())
... >> dp.t.then_sum()
... >> make_base_constant("denied")
... )
...
>>> meas([2, 3, 4])
'denied'
>>> meas.map(1) # computes epsilon, because the output measure is max divergence
0.0
While this mechanism clearly has no utility, the code snip may form a basis for you to create own measurements, or even incorporate mechanisms from other libraries.
You can also define your own transformations (opendp.transformations.make_user_transformation()
) and postprocessors (opendp.core.new_function()
).