From 000d1e1f2ca4e4c871ce4f8fa36ed62a503b250a Mon Sep 17 00:00:00 2001 From: Gabriel Franco Date: Fri, 28 Aug 2026 16:57:17 -0300 Subject: [PATCH] experiment v1 --- .gitignore | 1 + README.md | 2 + __pycache__/data.cpython-314.pyc | Bin 0 -> 5263 bytes __pycache__/dp.cpython-314.pyc | Bin 0 -> 846 bytes __pycache__/experiment.cpython-314.pyc | Bin 0 -> 3005 bytes __pycache__/t_tests.cpython-314.pyc | Bin 2096 -> 2080 bytes bud.py | 3 + data.py | 8 +- experiment.py | 152 +++++++++++++++++++++++++ 9 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 __pycache__/data.cpython-314.pyc create mode 100644 __pycache__/dp.cpython-314.pyc create mode 100644 __pycache__/experiment.cpython-314.pyc create mode 100644 bud.py create mode 100644 experiment.py diff --git a/.gitignore b/.gitignore index 6ef09d7..9b31389 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ venv/ **/venv/ *.parquet *.zip +*.csv diff --git a/README.md b/README.md index 5b5f144..3c203c2 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ # Budget Allocation in Differential Privacy + +O experimento está em experiment.py diff --git a/__pycache__/data.cpython-314.pyc b/__pycache__/data.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31decf1d3c5074306ca5a74f943b2e9dfab907ef GIT binary patch literal 5263 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 YxB8XEpDew&@G+75%<{kDz$OFu-+gn5L;wH) delta 928 zcmbVL&1(};5TCd2?QXsrlR_%3ZEQtqqm_tM4Jy4zw56zJ53z^DC77i|l5KeViqJ~} zBBXe!EQ&`3FWwaY6h(9^1o0rAtnEMGyv@cY!Gk#PX6NJ0Z-28h`y%ls(L56$i2%yQ zwzz*&2lytPp0L0;sG!k;yI_!ISR#TfDMC3eePx*nS|T&B5L^|^phrQd21BitbVJRp z0aOwIlTZrHKuJ5iyFlQ{b|R(ykhK}bi>_P3rMq*&lf`XczXR`=1fTa#$X+yp)efKBLxx1{374osd z|BcnptBdtFUjNo(!0Xguj{&bdS;+!~A&p~MS?pQ`aHHzOG0Nq7d3rE#E{B~_-B;?| zs{F{)QaJ7nct`lAZI){_Q<%bXgu_o_bOevnAaVmf#p11eCz;-vYO9^piJekA|7C3I zx%Jd;-|&rh^*Bg&%ci0VCu%cb&3ar_a0r=^mt{P)R9 zyIi+S(^DI~YKzyvC1RIi=xTkVvRShh`Du(HD{wBM+M|S!4qVuU=+|?R)Z?=)eP5$Q i+mFqW= min_value: + yield tuple(sequence + [remaining]) + return + + # Precisamos deixar pelo menos 1 para cada posição restante + max_value = remaining - (length - position - 1) * min_value + + for value in range(min_value, max_value + 1): + yield from generate(position + 1, remaining - value, sequence + [value]) + + for sequence in generate(0, units, []): + yield tuple(value * granularity for value in sequence) + + +# comparação a ser feita: sudeste informal vs nordeste informal +def get_informal_sta(regions): + return ( + regions["Sudeste"]["informal_count"], + regions["Sudeste"]["informal_mean"], + regions["Sudeste"]["informal_std"], + regions["Nordeste"]["informal_count"], + regions["Nordeste"]["informal_mean"], + regions["Nordeste"]["informal_std"], + ) + + +def get_informal_sen(regions): + return ( + regions["Sudeste"]["sens_count"], + regions["Sudeste"]["sens_informal_mean"], + regions["Sudeste"]["sens_informal_std"], + regions["Nordeste"]["sens_count"], + regions["Nordeste"]["sens_informal_mean"], + regions["Nordeste"]["sens_informal_std"], + ) + + +# comparação a ser feita: sudeste formal vs nordeste formal +def get_formal_sta(regions): + return ( + regions["Sudeste"]["formal_count"], + regions["Sudeste"]["formal_mean"], + regions["Sudeste"]["formal_std"], + regions["Nordeste"]["formal_count"], + regions["Nordeste"]["formal_mean"], + regions["Nordeste"]["formal_std"], + ) + + +def get_formal_sen(regions): + return ( + regions["Sudeste"]["sens_count"], + regions["Sudeste"]["sens_formal_mean"], + regions["Sudeste"]["sens_formal_std"], + regions["Nordeste"]["sens_count"], + regions["Nordeste"]["sens_formal_mean"], + regions["Nordeste"]["sens_formal_std"], + ) + + +def us(bud_sequence, sen_sequence): + result = 0 + for i in range(12): + result += sen_sequence[i] / bud_sequence[i] + return result + + +def ue(sta_true, bud, sen): + result = [0.0, 0.0] + for i in range(1000): + sta_noisy = [] + for i in range(12): + sta_noisy.append(epsilon_dp(sta_true[i], bud[i], sen[i])) + + t_true_informal = t(*sta_true[0:6]) + t_true_formal = t(*sta_true[6:12]) + t_noisy_informal = t(*sta_noisy[0:6]) + t_noisy_formal = t(*sta_noisy[6:12]) + result[0] += abs(t_true_informal - t_noisy_informal) + result[1] += abs(t_true_formal - t_noisy_formal) + + result[0] = result[0] / 1000 + result[1] = result[1] / 1000 + + return result + + +df = pd.read_parquet(FILE) +df = clip_and_normalize(df, C) +regions = get_regions(df, C) + +sequences = [] +if sys.argv[1] == "real": + sequences = generate_sequences() +elif sys.argv[1] == "teste": + sequences = [ + [1 for _ in range(12)], + [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5], + [2 for _ in range(12)], + ] + +informal_sta = get_informal_sta(regions) +formal_sta = get_formal_sta(regions) +informal_sen = get_informal_sen(regions) +formal_sen = get_formal_sen(regions) + +print(informal_sen) +print(formal_sen) + +results = [] +best_metric = sys.float_info.max + +for bud in sequences: + metric = 0 + sta = informal_sta + formal_sta + sen = informal_sen + formal_sen + us_result = us(bud, sen) + ue_result = ue(sta, bud, sen) + metric += us_result + metric += ue_result[0] + ue_result[1] + metric = metric / 14.0 + print(metric) + results.append([*bud, metric]) + if metric < best_metric: + best_metric = metric + +print(f"melhor metrica: {best_metric}") + +# gera um dataframe do pandas com cada valor de bud de cada sequência, seguido do resultado da metrica para aquela sequência +cols = [f"bud_{i}" for i in range(1, 13)] +cols.append("metric") + +result_df = pd.DataFrame(results, columns=cols) +result_df.to_csv("result.csv") + +print("Dados salvos em result.csv")