From 292510f409e445b7d82919eddfba05bb77c56d16 Mon Sep 17 00:00:00 2001 From: Oscar Plaisant Date: Thu, 27 Jun 2024 17:14:56 +0200 Subject: [PATCH] move `concentration_test.py` to `old_concentration_test.py`. gitignore the `__pycache__`. --- old_concentration_test.py | 342 ++++++++++++++++++ .../concentration_test.cpython-312.pyc | Bin 9459 -> 0 bytes src/__pycache__/data.cpython-312.pyc | Bin 5271 -> 0 bytes .../kemeny_young.__tau-38.py312.1.nbc | Bin 39558 -> 0 bytes .../kemeny_young.__tau-38.py312.nbi | Bin 587 -> 0 bytes src/__pycache__/kemeny_young.cpython-312.pyc | Bin 3561 -> 0 bytes src/__pycache__/orderankings.cpython-312.pyc | Bin 5202 -> 0 bytes .../query_generator.cpython-312.pyc | Bin 9683 -> 0 bytes src/__pycache__/querying.cpython-312.pyc | Bin 7090 -> 0 bytes src/__pycache__/tools.cpython-312.pyc | Bin 1191 -> 0 bytes src/__pycache__/tprint.cpython-312.pyc | Bin 3465 -> 0 bytes 11 files changed, 342 insertions(+) create mode 100644 old_concentration_test.py delete mode 100644 src/__pycache__/concentration_test.cpython-312.pyc delete mode 100644 src/__pycache__/data.cpython-312.pyc delete mode 100644 src/__pycache__/kemeny_young.__tau-38.py312.1.nbc delete mode 100644 src/__pycache__/kemeny_young.__tau-38.py312.nbi delete mode 100644 src/__pycache__/kemeny_young.cpython-312.pyc delete mode 100644 src/__pycache__/orderankings.cpython-312.pyc delete mode 100644 src/__pycache__/query_generator.cpython-312.pyc delete mode 100644 src/__pycache__/querying.cpython-312.pyc delete mode 100644 src/__pycache__/tools.cpython-312.pyc delete mode 100644 src/__pycache__/tprint.cpython-312.pyc diff --git a/old_concentration_test.py b/old_concentration_test.py new file mode 100644 index 0000000..b06a938 --- /dev/null +++ b/old_concentration_test.py @@ -0,0 +1,342 @@ +import matplotlib.pyplot as plt +import numpy as np +from scipy.stats import norm as Norm, beta as Beta, t as Student +from tprint import tprint +import orderankings as odrk +from querying import find_orderings +from kemeny_young import kendall_tau_dist, rank_aggregation +from tqdm import tqdm +from collections import Counter, defaultdict +import joblib +from functools import partial +import random +import yaml + +# Random number generator for the whole program +# RNG = np.random.default_rng(1234) + + + +######################## YAML CONFIG (src/config.yaml) ######################### +with open('src/config.yaml') as config_file: + cfg = yaml.load(config_file, Loader=yaml.Loader) + +DATABASE_NAME = cfg["database_name"] + + +VERBOSE = cfg["verbose"]["concentration_test"] + + +################## DATA SETTINGS (parameters, hypothesis...) ################### +# loaded from src/config.yaml + +PARAMETER = tuple(cfg[DATABASE_NAME]["parameter"]) +SUMMED_ATTRIBUTE = tuple(cfg[DATABASE_NAME]["summmed_attribute"]) +# SUMMED_ATTRIBUTE = "lo_revenue" +# SUMMED_ATTRIBUTE = "lo_extendedprice" +LENGTH = cfg[DATABASE_NAME]["orders_length"] + +AUTHORIZED_PARAMETER_VALUES = tuple(cfg[DATABASE_NAME]["authorized_parameter_values"]) + +CRITERION = tuple(cfg[DATABASE_NAME]["criterion"]) + +HYPOTHESIS_ORDERING = tuple(cfg[DATABASE_NAME]["hypothesis_ordering"]) + +assert len(HYPOTHESIS_ORDERING) == LENGTH + +################################ LOSS FUNCTIONS ################################ + +def orderings_average_loss(orderings: list[list[str]], truth: list[str]) -> float:# {{{ + """This loss is the the average of kendall tau distances between the truth + and each ordering.""" + rankings = odrk.rankings_from_orderings(orderings) + true_ranking = odrk.rankings_from_orderings([truth])[0] + return rankings_average_loss(rankings, true_ranking)# }}} + + +def rankings_average_loss(rankings: list[list[int]], truth: list[int]) -> float:# {{{ + distance = sum(kendall_tau_dist(rkng, truth) for rkng in rankings) + length = len(rankings) + # apparently, this is what works for a good normalization + return distance / length + # return distance * 2 / (length * (length - 1))}}} + + +def kmny_dist_loss(orderings: list[list[str]], truth: list[str]) -> int:# {{{ + """Return the kendall tau distance between the truth and the kemeny-young + aggregation of orderings""" + _, agg_rank = rank_aggregation(odrk.rankings_from_orderings(orderings)) + aggregation = odrk.ordering_from_ranking(agg_rank, truth) + loss = kendall_tau_dist( + odrk.ranking_from_ordering(aggregation), + odrk.ranking_from_ordering(truth)) + return loss + # print(aggregation, HYPOTHESIS_ORDERING, kdl_agg_dist)}}} + + +def get_loss_progression(): # {{{ + grouped_orderings = find_orderings(parameter=PARAMETER, + summed_attribute=SUMMED_ATTRIBUTE, + criterion=CRITERION, + length=LENGTH) + RNG.shuffle(grouped_orderings) + + average_losses = [] + kendal_aggregation_losses = [] + + for nb_considered_orderings in range(1, len(grouped_orderings)+1): + # loss as the average distance from truth to all considered orderings + considered_orderings = grouped_orderings[:nb_considered_orderings] + loss = orderings_average_loss(orderings=considered_orderings, + truth=HYPOTHESIS_ORDERING) + + # loss as the distance between truth and the aggregation + kdl_agg_loss = kmny_dist_loss(orderings=considered_orderings, + truth=HYPOTHESIS_ORDERING) + kendal_aggregation_losses.append(kdl_agg_loss) + + if VERBOSE: + print(f"using {nb_considered_orderings} orderings") + tprint(considered_orderings) + print("truth :", HYPOTHESIS_ORDERING) + print("loss =", loss) + average_losses.append(loss) + return average_losses, kendal_aggregation_losses + # }}} + +################## APPLIED ON SAMPLES FOR CONCENTRATION TESTS ################## + +def plot_loss_progression(): # {{{ + """Plot the progression of losses when using more and more of the values + (see get_loss_progression).""" + N = 20 + + avg_loss_progression, kdl_agg_loss_progression = get_loss_progression() + avg_loss_progression = np.array(avg_loss_progression) + kdl_agg_loss_progression = np.array(kdl_agg_loss_progression) + + for _ in tqdm(range(N-1), leave=False): + avg_lp, kmny_lp = get_loss_progression() + avg_loss_progression += avg_lp + kdl_agg_loss_progression += kmny_lp + # print(progression) + if VERBOSE: + print(avg_loss_progression) + print(kdl_agg_loss_progression) + plt.plot(avg_loss_progression, color="orange") + plt.plot(kdl_agg_loss_progression, color="green") + # }}} + +def get_mode_loss_progression(all_orderings: list[list[str]], + number_of_steps: int, + orders_added_each_step: int =1) -> list[bool]: + + # all_rankings = odrk.rankings_from_orderings(all_orderings) + + # considered_orderings = list(RNG.choice(all_orderings, size=orders_added_each_step)) + considered_orderings = list(random.choices(all_orderings, k=orders_added_each_step)) + # count occurrences of each ordering + orderings_count = Counter(map(tuple, considered_orderings)) + + # loss progression when adding more and more orderings + loss_history = np.zeros(number_of_steps) + + # # random permutation of the orderings + # permuted_orderings = np.random.permutation(all_orderings) + + for idx in range(number_of_steps): + # new_orders = RNG.choice(all_orderings, size=orders_added_each_step) + new_orders = random.choices(all_orderings, k=orders_added_each_step) + # new_orders = permuted_orderings[orders_added_each_step*idx:orders_added_each_step*(idx+1)] + + # considered_orderings.extend(new_orders) + # update the counter of orderings occurrences + orderings_count.update(Counter(map(tuple, new_orders))) + # the most common (modal) ordering + modal_ordering = orderings_count.most_common()[0][0] + modal_ordering = np.array(modal_ordering) + # if VERBOSE: print(modal_ordering) + # the loss is 1 if the modal ordering is the same as the hypothesis + loss = int(not np.array_equal(modal_ordering, HYPOTHESIS_ORDERING)) + # loss = int((modal_ordering == HYPOTHESIS_ORDERING).all()) + # loss = int(all(map(lambda x: x[0]==x[1], + # zip(modal_ordering, HYPOTHESIS_ORDERING)))) + # add loss to the list of losses + loss_history[idx] = loss + if VERBOSE: + # print(loss_history, HYPOTHESIS_ORDERING) + print(orderings_count.most_common(1)[0]) + return np.repeat(loss_history, orders_added_each_step) + + +################################################################################ + +def plot_modal_losses(): + ################### + # sampling settings + N = 100 # number of repetitions of the experiment + max_number_of_orders = 7500 # max sample size + GRANULARITY = 12 # granularity of the sampling (orders by iteration) + + number_of_steps = max_number_of_orders // GRANULARITY + + all_orderings = find_orderings( + parameter=PARAMETER, + summed_attribute=SUMMED_ATTRIBUTE, + criterion=CRITERION, + length=LENGTH, + authorized_parameter_values=AUTHORIZED_PARAMETER_VALUES) + + print(f"there are {all_orderings.size} orders in total :") + tprint(all_orderings, limit=10) + + + # make get_mode_loss_progression parallelizable + gmlp = joblib.delayed(get_mode_loss_progression) + + #### + # Aggregate multiple simulations + + # don't use the tqdm progress bar if there are some logs + range_N = range(N) if VERBOSE else tqdm(range(N)) + + # for my 8-core computer, n_jobs=7 is empirically the best value + loss_history = joblib.Parallel(n_jobs=7)( + gmlp(all_orderings, + number_of_steps, + orders_added_each_step=GRANULARITY) + for _ in range_N + ) + loss_history = np.array(loss_history) + + # the sum of losses for each number of steps + losses = np.sum(loss_history, axis=0) + + if VERBOSE: print("losses :", losses, sep="\n") + + ##### + # average + # since losses is the sum of losses, losses/N is the average + mean = losses / N + plt.plot(mean, color="green", label="loss average") + + ##### + # standard deviation + # variance is (average of squares) - (square of the average) + # since we only have 1 or 0, average of squares is just the average + # so the variance is average - average**2 + # stddev is the square root of variance + stddev = np.sqrt(mean - mean**2) + plt.plot(stddev, color="grey", label="loss standard deviation") + + + + ############################################################################ + # CONFIDENCE INTERVALS + + X = np.arange(mean.size) # the x axis + + ###### + ## confidence interval + ## assuming the experimental variance is the correct one + #confidence = 0.95 + #alpha = 1 - confidence + #eta = Norm.ppf(1 - alpha/2, loc=0, scale=1) + #epsilon = eta * stddev / np.sqrt(N) + #plt.fill_between(X, mean - epsilon, mean + epsilon, + # color="blue", alpha=0.25, + # label=f"{100*confidence}% confidence interval") + + ##### + # confidence interval + # assuming each summed distribution is a normal distribution + confidence = 0.999999 + delta = 1 - confidence + + # corrected sample variance + S = np.sqrt((1 / N-1) * (mean - mean**2)) + + eta = Student(df=N-1).ppf(1 - delta/2) + epsilon = eta * stddev / np.sqrt(N) + plt.fill_between(X, mean - epsilon, mean + epsilon, + color="green", alpha=0.2, + label=f"{100*confidence}% confidence interval") + + # confidence = 0.95 + # delta = 1 - confidence + # eta = Student(df=X-1).ppf(1 - delta/2) + # epsilon = eta * stddev / np.sqrt(X) + # plt.fill_between(X, mean - epsilon, mean + epsilon, + # color="green", alpha=0.5, + # label=f"{100*confidence}% confidence interval") + + ###### + ## beta distribution + ## confidence = 0.95 + #delta = 1 - confidence + #alpha = np.cumsum(1 - loss_history, axis=1).mean(axis=0) + #beta = np.cumsum(loss_history, axis=1).mean(axis=0) + #epsilon = Beta.ppf(1 - delta/2, alpha, beta) + #plt.fill_between(X, mean - epsilon, mean + epsilon, + # color="orange", alpha=0.30, + # label=f"{100*confidence} β confidence interval") + + + ###### + ## fluctuation interval + #confidence = 0.1 + #alpha = 1-confidence + #k = Norm.ppf(alpha/2, loc=0, scale=1) + #fluctuation = k * stddev + #plt.fill_between(X, mean - fluctuation, mean + fluctuation, + # color="orange", alpha=0.25, + # label=f"{100*confidence}% fluctuation interval") + + ##### + # hoeffding + t = 0.99 + plt.plot(X, np.exp(-2 * t ** 2 / X), + color="red") + + ###### + ## y = 1/2 + #plt.plot([0, mean.size], [0.5, 0.5], + # color="orange", alpha=0.25) + +if __name__ == '__main__': + rankings = np.array([[1, 3, 2, 4], + [3, 4, 2, 1], + [1, 2, 3, 4], + [1, 3, 2, 4], + [2, 3, 1, 4], + [1, 3, 2, 1], + [2, 3, 1, 4], + [2, 3, 1, 4]]) + + # all_orderings = find_orderings(parameter=PARAMETER, + # summed_attribute=SUMMED_ATTRIBUTE, + # criterion=CRITERION, + # length=LENGTH) + # # print(all_orderings) + # print(f"There are {len(all_orderings)} orderings in `all_orderings`") + + # for _ in range(20): + # dep = time() + # plot_modal_losses() + # print(round(time()-dep, 4)) + + plt.style.use('dark_background') + + # HYPOTHESIS_ORDERING = ("bisque", "aquamarine") + # plot_modal_losses() + HYPOTHESIS_ORDERING = ("bisque", "blue") + plot_modal_losses() + plt.legend() + + ax = plt.gca() + # ax.set_ylim([0, 1]) + + # plt.ion() + plt.show() + + diff --git a/src/__pycache__/concentration_test.cpython-312.pyc b/src/__pycache__/concentration_test.cpython-312.pyc deleted file mode 100644 index 8ae3b2e5f4ae3d0619772921752199cb2540d823..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9459 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 diff --git a/src/__pycache__/data.cpython-312.pyc b/src/__pycache__/data.cpython-312.pyc deleted file mode 100644 index 997dfbb11e332bd3c5dc45852a3f81a31920ed6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5271 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 diff --git a/src/__pycache__/kemeny_young.__tau-38.py312.1.nbc b/src/__pycache__/kemeny_young.__tau-38.py312.1.nbc deleted file mode 100644 index 804ca7433f12084dd33b0d5fb6deff3428f9caf8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39558 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 diff --git a/src/__pycache__/kemeny_young.cpython-312.pyc b/src/__pycache__/kemeny_young.cpython-312.pyc deleted file mode 100644 index 8a3913d150fdc1f2bcbf4ffad9d5ed03d235667d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3561 zcmai0U2qfE6}~I2Wc~V2wv4bL3xo!Fj1Ab3Vi*$hS2LyVP)KJ`Q#NbumAv+9SKM70 z>`JMoL#9$;20Kj$IWK{x4|ZUtPM_!-kDcj5D|#oAJEbl=8$pjCZNtlsD#Oyj%69d@&z~upb9zn-GcxT_<>hwRryYmn(9}MJ$j7iFHwoO`&OOP=$EI!dR=hR16$9D(B$BEWw>*4=(|!GG23)M=(!L6r6tyl zJ8`$n$=nBynuTKEdb|T_JMP(f4i4Qq!=o8)hKuf4qtnNt4$C>Im=>=AjdE5XjY%qF zN~WS~2K3wFdTLzJYJE{ph=)MPn^)x&v~Dv^6wS1}MAD`dEh$PH?6~D7*vt?uUOy?_ z4!NK@p{_p$atE39C;=O6)`BrwvdBJv?p2yxLz6S<9;{^1q}%2<+J>ehi?S@Ta?UJQ z=lJiRlXJj)0i04K`m=lU7(9P45LJT@t(l+MPe#3PzBENKWymp#3>aVEF za%gGGB@rUc5NctIH0Fp=Fcu-sDj%VIeid0(nX?H%8?+DsDm^^V>yjX3i!sM4XPmsgqo4G+2jYn7;ggs zqqhBjC9u<94lZ9<9{fDK z)Uwk4!;1fCnLkRl!6KH&j{p960}Vj#fy$8L07!r9ezleCy8%|f)LNP3ZEmB@0aoT9 z_rDJt-h~V2oH>3Y*G=3J_s*IU5K8!D;|#^fk7il3SKDOl zg$SX(rJ=gs1LP0f<_IZrU`-mlP{118Sd?RU0IwZSrnDqHYk+o&ESXre!;h*9c^2#6 zdXB47YFw61%4ASiYZ2Y6hPnL?_WE zLN9B1z&;G+tiU)nO#2QNCt5*mTx?veT%EHoK+Oy7g|P4^(J1J^}*Q z`KB4Qw%@*9yk7EDT6X0}A9sZBoSi?LA6*S~<{pQ`S(}&j{HbI_iRV>!QSOy zrT0W-$6L>l+qJ*!i9Bm*yFFc;{%HKmaC9Xct@OTE9*>uCsuI>JEqZ}}>Tj9bck`{) zuI|Fc+TBDJ%d58>vfb>&Bf4^XeHq0?KDV@rcUKnChHjB=GVQ6DPwktL58h!BAc2Z4_ zw9;m$FiaUUJTtkxA5yKg6{I+hoOh~ z(W$?M9*zE0FCYEM%HY^K9jFc=K2VtbhcmJo=qQ}LJz5<7P`AQ+8(-DShu>I7d~jd> zOf`&xoi(NTOACGXGK&{Jyn2#F+Ku?_EX@B8-$p{{ diff --git a/src/__pycache__/orderankings.cpython-312.pyc b/src/__pycache__/orderankings.cpython-312.pyc deleted file mode 100644 index 643781d5d59197918be4163e21fdc267c8731e62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5202 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 UF5g@^`P#p7_EqXTd}TiQFZ*b6sQ>@~ diff --git a/src/__pycache__/query_generator.cpython-312.pyc b/src/__pycache__/query_generator.cpython-312.pyc deleted file mode 100644 index 256921c79c103d862feba48e7e27c13c750e64cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9683 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 diff --git a/src/__pycache__/querying.cpython-312.pyc b/src/__pycache__/querying.cpython-312.pyc deleted file mode 100644 index 90ca214e61cb7ccd988e92b4197441a9f77f77ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7090 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 diff --git a/src/__pycache__/tprint.cpython-312.pyc b/src/__pycache__/tprint.cpython-312.pyc deleted file mode 100644 index b8f2229282fde7de18530243221d8635b57c292c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3465 zcmcImO>7&-6`t8$l1oaIZ85TJDRx$h**>EBti7P~@;1sAW6^)Gok`i{!9ZFP| zyX@>RwrHtPV+ElT7gb=la*+Ua&_g6RX#+S10lnlHAQv+hVtJ!O;9i=WZ2FM+)HkzS zk~Y-DE!qJ&JOA^(_rCY$eIAWQ5R|Wyzsl|oA@mR4@k^lAsP;o+5gBL{8Q73aJSrIx zLm_fjG6M5~QN;)vvJrYuGE@=}r9?|j{Ok#D#V!{2Zz-GG_P=U7JKL$#v9SB8JJA4cC) z7ZJn$)C{^(Ya960I6}0Q@s*+&l0S#hw9I^@Xe#KhXnZBqG|%sQpcu-0{ifzSKMY){ zN&1!w8VXIdJg^bEhB}YVsYB>WZOWIb#OK1io|PI>&ooKRqO~okapw?vIgijd+&U}I zDl_s7esu_N{|Kzrvgz%u-*bCZ+#YDUJ>W}+5!ad#nGMbaH$S(sx+#)v--D!GAPF^{8fu(6Ehl27n?I+7v1yNoIcowa zNHx92LCr3*LXo8&*Up?d6Vady(h28T(c(Qp$~dq(@vL?nD4y3(YgRFTl2Fag!mOaa z?VX*f@8UcC@)OZ5b03L^-_QuNa~r^w@lr`cjyG(i(rL0k9f zf`^?$@UQNL>Sy3Qi{P{`!}?h~gAG&yUHuU+VxV}7f~N6D@+rJ575OeWX?PheORkhU z;08|R3^wU-i)tF>(d1tE@C32Q=>i=n^$4D9hR0vh4m+xkK=n`b?Hu|dKC;rW)Uj0j zsJjv$`L3$K#OqtO;Tj~saiPe^fB{;OTT|n$`*87TfolL7bzB`Bmw~35*#Psr%wXTr zHN2fZ-b4-W+kYJf-3BwnVuVsIaWh^DXQPKex}ERa36+O5Iriy^r4xS}Umjn1;>P~x zE6K6%909j`7Zw;fwEK{8yaL%P(D(zcW7|^;uNcB|9bY3XPt_k7*j6j&APjR+9zebq zkRxts3ePS|NR-nDUbv~E!x9RO@m?rnn`sCou1rkkwnDF%x6&R9xcm@5<^&HORxe$! z$vFtsw?Z*@5bhboH?`#D&{FKKjC%K8&irNP2amn~*vF5qOjHgYxzY3DZL!AF*V%ph zeR}YS&|v)E{|Ahx+~4RnUj4Ub-_193+tW^{8bp3K5u*Izb_2pkT*)f9GK6V2{2IwH zo90TyRi^Bm<%S8Un^2vRMA%gfo#~V-+6_(;-5}JJxiu6XgI$%FX0G7m99N~pNsF;y z*0wosxgZWVC|F38=Y^Tvw)=gQ?uR8jf;gQ(Ch*C-ZAfh?KXrC`Ves|etgF#$ZO*F7 z*3`E3SjS@jJN?(X2HxxabMjBg%9B67-Zikou6GT6c5pRzZ0_jS(T+@7VU3DZ7>xr?lqhy?5Liw|eWz#D9{4h}?$gnMv>9hBQ7``S<^r zk?`YP{(#EFGT^ZnPCzxV8iYM=R?p)Uu0J>6>8=*+yhqOsde1q13KsXk-+2~1~gk!grow)t7 eTt)EN=tsLA|5&<%T5$J*v%x=0hwk!^5b0m=%vgE=