def main(): odp = opendp.OpenDP() ### HELLO WORLD identity = odp.trans.make_identity(b"<HammingDistance, String>") arg = "hello, world!" res = odp.transformation_invoke(identity, arg) print(res) odp.core.transformation_free(identity) ### SUMMARY STATS # Parse dataframe col_names = odp.py_to_object([0, 1, 2]) split_dataframe = odp.trans.make_split_dataframe(b"<HammingDistance, i32>", b",", col_names) parse_column_1 = odp.trans.make_parse_column( b"<HammingDistance, i32, i32>", opendp.i32_p(1), True) parse_column_2 = odp.trans.make_parse_column( b"<HammingDistance, i32, f64>", opendp.i32_p(2), True) parse_dataframe = odp.make_chain_tt_multi(parse_column_2, parse_column_1, split_dataframe) # Noisy sum, col 1 select_1 = odp.trans.make_select_column(b"<HammingDistance, i32, i32>", opendp.i32_p(1)) clamp_1 = odp.trans.make_clamp_vec(b"<HammingDistance, i32>", opendp.i32_p(0), opendp.i32_p(10)) bounded_sum_1 = odp.trans.make_bounded_sum( b"<HammingDistance, L1Sensitivity<i32>>", opendp.i32_p(0), opendp.i32_p(10)) base_geometric_1 = odp.meas.make_base_simple_geometric( b"<i32, f64>", opendp.f64_p(1.0), opendp.u32_p(0), opendp.u32_p(1000)) # base_laplace_1 = odp.meas.make_base_laplace(b"<i32>", opendp.f64_p(1.0)) noisy_sum_1 = odp.core.make_chain_mt( base_geometric_1, odp.make_chain_tt_multi(bounded_sum_1, clamp_1, select_1)) # Count, col 1 select_2 = odp.trans.make_select_column(b"<HammingDistance, i32, f64>", opendp.i32_p(2)) count_2 = odp.trans.make_count( b"<HammingDistance, L1Sensitivity<u32>, f64>") base_geometric_2 = odp.meas.make_base_simple_geometric( b"<u32, f64>", opendp.f64_p(1.0), opendp.u32_p(0), opendp.u32_p(1000)) noisy_count_2 = odp.core.make_chain_mt( base_geometric_2, odp.make_chain_tt_multi(count_2, select_2)) # Compose & chain composition = odp.core.make_composition(noisy_sum_1, noisy_count_2) everything = odp.core.make_chain_mt(composition, parse_dataframe) # Do it!!! arg = "ant, 1, 1.1\nbat, 2, 2.2\ncat, 3, 3.3" res = odp.measurement_invoke(everything, arg) print(res) # Clean up odp.core.measurement_free(everything)
def check_stability(scale, threshold, line_count, budget): count_by = odp.trans.make_count_by( b"<SymmetricDistance, L2Sensitivity<f64>, String, u32>", line_count) base_stability = odp.meas.make_base_stability( b"<L2Sensitivity<f64>, String, u32, f64>", line_count, opendp.f64_p(scale), opendp.f64_p(threshold)) stability_mech = odp.core.make_chain_mt(base_stability, count_by) # assuming each line is a different user, a user can influence up to max_word_count_per_individual counts check = odp.measurement_check(stability_mech, max_word_count_per_individual, budget) odp.core.measurement_free(stability_mech) return check
def privatize_vocabulary(word_count, line_count, budget): scale = binary_search( lambda s: check_stability(s, 1000., line_count, budget), 0., 100.) threshold = binary_search( lambda thresh: check_stability(scale, thresh, line_count, budget), 0., 1000.) print("chosen scale and threshold:", scale, threshold) # stability_mech = odp.meas.make_stability_mechanism_l1(b"<u32, u32>", line_count, scale, threshold) # print("does chosen scale and threshold pass:"******"<f64>", opendp.f64_p(scale)) word_count = dict(word_count) vocabulary = set() for word in word_count: privatized_count = odp.measurement_invoke(laplace_mechanism, word_count[word], type_name="<f64>") if privatized_count >= threshold: vocabulary.add(word) return vocabulary
def test_relation(): base_laplace = odp.meas.make_base_gaussian(b"<f64>", opendp.f64_p(1.0)) with pytest.raises(OdpException): odp.measurement_check(base_laplace, 2, (-.01, 1e-7))
def test_unknown_dispatch(): with pytest.raises(OdpException): odp.meas.make_base_laplace(b"<u32>", opendp.f64_p(1.0))
def test_invalid_constructor(): with pytest.raises(OdpException): odp.meas.make_base_laplace(b"<f64>", opendp.f64_p(-1.0))
def test_invalid_data(): base_laplace = odp.meas.make_base_laplace(b"<f64>", opendp.f64_p(1.0)) with pytest.raises(OdpException): odp.measurement_invoke(base_laplace, 2)
def test_invalid_arg_length(): with pytest.raises(OdpException): odp.meas.make_base_laplace(b"<u32, f64>", opendp.f64_p(1.0))
def test_sum_float(): mean = odp.trans.make_bounded_sum(b"<HammingDistance, L1Sensitivity<f64>>", opendp.f64_p(0.), opendp.f64_p(10.)) result = odp.transformation_invoke(mean, [1., 2., 3., 4., 5.]) assert isinstance(result, float) assert result == 15.
def test_mean(): mean = odp.trans.make_bounded_mean( b"<HammingDistance, L1Sensitivity<f64>>", opendp.f64_p(0.), opendp.f64_p(10.), 5) result = odp.transformation_invoke(mean, [1., 2., 3., 4., 5.]) assert result == 3.