From 52a2042b38a4d31a6008a57291cb48b0eb47ee85 Mon Sep 17 00:00:00 2001 From: Davide Posillipo <40352574+DavidePosillipo@users.noreply.github.com> Date: Sun, 2 Jun 2024 12:02:47 +0200 Subject: [PATCH 1/2] Risk measure in dev (#23) * Risk measure implementation (#22) * first Risk Measure implementation in notebook * completed notebook risk implementation. Added experiments on 3 models * new risk experiments WIP * removed useless folder * implemented risk measure weights and adapted for FreqVsRef, Notebook3 * added first Risk classes (wip) * doc explaining risk implementation and strategy -- final * Create #FreqVsRefBiasDetector.py# * changed HazardCalculator with new scaling * Avoided nan results for JS distance in Bias Detector (task 86946hjea) * Better management of None distances to avoid crash during max and std computation * changed behavior for multi-class problems and None distances exclusion * fixed output data structure in FreqVsRef to prevent bug in Hazard computation * added Risks unit tests * updated README file --------- Co-authored-by: etagreta Co-authored-by: francescogenco * Update VERSION.txt --------- Co-authored-by: dlbddepartment <98757489+dlbddepartment@users.noreply.github.com> Co-authored-by: etagreta Co-authored-by: francescogenco --- .circleci/config.yml | 5 + README.md | 7 +- VERSION.txt | 2 +- brio/bias/FreqVsFreqBiasDetector.py | 86 +- brio/bias/FreqVsRefBiasDetector.py | 88 +- .../risk/HazardFromBiasDetectionCalculator.py | 96 + brio/risk/RiskCalculator.py | 20 + brio/{risks => risk}/__init__.py | 0 notebooks/RiskMeasure_experiments_2_WIP.ipynb | 2187 +++++++++++++++++ notebooks/RiskMeasure_experiments_3.ipynb | 906 +++++++ notebooks/RiskMeasure_experiments_4.ipynb | 821 +++++++ ...asure_implementation_and_experiments.ipynb | 721 ++++++ notes on risk/main.aux | 27 + notes on risk/main.bbl | 26 + notes on risk/main.blg | 59 + notes on risk/main.pdf | Bin 0 -> 221411 bytes notes on risk/main.synctex.gz | Bin 0 -> 34124 bytes notes on risk/main.tex | 109 + notes on risk/main.toc | 6 + notes on risk/temp.bib | 1945 +++++++++++++++ tests/unit/TestBiasDetector.py | 24 +- tests/unit/TestRiskCalculator.py | 58 + ...ed_groups_with_KL_and_ref_distribution.pkl | Bin 0 -> 2666 bytes ...t_variable_conditioned_groups_with_TVD.pkl | Bin 0 -> 2093 bytes ...t_compare_root_variable_groups_with_JS.pkl | Bin 0 -> 177 bytes ...le_groups_with_KL_and_ref_distribution.pkl | Bin 0 -> 214 bytes ..._compare_root_variable_groups_with_TVD.pkl | Bin 0 -> 177 bytes 27 files changed, 7113 insertions(+), 80 deletions(-) create mode 100644 brio/risk/HazardFromBiasDetectionCalculator.py create mode 100644 brio/risk/RiskCalculator.py rename brio/{risks => risk}/__init__.py (100%) create mode 100644 notebooks/RiskMeasure_experiments_2_WIP.ipynb create mode 100644 notebooks/RiskMeasure_experiments_3.ipynb create mode 100644 notebooks/RiskMeasure_experiments_4.ipynb create mode 100644 notebooks/RiskMeasure_implementation_and_experiments.ipynb create mode 100644 notes on risk/main.aux create mode 100644 notes on risk/main.bbl create mode 100644 notes on risk/main.blg create mode 100644 notes on risk/main.pdf create mode 100644 notes on risk/main.synctex.gz create mode 100644 notes on risk/main.tex create mode 100644 notes on risk/main.toc create mode 100644 notes on risk/temp.bib create mode 100644 tests/unit/TestRiskCalculator.py create mode 100644 tests/unit/test_data/results_test_compare_root_variable_conditioned_groups_with_KL_and_ref_distribution.pkl create mode 100644 tests/unit/test_data/results_test_compare_root_variable_conditioned_groups_with_TVD.pkl create mode 100644 tests/unit/test_data/results_test_compare_root_variable_groups_with_JS.pkl create mode 100644 tests/unit/test_data/results_test_compare_root_variable_groups_with_KL_and_ref_distribution.pkl create mode 100644 tests/unit/test_data/results_test_compare_root_variable_groups_with_TVD.pkl diff --git a/.circleci/config.yml b/.circleci/config.yml index 04cab68..47f10df 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,6 +13,11 @@ jobs: pip3 install -r requirements.txt python3 -m tests.unit.TestBiasDetector + - run: + name: Unit Tests for Risk Calculator + command: | + python3 -m tests.unit.TestRiskCalculator + workflows: version: 2 test_and_run: diff --git a/README.md b/README.md index e1412f3..c160786 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,13 @@ The method `compare_root_variable_conditioned_groups` performs the same calculat For both methods the output is a tuple similar to the ones described for the FreqsVsRef method, but with an additional element given by the standard deviation of the distances, provided only when the root variable is a multi-class feature. +## Focus on the Risk Analysis +With the latest version (1.2) we introduce a Risk measurement, based on the results of the Bias Detector. Currently it's only accessible via the python API, but we plan to add a frontend option for it. It is implemented in the `brio/risk` sub-module. + +The methodology behind the risk computation will be soon published with a scientific paper. If you want to experiment with it already, you can use the method `compute_hazard_from_freqvsfreq_or_freqvsref` of the class `HazardFromBiasDetectionCalculator` upon each results from FreqVsFreq and FreqVsRef. The computed hazards need to be passed to `compute_risk` from `RiskCalculator`: this function will provide an overall measure of risk. + ## What's next -Currently (September 2023) we plan to implement functionalities for the Opacity section, which is now empty. Furthermore, we want to introduce a risk measurement analysis, which will provide an overall risk assessment of a model using a series of bias and opacity checks. +Currently (June 2024) we plan to implement functionalities for the Opacity section, which is now empty, and a more refined and accessible Risk section. ## Call to action! We hope to raise interest in the data science community and ask for support! Anyone interested in expanding and improving our tool is more than welcome! You can do that opening a pull request for a functionality you wish to include. Also bugs warnings are very important and welcome. diff --git a/VERSION.txt b/VERSION.txt index 3eefcb9..26aaba0 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -1.0.0 +1.2.0 diff --git a/brio/bias/FreqVsFreqBiasDetector.py b/brio/bias/FreqVsFreqBiasDetector.py index 2c55db4..d8098ff 100644 --- a/brio/bias/FreqVsFreqBiasDetector.py +++ b/brio/bias/FreqVsFreqBiasDetector.py @@ -1,7 +1,7 @@ from .BiasDetector import BiasDetector from .threshold_calculator import threshold_calculator from sklearn.utils.extmath import cartesian -from itertools import combinations +from itertools import combinations, compress from scipy.spatial.distance import jensenshannon import numpy as np @@ -45,16 +45,22 @@ def compute_distance_between_frequencies(self, for pair in combinations(observed_distribution, 2): # Squaring JS given that the scipy implementation has square root distance = jensenshannon(p=pair[0], q=pair[1], base=2)**2 - distances.append(distance) + # If no observation are present for one class, the JS distance will be a nan. + # Changing into None to keep the functionalities of Risk Measurement. + if np.isnan(distance): + distances.append(None) + else: + distances.append(distance) else: raise Exception("Only TVD or JS are supported as distances for freq_vs_freq analysis") - overall_distance = self.aggregating_function(distances) - - if len(distances) > 1: + #Keeping all the not None distances (relevant for multi-classe root variable scenarios) + distances_not_none = list(compress(distances, [d is not None for d in distances])) + overall_distance = self.aggregating_function(distances_not_none) if len(distances_not_none) > 0 else None + if len(distances_not_none) > 1: ## Computing the standard deviation of the distances in case of # multi-class root_variable - return overall_distance, np.std(distances) + return overall_distance, np.std(distances_not_none) else: return overall_distance, None @@ -158,13 +164,11 @@ def compare_root_variable_conditioned_groups(self, # Second parameter for threshold calculator A2 = len(root_variable_labels) - - conditioned_frequencies = {} - conditioning_variables_subsets = list(self.powerset(conditioning_variables)) # All the possible subsets of conditioning variables are inspected. The first one # is excluded being the empty set. + conditioned_frequencies = {} for conditioning_variables_subset in conditioning_variables_subsets[1:]: combinations = cartesian([dataframe[v].unique() for v in conditioning_variables_subset]) @@ -177,48 +181,52 @@ def compare_root_variable_conditioned_groups(self, dataframe_subset = dataframe.query(condition) num_of_obs = dataframe_subset.shape[0] - if num_of_obs >= min_obs_per_group: - if self.target_variable_type == 'class': - conditioned_frequencies[condition] = ( - num_of_obs, - self.get_frequencies_list( - dataframe_subset, - target_variable, - target_variable_labels, - root_variable, - root_variable_labels)[0] #taking the relative freqs, the absolute freqs are not needed here - ) - elif self.target_variable_type == 'probability': - conditioned_frequencies[condition] = ( - num_of_obs, - self.get_frequencies_list_from_probs( - dataframe_subset, - target_variable, - root_variable, - root_variable_labels, - n_bins)[0] #taking the relative freqs, the absolute freqs are not needed here - ) - - else: - conditioned_frequencies[condition] = (num_of_obs, None) + if self.target_variable_type == 'class': + conditioned_frequencies[condition] = ( + num_of_obs, + self.get_frequencies_list( + dataframe_subset, + target_variable, + target_variable_labels, + root_variable, + root_variable_labels)[0] #taking the relative freqs, the absolute freqs are not needed here + ) + elif self.target_variable_type == 'probability': + conditioned_frequencies[condition] = ( + num_of_obs, + self.get_frequencies_list_from_probs( + dataframe_subset, + target_variable, + root_variable, + root_variable_labels, + n_bins)[0] #taking the relative freqs, the absolute freqs are not needed here + ) distances = { # group: (number_of_observations, (overall_distance, standard_deviations) ) group: ( (obs_and_freqs[0], self.compute_distance_between_frequencies(obs_and_freqs[1]) # (distance, standard_deviations) - ) if obs_and_freqs[1] is not None else (obs_and_freqs[0], None) + ) ) for group, obs_and_freqs in conditioned_frequencies.items() } - - results = {group: ( - ( + + results = {} + for group, obs_and_dist in distances.items(): + # Too small groups + if obs_and_dist[0] < min_obs_per_group: + result = (obs_and_dist[0], None, 'Not enough observations') + # Groups for which distance is not defined (only one class available, JS computed) + elif obs_and_dist[1][0] is None: + result = (obs_and_dist[0], None, 'Distance non defined') + else: + result = ( obs_and_dist[0], #This will also be the A3 for threshold_calculator, being it the number of obs of the group obs_and_dist[1][0], #distance obs_and_dist[1][0]<=threshold_calculator(A1=self.A1, A2=A2, A3=obs_and_dist[0], default_threshold=threshold), threshold_calculator(A1=self.A1, A2=A2, A3=obs_and_dist[0], default_threshold=threshold), obs_and_dist[1][1] #standard deviation - ) if obs_and_dist[1] is not None else (obs_and_dist[0], obs_and_dist[1], 'Not enough observations') - ) for group, obs_and_dist in distances.items()} + ) + results[group] = result return results \ No newline at end of file diff --git a/brio/bias/FreqVsRefBiasDetector.py b/brio/bias/FreqVsRefBiasDetector.py index 533fb95..4ba6601 100644 --- a/brio/bias/FreqVsRefBiasDetector.py +++ b/brio/bias/FreqVsRefBiasDetector.py @@ -93,8 +93,13 @@ def compute_distance_from_reference(self, kl = kl_elementwise.sum() else: raise Exception("Only 'no','zero' and 'laplace' are supported as divergence adjustment methods.") + divergence = self.normalization_function(kl) - divergences.append(divergence) + + if np.isnan(divergence): + divergences.append(None) + else: + divergences.append(divergence) return divergences @@ -230,34 +235,30 @@ def compare_root_variable_conditioned_groups(self, dataframe_subset = dataframe.query(condition) num_of_obs = dataframe_subset.shape[0] - if num_of_obs >= min_obs_per_group: - if self.target_variable_type == 'class': - freqs, abs_freqs = self.get_frequencies_list( - dataframe_subset, - target_variable, - target_variable_labels, - root_variable, - root_variable_labels) - conditioned_frequencies[condition] = ( - num_of_obs, - freqs, - [sum(x) for x in abs_freqs] - ) - elif self.target_variable_type == 'probability': - freqs, abs_freqs = self.get_frequencies_list_from_probs( - dataframe_subset, - target_variable, - root_variable, - root_variable_labels, - n_bins) - conditioned_frequencies[condition] = ( - num_of_obs, - freqs, - [sum(x) for x in abs_freqs] - ) - - else: - conditioned_frequencies[condition] = (num_of_obs, None) + if self.target_variable_type == 'class': + freqs, abs_freqs = self.get_frequencies_list( + dataframe_subset, + target_variable, + target_variable_labels, + root_variable, + root_variable_labels) + conditioned_frequencies[condition] = ( + num_of_obs, + freqs, + [sum(x) for x in abs_freqs] + ) + elif self.target_variable_type == 'probability': + freqs, abs_freqs = self.get_frequencies_list_from_probs( + dataframe_subset, + target_variable, + root_variable, + root_variable_labels, + n_bins) + conditioned_frequencies[condition] = ( + num_of_obs, + freqs, + [sum(x) for x in abs_freqs] + ) distances = { group: ( @@ -266,17 +267,28 @@ def compare_root_variable_conditioned_groups(self, self.compute_distance_from_reference(observed_distribution=obs_and_freqs[1], reference_distribution=reference_distribution, n_obs=obs_and_freqs[2]) - ) if obs_and_freqs[1] is not None else (obs_and_freqs[0], None) + ) ) for group, obs_and_freqs in conditioned_frequencies.items() } - - results = {group: ( - ( - obs_and_dist[0], - obs_and_dist[1], - [d<=threshold_calculator(A1=self.A1, A2=A2, A3=obs_and_dist[0], default_threshold=threshold) for d in obs_and_dist[1]], + + results = {} + for group, obs_and_dist in distances.items(): + # Too small groups + if obs_and_dist[0] < min_obs_per_group: + result = (obs_and_dist[0], [None for d in obs_and_dist[1]], 'Not enough observations') + else: + result = ( + obs_and_dist[0], #obs + obs_and_dist[1], #distance + [d<=threshold_calculator( + A1=self.A1, + A2=A2, + A3=obs_and_dist[0], + default_threshold=threshold + ) if d is not None else 'Distance not defined' for d in obs_and_dist[1]], threshold_calculator(A1=self.A1, A2=A2, A3=obs_and_dist[0], default_threshold=threshold) - ) if obs_and_dist[1] is not None else (obs_and_dist[0], obs_and_dist[1], 'Not enough observations') - ) for group, obs_and_dist in distances.items()} + ) + + results[group] = result return results \ No newline at end of file diff --git a/brio/risk/HazardFromBiasDetectionCalculator.py b/brio/risk/HazardFromBiasDetectionCalculator.py new file mode 100644 index 0000000..8997f1e --- /dev/null +++ b/brio/risk/HazardFromBiasDetectionCalculator.py @@ -0,0 +1,96 @@ +import numpy as np + +class HazardFromBiasDetectionCalculator: + + ''' + This class manages the calculation of hazards for the + tests within the Bias module + ''' + + def as_list(self, x): + if type(x) is list: + return x + else: + return [x] + + def compute_hazard_from_freqvsfreq_or_freqvsref( + self, + overall_result, + conditioned_results, + tot_observations, + conditioning_variables, + weight_logic="group"): + + ''' + Computes the hazard for a FreqVsFreq or a FreqVsRef analysis. + + Args: + overall_result: dict with non-conditioned results from FreqVs* analysis + conditioned_result: dict with conditioned results from FreqVs* analysis #TODO handle when only overall result is available + tot_observation: num, total number of data points analyzed + conditioning_variables: list, conditioning variables used in FreqVs* analysis + weight_logic: str, it can be either "group" or "individual", it determines how much each single test will weight on the hazard result + ''' + + #tot number features=conditioning + root (+1) + n_features_total = len(conditioning_variables) + 1 + + hazard_overall = 0 + # Iterating over each reference distribution, if available (FreqVsRef) + # In case of FreqVsFreq, there will be a single iteration + num_iterations = len(self.as_list(overall_result[0])) + for k in np.arange(0, num_iterations): + + # test result, threshold, num_samples, boolean, num_used_features + #TODO use dict instead, and use explicit keys for readibility + test_results = [] + test_results.append(( + self.as_list(overall_result[0])[k], + overall_result[2], + tot_observations, + self.as_list(overall_result[1])[k], + 1 #for the overall test, only 1 feature used, the root variable + )) + + for group_name, group in conditioned_results.items(): + if (self.as_list(group[1])[k] is not None): + test_results.append( + ( + self.as_list(group[1])[k], #test result + group[3], #threshold + group[0], #num_samples + self.as_list(group[2])[k], #boolean + len(group_name.split("&"))+1 #num_used_features, cond.+root + ) + ) + + if weight_logic=="group": + #T_i in Risk Function document + weight_denominator = 0 + for line in test_results: + weight_denominator += n_features_total - line[4] + 1 + elif weight_logic=="individual": + #S_i in Risk Function document + weight_denominator = np.sum([x[4] for x in test_results]) + else: + raise Exception('Only "group" or "individual" are allowed for parameter weight_logic') + + + hazard = 0 + for line in test_results: + if weight_logic=="group": + c_info = n_features_total - line[4] + 1 + weight = c_info/weight_denominator + elif weight_logic=="individual": + weight = line[4]/weight_denominator + else: + raise Exception('Only "group" or "individual" are allowed for parameter weight_logic') + + delta = 1 if line[3]==False else 0 + q = line[2]/tot_observations + e = line[0] - line[1] + hazard += delta * weight * q * abs(e)**(1./3.) * line[1]**(1./3.) + + hazard_overall+= hazard + + return hazard_overall \ No newline at end of file diff --git a/brio/risk/RiskCalculator.py b/brio/risk/RiskCalculator.py new file mode 100644 index 0000000..ab4714f --- /dev/null +++ b/brio/risk/RiskCalculator.py @@ -0,0 +1,20 @@ +import numpy as np + +class RiskCalculator: + + def compute_risk(self, test_hazards): + ''' + Computes the overall risk using the hazards coming from the + different Bias and Opacity tests. + + Args: + test_hazards: list of hazards computed for a set of tests + + Returns: + risk: num, the overall measure of risk + ''' + # test_hazards = [list_of_hazards] + + risk = np.sum(test_hazards)/len(test_hazards) + + return risk \ No newline at end of file diff --git a/brio/risks/__init__.py b/brio/risk/__init__.py similarity index 100% rename from brio/risks/__init__.py rename to brio/risk/__init__.py diff --git a/notebooks/RiskMeasure_experiments_2_WIP.ipynb b/notebooks/RiskMeasure_experiments_2_WIP.ipynb new file mode 100644 index 0000000..28737f8 --- /dev/null +++ b/notebooks/RiskMeasure_experiments_2_WIP.ipynb @@ -0,0 +1,2187 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "0b134d6e", + "metadata": {}, + "outputs": [], + "source": [ + "import os, sys\n", + "dir2 = os.path.abspath('')\n", + "dir1 = os.path.dirname(dir2)\n", + "if not dir1 in sys.path: sys.path.append(dir1)" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "77c1e269", + "metadata": {}, + "outputs": [], + "source": [ + "from brio.utils.Preprocessing import Preprocessing\n", + "from sklearn.model_selection import train_test_split\n", + "from pickle import dump, load\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "from brio.bias.FreqVsFreqBiasDetector import FreqVsFreqBiasDetector\n", + "from brio.bias.FreqVsRefBiasDetector import FreqVsRefBiasDetector" + ] + }, + { + "cell_type": "markdown", + "id": "68af6499", + "metadata": {}, + "source": [ + "## Importing Data and Trained Classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "66127e6c", + "metadata": {}, + "outputs": [], + "source": [ + "input_data_path = \"../data/raw_data/uci-default-of-credit-card/data/data.csv\"\n", + "local_path_save = '../data/mlflow_artifacts/'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bf0e3b01", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/davideposillipo/.pyenv/versions/3.10.9/envs/prova/lib/python3.10/site-packages/sklearn/base.py:329: UserWarning: Trying to unpickle estimator OneHotEncoder from version 1.2.1 when using version 1.0.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/modules/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n", + "/Users/davideposillipo/.pyenv/versions/3.10.9/envs/prova/lib/python3.10/site-packages/sklearn/base.py:329: UserWarning: Trying to unpickle estimator StandardScaler from version 1.2.1 when using version 1.0.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/modules/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "fitted_ohe = load(open(local_path_save + '_ohe.pkl', 'rb')) \n", + "fitted_scaler = load(open(local_path_save + '_scaler.pkl', 'rb'))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6646c312", + "metadata": {}, + "outputs": [], + "source": [ + "pp = Preprocessing(input_data_path, \"default\")\n", + "X, Y = pp.read_dataframe()\n", + "\n", + "X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size=0.3, random_state=420)\n", + "\n", + "X_test_ohe, _, _ = pp.preprocess_for_classification(df=X_test, \n", + " fit_ohe=True, \n", + " fitted_ohe=fitted_ohe,\n", + " perform_scaling=True,\n", + " fitted_scaler=fitted_scaler)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "ba010d39", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"./mlruns/1/1e4a0667c7a64cbe8c7b023410e5781c/artifacts/model/model.pkl\", \"rb\") as file:\n", + " classifier = load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "04cacf92", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_prob = classifier.predict_proba(X_test_ohe)\n", + "predicted_values = classifier.predict(X_test_ohe)" + ] + }, + { + "cell_type": "markdown", + "id": "01057c6d", + "metadata": {}, + "source": [ + "#### Definition of conditioning variables" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "d7e96a84", + "metadata": {}, + "outputs": [], + "source": [ + "def age_buckets(x):\n", + " if x < 30:\n", + " return 1\n", + " elif x < 40:\n", + " return 2\n", + " else:\n", + " return 3\n", + "\n", + "X_test['age_buckets'] = X.x5_age.apply(age_buckets)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c24a0c9c", + "metadata": {}, + "outputs": [], + "source": [ + "conditioning_variables = ['x3_education', 'x4_marriage', 'age_buckets']" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7950602d", + "metadata": {}, + "outputs": [], + "source": [ + "df_with_predictions = pd.concat(\n", + " [X_test.reset_index(drop=True), pd.Series(predicted_values)], axis=1).rename(columns={0:\"predictions\"})" + ] + }, + { + "cell_type": "markdown", + "id": "d6f80bfb", + "metadata": {}, + "source": [ + "## Hazard and risk functions" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "7e6183a2", + "metadata": {}, + "outputs": [], + "source": [ + "def hazard_function(overall_result, conditioned_results, tot_observations):\n", + " \n", + " # test result, threshold, num_samples, boolean\n", + " test_results = []\n", + " test_results.append((overall_result[0], \n", + " overall_result[2], \n", + " tot_observations, \n", + " overall_result[1]))\n", + " \n", + " for group in conditioned_results.values():\n", + " if (group[1] is not None):\n", + " test_results.append((group[1], group[3], group[0], group[2]))\n", + " \n", + " hazard = 0\n", + " for line in test_results:\n", + " weight = 1 #to be implemented\n", + " delta = 1 if line[3]==False else 0\n", + " q = line[2]/tot_observations\n", + " e = line[0] - line[1]\n", + " hazard += delta * weight * q * e\n", + " \n", + " average_threshold = np.mean([x[1] for x in test_results])\n", + " \n", + " return hazard, average_threshold" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "a1bdeff0", + "metadata": {}, + "outputs": [], + "source": [ + "def hazard_function_2(overall_result, conditioned_results, tot_observations):\n", + " \n", + " # test result, threshold, num_samples, boolean\n", + " test_results = []\n", + " test_results.append((overall_result[0], \n", + " overall_result[2], \n", + " tot_observations, \n", + " overall_result[1]))\n", + " \n", + " for group in conditioned_results.values():\n", + " if (group[1] is not None):\n", + " test_results.append((group[1], group[3], group[0], group[2]))\n", + " \n", + " hazard = 0\n", + " for line in test_results:\n", + " weight = 1 #to be implemented\n", + " delta = 1 if line[3]==False else 0\n", + " q = line[2]/tot_observations\n", + " e = line[0] - line[1]\n", + " hazard += delta * weight * q * e * line[1] #aggiunta di threshold del singolo gruppo\n", + " \n", + " average_threshold = np.mean([x[1] for x in test_results])\n", + " \n", + " return hazard, average_threshold" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "9dec052f", + "metadata": {}, + "outputs": [], + "source": [ + "def risk_function(test_hazards, average_thresholds):\n", + " # test_hazards = [list_of_hazards]\n", + " # average_thresholds = [mean(thresholds_of_test1), mean(thresholds_of_a_test2), ...], \n", + " # needed if automatic threshold is used\n", + " risk = 0\n", + " for hazard, threshold in zip(test_hazards, average_thresholds):\n", + " risk += hazard * threshold\n", + " \n", + " risk = risk/len(test_hazards)**2\n", + " \n", + " return risk" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "a61a651d", + "metadata": {}, + "outputs": [], + "source": [ + "def risk_function_2(test_hazards, average_thresholds):\n", + " # test_hazards = [list_of_hazards]\n", + " # average_thresholds = [mean(thresholds_of_test1), mean(thresholds_of_a_test2), ...], \n", + " # needed if automatic threshold is used\n", + " risk = 0\n", + " for hazard, threshold in zip(test_hazards, average_thresholds):\n", + " risk += hazard # tolto threshold\n", + " \n", + " risk = risk/len(test_hazards)**2\n", + " \n", + " return risk" + ] + }, + { + "cell_type": "markdown", + "id": "0e6e5723", + "metadata": {}, + "source": [ + "### Test 1: TVD, A1=high" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "38346302", + "metadata": {}, + "outputs": [], + "source": [ + "bd_1 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"high\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "ebde5b3d", + "metadata": {}, + "outputs": [], + "source": [ + "overall_1 = bd_1.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "9dc1af6e", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_1 = bd_1.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "e4ad51ba", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_1, average_threshold_1 = hazard_function(\n", + " overall_1, \n", + " conditioned_1, \n", + " df_with_predictions.shape[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "ec7f74f2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.09976465885178575" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hazard_test_1" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "cbf707be", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_1_2, average_threshold_1_2 = hazard_function_2(\n", + " overall_1, \n", + " conditioned_1, \n", + " df_with_predictions.shape[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "3ecfd390", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0016526941966088404" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hazard_test_1_2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e4aa9c2", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49f2d0fe", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ae31dc3", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "55e07a3c", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "e7914be4", + "metadata": {}, + "source": [ + "### Test 2 (TVD, low)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "e8377772", + "metadata": {}, + "outputs": [], + "source": [ + "bd_2 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"low\")" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "14e80b7e", + "metadata": {}, + "outputs": [], + "source": [ + "overall_2 = bd_2.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "468b603a", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_2 = bd_2.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "4016a74d", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_2, average_threshold_2 = hazard_function(\n", + " overall_2, \n", + " conditioned_2, \n", + " df_with_predictions.shape[0])" + ] + }, + { + "cell_type": "markdown", + "id": "847b9871", + "metadata": {}, + "source": [ + "### Test 3 (JS, high)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "e8ce1a46", + "metadata": {}, + "outputs": [], + "source": [ + "bd_3 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"high\")" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "5817e2d8", + "metadata": {}, + "outputs": [], + "source": [ + "overall_3 = bd_3.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "ff84ad8a", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_3 = bd_3.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "1043e2b1", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_3, average_threshold_3 = hazard_function(\n", + " overall_3, \n", + " conditioned_3, \n", + " df_with_predictions.shape[0])" + ] + }, + { + "cell_type": "markdown", + "id": "e65d63c0", + "metadata": {}, + "source": [ + "### Test 4 (JS, low)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "8bd6ad0f", + "metadata": {}, + "outputs": [], + "source": [ + "bd_4 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"low\")" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "f35b30be", + "metadata": {}, + "outputs": [], + "source": [ + "overall_4 = bd_4.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "3ba5c71c", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_4 = bd_4.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "b11aedbb", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_4, average_threshold_4 = hazard_function(\n", + " overall_4, \n", + " conditioned_4, \n", + " df_with_predictions.shape[0])" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "21c1a238", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(0.0011441803173238346, True, 0.038868585412256317, None)" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "overall_4" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "cf25ff2c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'x3_education==1': (3119,\n", + " 0.000889500656873715,\n", + " True,\n", + " 0.03895143959289674,\n", + " None),\n", + " 'x3_education==3': (1499,\n", + " 0.0015440397130407938,\n", + " True,\n", + " 0.03904057062398841,\n", + " None),\n", + " 'x3_education==2': (4250,\n", + " 0.0014069427700605507,\n", + " True,\n", + " 0.038922567122490655,\n", + " None),\n", + " 'x3_education==4': (40, 0.0, True, 0.04052878118384472, None),\n", + " 'x3_education==5': (75, 0.01773188348797698, True, 0.04004903810567666, None),\n", + " 'x3_education==6': (14, None, 'Not enough observations'),\n", + " 'x3_education==0': (3, None, 'Not enough observations'),\n", + " 'x4_marriage==1': (4065,\n", + " 0.0006622420845844328,\n", + " True,\n", + " 0.03892645023759367,\n", + " None),\n", + " 'x4_marriage==2': (4822,\n", + " 0.0017816477735895428,\n", + " True,\n", + " 0.03891200891721621,\n", + " None),\n", + " 'x4_marriage==3': (95, 0.005139203671928956, True, 0.0399042256460958, None),\n", + " 'x4_marriage==0': (18, None, 'Not enough observations'),\n", + " 'age_buckets==3': (2727,\n", + " 0.0005520467561810636,\n", + " True,\n", + " 0.038965431871108035,\n", + " None),\n", + " 'age_buckets==1': (2895,\n", + " 0.00014080595312827762,\n", + " True,\n", + " 0.03895908758112406,\n", + " None),\n", + " 'age_buckets==2': (3378,\n", + " 0.004642843764858481,\n", + " True,\n", + " 0.03894356315834885,\n", + " None),\n", + " 'x3_education==1 & x4_marriage==1': (1106,\n", + " 0.0013808097053743882,\n", + " True,\n", + " 0.0390882789383699,\n", + " None),\n", + " 'x3_education==1 & x4_marriage==2': (2002,\n", + " 0.0007714976131269403,\n", + " True,\n", + " 0.03900143196290057,\n", + " None),\n", + " 'x3_education==1 & x4_marriage==3': (10, None, 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==0': (1, None, 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==1': (842,\n", + " 0.0013293644451187769,\n", + " True,\n", + " 0.03913770060319752,\n", + " None),\n", + " 'x3_education==3 & x4_marriage==2': (616,\n", + " 0.0026766502047438972,\n", + " True,\n", + " 0.039203275417264274,\n", + " None),\n", + " 'x3_education==3 & x4_marriage==3': (26, None, 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==0': (15, None, 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==1': (2047,\n", + " 0.0008843782698063716,\n", + " True,\n", + " 0.038998652941457684,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==2': (2145,\n", + " 0.0020037880399754724,\n", + " True,\n", + " 0.038992906353361736,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==3': (56,\n", + " 0.0034056180121872144,\n", + " True,\n", + " 0.04025334448575739,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==0': (2, None, 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==1': (17, None, 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==2': (21, None, 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==3': (2, None, 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==0': (0, None, 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==1': (45,\n", + " 0.016319772563106846,\n", + " True,\n", + " 0.040427050983124845,\n", + " None),\n", + " 'x3_education==5 & x4_marriage==2': (29, None, 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==3': (1, None, 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==0': (0, None, 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==1': (7, None, 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==2': (7, None, 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==3': (0, None, 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==0': (0, None, 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==1': (1, None, 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==2': (2, None, 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==3': (0, None, 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==0': (0, None, 'Not enough observations'),\n", + " 'x3_education==1 & age_buckets==3': (710,\n", + " 9.289286910588404e-05,\n", + " True,\n", + " 0.039172204976585454,\n", + " None),\n", + " 'x3_education==1 & age_buckets==1': (1070,\n", + " 9.344831622309132e-05,\n", + " True,\n", + " 0.03909392253529011,\n", + " None),\n", + " 'x3_education==1 & age_buckets==2': (1339,\n", + " 0.003380171689433621,\n", + " True,\n", + " 0.03905744131846861,\n", + " None),\n", + " 'x3_education==3 & age_buckets==3': (783,\n", + " 0.002279727387873382,\n", + " True,\n", + " 0.039152042200564174,\n", + " None),\n", + " 'x3_education==3 & age_buckets==1': (281,\n", + " 0.0028387729486277547,\n", + " True,\n", + " 0.039421118734555886,\n", + " None),\n", + " 'x3_education==3 & age_buckets==2': (435,\n", + " 0.007446428652865581,\n", + " True,\n", + " 0.03928939621417106,\n", + " None),\n", + " 'x3_education==2 & age_buckets==3': (1180,\n", + " 0.0004958039568485653,\n", + " True,\n", + " 0.03907750016172852,\n", + " None),\n", + " 'x3_education==2 & age_buckets==1': (1502,\n", + " 0.000498442393993108,\n", + " True,\n", + " 0.0390402802952325,\n", + " None),\n", + " 'x3_education==2 & age_buckets==2': (1568,\n", + " 0.005620102489719185,\n", + " True,\n", + " 0.039034105403155314,\n", + " None),\n", + " 'x3_education==4 & age_buckets==3': (13, None, 'Not enough observations'),\n", + " 'x3_education==4 & age_buckets==1': (15, None, 'Not enough observations'),\n", + " 'x3_education==4 & age_buckets==2': (12, None, 'Not enough observations'),\n", + " 'x3_education==5 & age_buckets==3': (28, None, 'Not enough observations'),\n", + " 'x3_education==5 & age_buckets==1': (26, None, 'Not enough observations'),\n", + " 'x3_education==5 & age_buckets==2': (21, None, 'Not enough observations'),\n", + " 'x3_education==6 & age_buckets==3': (12, None, 'Not enough observations'),\n", + " 'x3_education==6 & age_buckets==1': (1, None, 'Not enough observations'),\n", + " 'x3_education==6 & age_buckets==2': (1, None, 'Not enough observations'),\n", + " 'x3_education==0 & age_buckets==3': (1, None, 'Not enough observations'),\n", + " 'x3_education==0 & age_buckets==1': (0, None, 'Not enough observations'),\n", + " 'x3_education==0 & age_buckets==2': (2, None, 'Not enough observations'),\n", + " 'x4_marriage==1 & age_buckets==3': (1973,\n", + " 0.0005954671163637724,\n", + " True,\n", + " 0.03900327304970935,\n", + " None),\n", + " 'x4_marriage==1 & age_buckets==1': (433,\n", + " 0.0006050564306400878,\n", + " True,\n", + " 0.03929064049774874,\n", + " None),\n", + " 'x4_marriage==1 & age_buckets==2': (1659,\n", + " 0.0025308859076596394,\n", + " True,\n", + " 0.039026203596578886,\n", + " None),\n", + " 'x4_marriage==2 & age_buckets==3': (682,\n", + " 0.000984116705666417,\n", + " True,\n", + " 0.03918078476435046,\n", + " None),\n", + " 'x4_marriage==2 & age_buckets==1': (2450,\n", + " 0.0004679756788383263,\n", + " True,\n", + " 0.038977284322524244,\n", + " None),\n", + " 'x4_marriage==2 & age_buckets==2': (1690,\n", + " 0.008770217406302681,\n", + " True,\n", + " 0.03902365864366842,\n", + " None),\n", + " 'x4_marriage==3 & age_buckets==3': (67,\n", + " 0.006048351225986506,\n", + " True,\n", + " 0.04012440624900843,\n", + " None),\n", + " 'x4_marriage==3 & age_buckets==1': (9, None, 'Not enough observations'),\n", + " 'x4_marriage==3 & age_buckets==2': (19, None, 'Not enough observations'),\n", + " 'x4_marriage==0 & age_buckets==3': (5, None, 'Not enough observations'),\n", + " 'x4_marriage==0 & age_buckets==1': (3, None, 'Not enough observations'),\n", + " 'x4_marriage==0 & age_buckets==2': (10, None, 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==1 & age_buckets==3': (530,\n", + " 0.0016115417796606346,\n", + " True,\n", + " 0.03923866877310845,\n", + " None),\n", + " 'x3_education==1 & x4_marriage==1 & age_buckets==1': (57,\n", + " 0.0006475595413858937,\n", + " True,\n", + " 0.040240098901698176,\n", + " None),\n", + " 'x3_education==1 & x4_marriage==1 & age_buckets==2': (519,\n", + " 0.00026135130212967203,\n", + " True,\n", + " 0.039243820191469415,\n", + " None),\n", + " 'x3_education==1 & x4_marriage==2 & age_buckets==3': (174,\n", + " 0.0032975398163250617,\n", + " True,\n", + " 0.039602860299026266,\n", + " None),\n", + " 'x3_education==1 & x4_marriage==2 & age_buckets==1': (1013,\n", + " 7.255783873653612e-05,\n", + " True,\n", + " 0.039103466125778766,\n", + " None),\n", + " 'x3_education==1 & x4_marriage==2 & age_buckets==2': (815,\n", + " 0.0055297298572293775,\n", + " True,\n", + " 0.039144070312308536,\n", + " None),\n", + " 'x3_education==1 & x4_marriage==3 & age_buckets==3': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==3 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==3 & age_buckets==2': (4,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==0 & age_buckets==2': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==1 & age_buckets==3': (540,\n", + " 0.0016661560238569815,\n", + " True,\n", + " 0.039234122918275924,\n", + " None),\n", + " 'x3_education==3 & x4_marriage==1 & age_buckets==1': (66,\n", + " 0.001641687659141143,\n", + " True,\n", + " 0.040134779273517496,\n", + " None),\n", + " 'x3_education==3 & x4_marriage==1 & age_buckets==2': (236,\n", + " 0.0031946627324049887,\n", + " True,\n", + " 0.03948231262426713,\n", + " None),\n", + " 'x3_education==3 & x4_marriage==2 & age_buckets==3': (215,\n", + " 0.006229793987585709,\n", + " True,\n", + " 0.039517243631904286,\n", + " None),\n", + " 'x3_education==3 & x4_marriage==2 & age_buckets==1': (212,\n", + " 0.0018314701557554697,\n", + " True,\n", + " 0.039522653172211375,\n", + " None),\n", + " 'x3_education==3 & x4_marriage==2 & age_buckets==2': (189,\n", + " 0.022452053043175157,\n", + " True,\n", + " 0.03956831708838497,\n", + " None),\n", + " 'x3_education==3 & x4_marriage==3 & age_buckets==3': (23,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==3 & age_buckets==1': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==3 & age_buckets==2': (2,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==0 & age_buckets==3': (5,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==0 & age_buckets==1': (2,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==0 & age_buckets==2': (8,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==1 & age_buckets==3': (865,\n", + " 0.00035057107813314626,\n", + " True,\n", + " 0.0391325114755164,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==1 & age_buckets==1': (298,\n", + " 0.0002290790469398784,\n", + " True,\n", + " 0.03940169500215893,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==1 & age_buckets==2': (884,\n", + " 0.005110244605296763,\n", + " True,\n", + " 0.039128378446622925,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==2 & age_buckets==3': (278,\n", + " 0.0019505471745487094,\n", + " True,\n", + " 0.039424730161892074,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==2 & age_buckets==1': (1196,\n", + " 0.0009740553778556391,\n", + " True,\n", + " 0.039075302149231016,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==2 & age_buckets==2': (671,\n", + " 0.008619822290895059,\n", + " True,\n", + " 0.039184301433021235,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==3 & age_buckets==3': (37,\n", + " 0.0032043535726546716,\n", + " True,\n", + " 0.04059948860718527,\n", + " None),\n", + " 'x3_education==2 & x4_marriage==3 & age_buckets==1': (7,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==3 & age_buckets==2': (12,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==0 & age_buckets==1': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==0 & age_buckets==2': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==1 & age_buckets==3': (9,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==1 & age_buckets==1': (2,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==1 & age_buckets==2': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==2 & age_buckets==3': (3,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==2 & age_buckets==1': (12,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==2 & age_buckets==2': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==3 & age_buckets==3': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==3 & age_buckets==1': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==3 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==0 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==1 & age_buckets==3': (22,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==1 & age_buckets==1': (10,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==1 & age_buckets==2': (13,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==2 & age_buckets==3': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==2 & age_buckets==1': (16,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==2 & age_buckets==2': (7,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==3 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==3 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==3 & age_buckets==2': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==0 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==1 & age_buckets==3': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==1 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==1 & age_buckets==2': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==2 & age_buckets==3': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==2 & age_buckets==1': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==2 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==3 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==3 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==3 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==0 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==1 & age_buckets==3': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==1 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==1 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==2 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==2 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==2 & age_buckets==2': (2,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==3 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==3 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==3 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==0 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations')}" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conditioned_4" + ] + }, + { + "cell_type": "markdown", + "id": "6b08c2f2", + "metadata": {}, + "source": [ + "## Risk results" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "0c8805e1", + "metadata": {}, + "outputs": [], + "source": [ + "hazards = [hazard_test_1, hazard_test_2, hazard_test_3, hazard_test_4]\n", + "average_thresholds = [average_threshold_1, average_threshold_2, average_threshold_3, average_threshold_4]" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "df958149", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.00015458111237839916" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "risk_function(hazards, average_thresholds)" + ] + }, + { + "cell_type": "markdown", + "id": "811da932", + "metadata": {}, + "source": [ + "# Experiments with 3 models" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "3022aa0b", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"./trained_model_for_testing/RF_12_200.pkl\", \"rb\") as file:\n", + " classifier_1 = load(file)\n", + " \n", + "with open(\"./trained_model_for_testing/RF_37_10.pkl\", \"rb\") as file:\n", + " classifier_2 = load(file)\n", + " \n", + "with open(\"./trained_model_for_testing/Tree_depth2.pkl\", \"rb\") as file:\n", + " classifier_3 = load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "b985b114", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_prob_1 = classifier_1.predict_proba(X_test_ohe)\n", + "predicted_values_1 = classifier_1.predict(X_test_ohe)\n", + "df_with_predictions_1 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_1)], axis=1).rename(columns={0:\"predictions\"})\n", + "\n", + "predicted_prob_2 = classifier_2.predict_proba(X_test_ohe)\n", + "predicted_values_2 = classifier_2.predict(X_test_ohe)\n", + "df_with_predictions_2 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_2)], axis=1).rename(columns={0:\"predictions\"})\n", + "\n", + "predicted_prob_3 = classifier_3.predict_proba(X_test_ohe)\n", + "predicted_values_3 = classifier_3.predict(X_test_ohe)\n", + "df_with_predictions_3 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_3)], axis=1).rename(columns={0:\"predictions\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "23ba3a67", + "metadata": {}, + "outputs": [], + "source": [ + "def test_model(data_frame):\n", + " ### Test 1: TVD, A1=high\n", + "\n", + " bd_1 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"high\")\n", + "\n", + " overall_1 = bd_1.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_1 = bd_1.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_1, average_threshold_1 = hazard_function(\n", + " overall_1, \n", + " conditioned_1, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 1 (TVD, A1=high) hazard: \", hazard_test_1)\n", + "\n", + " ### Test 2 (TVD, low)\n", + "\n", + " bd_2 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"low\")\n", + "\n", + " overall_2 = bd_2.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_2 = bd_2.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_2, average_threshold_2 = hazard_function(\n", + " overall_2, \n", + " conditioned_2, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 2 (TVD, A1=low) hazard: \", hazard_test_2)\n", + "\n", + " ### Test 3 (JS, high)\n", + "\n", + " bd_3 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"high\")\n", + "\n", + " overall_3 = bd_3.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_3 = bd_3.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_3, average_threshold_3 = hazard_function(\n", + " overall_3, \n", + " conditioned_3, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 3 (JS, A1=high) hazard: \", hazard_test_3)\n", + "\n", + " ### Test 4 (JS, low)\n", + "\n", + " bd_4 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"low\")\n", + "\n", + " overall_4 = bd_4.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_4 = bd_4.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_4, average_threshold_4 = hazard_function(\n", + " overall_4, \n", + " conditioned_4, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 4 (JS, A1=low) hazard: \", hazard_test_4)\n", + " \n", + " hazards = [hazard_test_1, hazard_test_2, hazard_test_3, hazard_test_4]\n", + " average_thresholds = [average_threshold_1, \n", + " average_threshold_2, average_threshold_3, average_threshold_4]\n", + " \n", + " return risk_function(hazards, average_thresholds)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "7f9c5d36", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test 1 (TVD, A1=high) hazard: 0.09976465885178575\n", + "Test 2 (TVD, A1=low) hazard: 0.02015304845287825\n", + "Test 3 (JS, A1=high) hazard: 0.00011458216656976323\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_12_200: 0.00015458111237839916\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.09085147869902101\n", + "Test 2 (TVD, A1=low) hazard: 0.014801760181546463\n", + "Test 3 (JS, A1=high) hazard: 1.52371151916934e-06\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_37_10: 0.00013193466737245095\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.03355105791241006\n", + "Test 2 (TVD, A1=low) hazard: 0.006384298991373367\n", + "Test 3 (JS, A1=high) hazard: 0.00014383137973982362\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model Tree_depth2: 5.113018082906323e-05\n", + "\n", + "\n" + ] + } + ], + "source": [ + "for model, df in zip([\"RF_12_200\", \"RF_37_10\", \"Tree_depth2\"],\n", + " [df_with_predictions_1, df_with_predictions_2, df_with_predictions_3]):\n", + " print(f\"Overall risk measure for model {model}: \", test_model(df))\n", + " print(\"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6f6f9ae", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6dad0e13", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dc7a0765", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "ab6c0a6a", + "metadata": {}, + "outputs": [], + "source": [ + "def test_model_2(data_frame):\n", + " ### Test 1: TVD, A1=high\n", + "\n", + " bd_1 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"high\")\n", + "\n", + " overall_1 = bd_1.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_1 = bd_1.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_1, average_threshold_1 = hazard_function_2(\n", + " overall_1, \n", + " conditioned_1, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 1 (TVD, A1=high) hazard: \", hazard_test_1)\n", + "\n", + " ### Test 2 (TVD, low)\n", + "\n", + " bd_2 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"low\")\n", + "\n", + " overall_2 = bd_2.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_2 = bd_2.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_2, average_threshold_2 = hazard_function_2(\n", + " overall_2, \n", + " conditioned_2, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 2 (TVD, A1=low) hazard: \", hazard_test_2)\n", + "\n", + " ### Test 3 (JS, high)\n", + "\n", + " bd_3 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"high\")\n", + "\n", + " overall_3 = bd_3.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_3 = bd_3.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_3, average_threshold_3 = hazard_function_2(\n", + " overall_3, \n", + " conditioned_3, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 3 (JS, A1=high) hazard: \", hazard_test_3)\n", + "\n", + " ### Test 4 (JS, low)\n", + "\n", + " bd_4 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"low\")\n", + "\n", + " overall_4 = bd_4.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_4 = bd_4.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_4, average_threshold_4 = hazard_function_2(\n", + " overall_4, \n", + " conditioned_4, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 4 (JS, A1=low) hazard: \", hazard_test_4)\n", + " \n", + " hazards = [hazard_test_1, hazard_test_2, hazard_test_3, hazard_test_4]\n", + " average_thresholds = [average_threshold_1, \n", + " average_threshold_2, average_threshold_3, average_threshold_4]\n", + " \n", + " return risk_function_2(hazards, average_thresholds)" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "9626cff1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test 1 (TVD, A1=high) hazard: 0.0016526941966088404\n", + "Test 2 (TVD, A1=low) hazard: 0.0007892524565281126\n", + "Test 3 (JS, A1=high) hazard: 1.956457231838417e-06\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_12_200: 0.00015274394439804945\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.0015049775936835396\n", + "Test 2 (TVD, A1=low) hazard: 0.0005801440913963854\n", + "Test 3 (JS, A1=high) hazard: 2.6739671511961216e-08\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_37_10: 0.0001303217765469648\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.0005595555272103964\n", + "Test 2 (TVD, A1=low) hazard: 0.00025096748221272835\n", + "Test 3 (JS, A1=high) hazard: 2.4731412590394615e-06\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model Tree_depth2: 5.081225941763526e-05\n", + "\n", + "\n" + ] + } + ], + "source": [ + "for model, df in zip([\"RF_12_200\", \"RF_37_10\", \"Tree_depth2\"],\n", + " [df_with_predictions_1, df_with_predictions_2, df_with_predictions_3]):\n", + " print(f\"Overall risk measure for model {model}: \", test_model_2(df))\n", + " print(\"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "67c01cb1", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test 1 (TVD, A1=high) hazard: 0.09976465885178575\n", + "Test 2 (TVD, A1=low) hazard: 0.02015304845287825\n", + "Test 3 (JS, A1=high) hazard: 0.00011458216656976323\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_12_200: 0.00015458111237839916\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.09085147869902101\n", + "Test 2 (TVD, A1=low) hazard: 0.014801760181546463\n", + "Test 3 (JS, A1=high) hazard: 1.52371151916934e-06\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_37_10: 0.00013193466737245095\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.03355105791241006\n", + "Test 2 (TVD, A1=low) hazard: 0.006384298991373367\n", + "Test 3 (JS, A1=high) hazard: 0.00014383137973982362\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model Tree_depth2: 5.113018082906323e-05\n", + "\n", + "\n" + ] + } + ], + "source": [ + "for model, df in zip([\"RF_12_200\", \"RF_37_10\", \"Tree_depth2\"],\n", + " [df_with_predictions_1, df_with_predictions_2, df_with_predictions_3]):\n", + " print(f\"Overall risk measure for model {model}: \", test_model(df))\n", + " print(\"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7d0a8bc0", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "93a740fc", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3d508927", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "23ed8452", + "metadata": {}, + "outputs": [], + "source": [ + "bd_ref = FreqVsRefBiasDetector()" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "bc060445", + "metadata": {}, + "outputs": [], + "source": [ + "male_0_ref = 55/100\n", + "male_1_ref = 45/100\n", + "\n", + "female_0_ref = 50/100\n", + "female_1_ref = 50/100\n", + "\n", + "ref_distribution = [np.array([female_0_ref, female_1_ref]), np.array([male_0_ref, male_1_ref])]" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "4d38d0d6", + "metadata": {}, + "outputs": [], + "source": [ + "overall_ref = bd_ref.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " #threshold=0.1,\n", + " reference_distribution=ref_distribution\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "eb083e91", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([0.3708341585642676, 0.3668290639264449],\n", + " [False, False],\n", + " 0.016368585412256314)" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "overall_ref" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "7f8a877e", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_ref = bd_ref.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables,\n", + " #threshold=0.1,\n", + " min_obs_per_group=30,\n", + " reference_distribution=ref_distribution)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "ca87efbd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'x3_education==1': (3119,\n", + " [0.4620223006815293, 0.456287468022177],\n", + " [False, False],\n", + " 0.016451439592896744),\n", + " 'x3_education==3': (1499,\n", + " [0.30004054728107643, 0.301920000109016],\n", + " [False, False],\n", + " 0.016540570623988414),\n", + " 'x3_education==2': (4250,\n", + " [0.3297513070249223, 0.32991040581610154],\n", + " [False, False],\n", + " 0.016422567122490656),\n", + " 'x3_education==4': (40, [1.0, 1.0], [False, False], 0.01802878118384471),\n", + " 'x3_education==5': (75,\n", + " [0.45277540525442184, 0.6135760511412283],\n", + " [False, False],\n", + " 0.017549038105676658),\n", + " 'x3_education==6': (14, None, 'Not enough observations'),\n", + " 'x3_education==0': (3, None, 'Not enough observations'),\n", + " 'x4_marriage==1': (4065,\n", + " [0.376452060901446, 0.35992113661821357],\n", + " [False, False],\n", + " 0.016426450237593673),\n", + " 'x4_marriage==2': (4822,\n", + " [0.36513728387900557, 0.3741329246698629],\n", + " [False, False],\n", + " 0.01641200891721621),\n", + " 'x4_marriage==3': (95,\n", + " [0.44397106958324817, 0.2777694169405729],\n", + " [False, False],\n", + " 0.017404225646095797),\n", + " 'x4_marriage==0': (18, None, 'Not enough observations'),\n", + " 'age_buckets==3': (2727,\n", + " [0.36859563815725926, 0.3482206719343247],\n", + " [False, False],\n", + " 0.016465431871108036),\n", + " 'age_buckets==1': (2895,\n", + " [0.3630201449190119, 0.3242010905897603],\n", + " [False, False],\n", + " 0.016459087581124063),\n", + " 'age_buckets==2': (3378,\n", + " [0.3782484161589076, 0.42896787633099487],\n", + " [False, False],\n", + " 0.01644356315834885),\n", + " 'x3_education==1 & x4_marriage==1': (1106,\n", + " [0.48192521938779376, 0.4889748520001793],\n", + " [False, False],\n", + " 0.0165882789383699),\n", + " 'x3_education==1 & x4_marriage==2': (2002,\n", + " [0.4492546144758617, 0.4395444808863672],\n", + " [False, False],\n", + " 0.016501431962900565),\n", + " 'x3_education==1 & x4_marriage==3': (10, None, 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==0': (1, None, 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==1': (842,\n", + " [0.2850405151436606, 0.28204816346821415],\n", + " [False, False],\n", + " 0.016637700603197515),\n", + " 'x3_education==3 & x4_marriage==2': (616,\n", + " [0.31017434029145563, 0.3318910910270282],\n", + " [False, False],\n", + " 0.016703275417264275),\n", + " 'x3_education==3 & x4_marriage==3': (26, None, 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==0': (15, None, 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==1': (2047,\n", + " [0.3470522934317195, 0.33566342753392664],\n", + " [False, False],\n", + " 0.016498652941457678),\n", + " 'x3_education==2 & x4_marriage==2': (2145,\n", + " [0.3149338370490783, 0.32590111074043315],\n", + " [False, False],\n", + " 0.016492906353361734),\n", + " 'x3_education==2 & x4_marriage==3': (56,\n", + " [0.40117071177669594, 0.2547990572571768],\n", + " [False, False],\n", + " 0.017753344485757386),\n", + " 'x3_education==2 & x4_marriage==0': (2, None, 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==1': (17, None, 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==2': (21, None, 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==3': (2, None, 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==0': (0, None, 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==1': (45,\n", + " [1.0, 0.5580368406063803],\n", + " [False, False],\n", + " 0.017927050983124842),\n", + " 'x3_education==5 & x4_marriage==2': (29, None, 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==3': (1, None, 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==0': (0, None, 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==1': (7, None, 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==2': (7, None, 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==3': (0, None, 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==0': (0, None, 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==1': (1, None, 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==2': (2, None, 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==3': (0, None, 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==0': (0, None, 'Not enough observations'),\n", + " 'x3_education==1 & age_buckets==3': (710,\n", + " [0.44173964106929964, 0.4029550549844849],\n", + " [False, False],\n", + " 0.016672204976585454),\n", + " 'x3_education==1 & age_buckets==1': (1070,\n", + " [0.469201641275132, 0.4320928423736369],\n", + " [False, False],\n", + " 0.016593922535290104),\n", + " 'x3_education==1 & age_buckets==2': (1339,\n", + " [0.47059578748144526, 0.5101121945730993],\n", + " [False, False],\n", + " 0.01655744131846861),\n", + " 'x3_education==3 & age_buckets==3': (783,\n", + " [0.2861974650786553, 0.30070274118258955],\n", + " [False, False],\n", + " 0.016652042200564175),\n", + " 'x3_education==3 & age_buckets==1': (281,\n", + " [0.3694620990998062, 0.2310031282303594],\n", + " [False, False],\n", + " 0.01692111873455588),\n", + " 'x3_education==3 & age_buckets==2': (435,\n", + " [0.2828094536399566, 0.35775924637179646],\n", + " [False, False],\n", + " 0.016789396214171054),\n", + " 'x3_education==2 & age_buckets==3': (1180,\n", + " [0.3694620990998062, 0.3471884692568875],\n", + " [False, False],\n", + " 0.016577500161728514),\n", + " 'x3_education==2 & age_buckets==1': (1502,\n", + " [0.29317998898179864, 0.2687271665830179],\n", + " [False, False],\n", + " 0.0165402802952325),\n", + " 'x3_education==2 & age_buckets==2': (1568,\n", + " [0.33068530906480187, 0.39009392224338335],\n", + " [False, False],\n", + " 0.01653410540315531),\n", + " 'x3_education==4 & age_buckets==3': (13, None, 'Not enough observations'),\n", + " 'x3_education==4 & age_buckets==1': (15, None, 'Not enough observations'),\n", + " 'x3_education==4 & age_buckets==2': (12, None, 'Not enough observations'),\n", + " 'x3_education==5 & age_buckets==3': (28, None, 'Not enough observations'),\n", + " 'x3_education==5 & age_buckets==1': (26, None, 'Not enough observations'),\n", + " 'x3_education==5 & age_buckets==2': (21, None, 'Not enough observations'),\n", + " 'x3_education==6 & age_buckets==3': (12, None, 'Not enough observations'),\n", + " 'x3_education==6 & age_buckets==1': (1, None, 'Not enough observations'),\n", + " 'x3_education==6 & age_buckets==2': (1, None, 'Not enough observations'),\n", + " 'x3_education==0 & age_buckets==3': (1, None, 'Not enough observations'),\n", + " 'x3_education==0 & age_buckets==1': (0, None, 'Not enough observations'),\n", + " 'x3_education==0 & age_buckets==2': (2, None, 'Not enough observations'),\n", + " 'x4_marriage==1 & age_buckets==3': (1973,\n", + " [0.379621655532961, 0.36112473512065624],\n", + " [False, False],\n", + " 0.016503273049709347),\n", + " 'x4_marriage==1 & age_buckets==1': (433,\n", + " [0.3529571445758697, 0.25770306238935237],\n", + " [False, False],\n", + " 0.016790640497748737),\n", + " 'x4_marriage==1 & age_buckets==2': (1659,\n", + " [0.37521311260533263, 0.39747610473967265],\n", + " [False, False],\n", + " 0.016526203596578883),\n", + " 'x4_marriage==2 & age_buckets==3': (682,\n", + " [0.33367457657786503, 0.3243599524588463],\n", + " [False, False],\n", + " 0.016680784764350462),\n", + " 'x4_marriage==2 & age_buckets==1': (2450,\n", + " [0.3628271322361155, 0.3393024156176122],\n", + " [False, False],\n", + " 0.01647728432252425),\n", + " 'x4_marriage==2 & age_buckets==2': (1690,\n", + " [0.3795673436649285, 0.47106904171590147],\n", + " [False, False],\n", + " 0.016523658643668417),\n", + " 'x4_marriage==3 & age_buckets==3': (67,\n", + " [0.40117071177669594, 0.22566287072110824],\n", + " [False, False],\n", + " 0.017624406249008434),\n", + " 'x4_marriage==3 & age_buckets==1': (9, None, 'Not enough observations'),\n", + " 'x4_marriage==3 & age_buckets==2': (19, None, 'Not enough observations'),\n", + " 'x4_marriage==0 & age_buckets==3': (5, None, 'Not enough observations'),\n", + " 'x4_marriage==0 & age_buckets==1': (3, None, 'Not enough observations'),\n", + " 'x4_marriage==0 & age_buckets==2': (10, None, 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==1 & age_buckets==3': (530,\n", + " [0.4425027716770654, 0.4519653039256851],\n", + " [False, False],\n", + " 0.01673866877310845),\n", + " 'x3_education==1 & x4_marriage==1 & age_buckets==1': (57,\n", + " [0.5113739208010888, 0.5019439948311757],\n", + " [False, False],\n", + " 0.017740098901698177),\n", + " 'x3_education==1 & x4_marriage==1 & age_buckets==2': (519,\n", + " [0.5414265059292653, 0.5196689353266379],\n", + " [False, False],\n", + " 0.016743820191469413),\n", + " 'x3_education==1 & x4_marriage==2 & age_buckets==3': (174,\n", + " [0.42949249559503866, 0.2849533828553775],\n", + " [False, False],\n", + " 0.017102860299026267),\n", + " 'x3_education==1 & x4_marriage==2 & age_buckets==1': (1013,\n", + " [0.46728611033129075, 0.42824428864825015],\n", + " [False, False],\n", + " 0.016603466125778767),\n", + " 'x3_education==1 & x4_marriage==2 & age_buckets==2': (815,\n", + " [0.43826868351871007, 0.5017685192835523],\n", + " [False, False],\n", + " 0.016644070312308534),\n", + " 'x3_education==1 & x4_marriage==3 & age_buckets==3': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==3 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==3 & age_buckets==2': (4,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==1 & x4_marriage==0 & age_buckets==2': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==1 & age_buckets==3': (540,\n", + " [0.29375755204621223, 0.2977854094815917],\n", + " [False, False],\n", + " 0.016734122918275925),\n", + " 'x3_education==3 & x4_marriage==1 & age_buckets==1': (66,\n", + " [0.2977520462199942, 0.18094766636572723],\n", + " [False, False],\n", + " 0.017634779273517497),\n", + " 'x3_education==3 & x4_marriage==1 & age_buckets==2': (236,\n", + " [0.2620627145731571, 0.2891593990185989],\n", + " [False, False],\n", + " 0.016982312624267134),\n", + " 'x3_education==3 & x4_marriage==2 & age_buckets==3': (215,\n", + " [0.2568716673225767, 0.31863017435611196],\n", + " [False, False],\n", + " 0.017017243631904284),\n", + " 'x3_education==3 & x4_marriage==2 & age_buckets==1': (212,\n", + " [0.3758755999451484, 0.25307084100179045],\n", + " [False, False],\n", + " 0.017022653172211376),\n", + " 'x3_education==3 & x4_marriage==2 & age_buckets==2': (189,\n", + " [0.2977520462199942, 0.4760688683527591],\n", + " [False, False],\n", + " 0.017068317088384972),\n", + " 'x3_education==3 & x4_marriage==3 & age_buckets==3': (23,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==3 & age_buckets==1': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==3 & age_buckets==2': (2,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==0 & age_buckets==3': (5,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==0 & age_buckets==1': (2,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==3 & x4_marriage==0 & age_buckets==2': (8,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==1 & age_buckets==3': (865,\n", + " [0.37992450338664374, 0.3524968775291666],\n", + " [False, False],\n", + " 0.0166325114755164),\n", + " 'x3_education==2 & x4_marriage==1 & age_buckets==1': (298,\n", + " [0.31473664010975755, 0.23391365140897302],\n", + " [False, False],\n", + " 0.016901695002158927),\n", + " 'x3_education==2 & x4_marriage==1 & age_buckets==2': (884,\n", + " [0.31690890667675464, 0.3701290466183629],\n", + " [False, False],\n", + " 0.016628378446622925),\n", + " 'x3_education==2 & x4_marriage==2 & age_buckets==3': (278,\n", + " [0.3398789491933295, 0.35090198280694873],\n", + " [False, False],\n", + " 0.016924730161892075),\n", + " 'x3_education==2 & x4_marriage==2 & age_buckets==1': (1196,\n", + " [0.2894603549750707, 0.27852237597110696],\n", + " [False, False],\n", + " 0.01657530214923101),\n", + " 'x3_education==2 & x4_marriage==2 & age_buckets==2': (671,\n", + " [0.34317261807623434, 0.4317080128171452],\n", + " [False, False],\n", + " 0.01668430143302123),\n", + " 'x3_education==2 & x4_marriage==3 & age_buckets==3': (37,\n", + " [0.35760339259412377, 0.21457646418892706],\n", + " [False, False],\n", + " 0.018099488607185268),\n", + " 'x3_education==2 & x4_marriage==3 & age_buckets==1': (7,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==3 & age_buckets==2': (12,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==0 & age_buckets==1': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==2 & x4_marriage==0 & age_buckets==2': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==1 & age_buckets==3': (9,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==1 & age_buckets==1': (2,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==1 & age_buckets==2': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==2 & age_buckets==3': (3,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==2 & age_buckets==1': (12,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==2 & age_buckets==2': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==3 & age_buckets==3': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==3 & age_buckets==1': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==3 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==4 & x4_marriage==0 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==1 & age_buckets==3': (22,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==1 & age_buckets==1': (10,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==1 & age_buckets==2': (13,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==2 & age_buckets==3': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==2 & age_buckets==1': (16,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==2 & age_buckets==2': (7,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==3 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==3 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==3 & age_buckets==2': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==5 & x4_marriage==0 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==1 & age_buckets==3': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==1 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==1 & age_buckets==2': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==2 & age_buckets==3': (6,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==2 & age_buckets==1': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==2 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==3 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==3 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==3 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==6 & x4_marriage==0 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==1 & age_buckets==3': (1,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==1 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==1 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==2 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==2 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==2 & age_buckets==2': (2,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==3 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==3 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==3 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==0 & age_buckets==3': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==0 & age_buckets==1': (0,\n", + " None,\n", + " 'Not enough observations'),\n", + " 'x3_education==0 & x4_marriage==0 & age_buckets==2': (0,\n", + " None,\n", + " 'Not enough observations')}" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "conditioned_ref" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "31101641", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO considerare i risultati nei sottogruppi come test indipendenti (fare ciclo for)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/RiskMeasure_experiments_3.ipynb b/notebooks/RiskMeasure_experiments_3.ipynb new file mode 100644 index 0000000..5f4447b --- /dev/null +++ b/notebooks/RiskMeasure_experiments_3.ipynb @@ -0,0 +1,906 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "0b134d6e", + "metadata": {}, + "outputs": [], + "source": [ + "import os, sys\n", + "dir2 = os.path.abspath('')\n", + "dir1 = os.path.dirname(dir2)\n", + "if not dir1 in sys.path: sys.path.append(dir1)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "77c1e269", + "metadata": {}, + "outputs": [], + "source": [ + "from brio.utils.Preprocessing import Preprocessing\n", + "from sklearn.model_selection import train_test_split\n", + "from pickle import dump, load\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "from brio.bias.FreqVsFreqBiasDetector import FreqVsFreqBiasDetector\n", + "from brio.bias.FreqVsRefBiasDetector import FreqVsRefBiasDetector" + ] + }, + { + "cell_type": "markdown", + "id": "68af6499", + "metadata": {}, + "source": [ + "## Importing Data and Trained Classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "66127e6c", + "metadata": {}, + "outputs": [], + "source": [ + "input_data_path = \"../data/raw_data/uci-default-of-credit-card/data/data.csv\"\n", + "local_path_save = '../data/mlflow_artifacts/'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bf0e3b01", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/davideposillipo/.pyenv/versions/3.10.9/envs/prova/lib/python3.10/site-packages/sklearn/base.py:329: UserWarning: Trying to unpickle estimator OneHotEncoder from version 1.2.1 when using version 1.0.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/modules/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n", + "/Users/davideposillipo/.pyenv/versions/3.10.9/envs/prova/lib/python3.10/site-packages/sklearn/base.py:329: UserWarning: Trying to unpickle estimator StandardScaler from version 1.2.1 when using version 1.0.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/modules/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "fitted_ohe = load(open(local_path_save + '_ohe.pkl', 'rb')) \n", + "fitted_scaler = load(open(local_path_save + '_scaler.pkl', 'rb'))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6646c312", + "metadata": {}, + "outputs": [], + "source": [ + "pp = Preprocessing(input_data_path, \"default\")\n", + "X, Y = pp.read_dataframe()\n", + "\n", + "X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size=0.3, random_state=420)\n", + "\n", + "X_test_ohe, _, _ = pp.preprocess_for_classification(df=X_test, \n", + " fit_ohe=True, \n", + " fitted_ohe=fitted_ohe,\n", + " perform_scaling=True,\n", + " fitted_scaler=fitted_scaler)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "ba010d39", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"./mlruns/1/1e4a0667c7a64cbe8c7b023410e5781c/artifacts/model/model.pkl\", \"rb\") as file:\n", + " classifier = load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "04cacf92", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_prob = classifier.predict_proba(X_test_ohe)\n", + "predicted_values = classifier.predict(X_test_ohe)" + ] + }, + { + "cell_type": "markdown", + "id": "01057c6d", + "metadata": {}, + "source": [ + "#### Definition of conditioning variables" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "d7e96a84", + "metadata": {}, + "outputs": [], + "source": [ + "def age_buckets(x):\n", + " if x < 30:\n", + " return 1\n", + " elif x < 40:\n", + " return 2\n", + " else:\n", + " return 3\n", + "\n", + "X_test['age_buckets'] = X.x5_age.apply(age_buckets)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c24a0c9c", + "metadata": {}, + "outputs": [], + "source": [ + "conditioning_variables = ['x3_education', 'x4_marriage', 'age_buckets']" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7950602d", + "metadata": {}, + "outputs": [], + "source": [ + "df_with_predictions = pd.concat(\n", + " [X_test.reset_index(drop=True), pd.Series(predicted_values)], axis=1).rename(columns={0:\"predictions\"})" + ] + }, + { + "cell_type": "markdown", + "id": "d6f80bfb", + "metadata": {}, + "source": [ + "## Hazard and risk functions" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "e6a1b053", + "metadata": {}, + "outputs": [], + "source": [ + "def as_list(x):\n", + " if type(x) is list:\n", + " return x\n", + " else:\n", + " return [x]" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "cf4062af", + "metadata": {}, + "outputs": [], + "source": [ + "def hazard_function(\n", + " overall_result, \n", + " conditioned_results, \n", + " tot_observations,\n", + " conditioning_variables,\n", + " weight_logic=\"group\"):\n", + " \n", + " #tot number features=conditioning + root (+1)\n", + " n_features_total = len(conditioning_variables) + 1\n", + " \n", + " hazard_overall = 0\n", + " # Iterating over each reference distribution, if available (FreqVsRef)\n", + " # In case of FreqVsFreq, there will be a single iteration\n", + " num_iterations = len(as_list(overall_result[0]))\n", + " for k in np.arange(0, num_iterations):\n", + " \n", + " # test result, threshold, num_samples, boolean, num_used_features\n", + " test_results = []\n", + " test_results.append((\n", + " as_list(overall_result[0])[k], \n", + " overall_result[2], \n", + " tot_observations, \n", + " as_list(overall_result[1])[k],\n", + " 1 #for the overall test, only 1 feature used, the root variable\n", + " ))\n", + "\n", + " for group_name, group in conditioned_results.items():\n", + " if (group[1] is not None):\n", + " test_results.append(\n", + " (\n", + " as_list(group[1])[k], #test result\n", + " group[3], #threshold\n", + " group[0], #num_samples\n", + " as_list(group[2])[k], #boolean\n", + " len(group_name.split(\"&\"))+1 #num_used_features, cond.+root\n", + " )\n", + " ) \n", + "\n", + " if weight_logic==\"group\":\n", + " #T_i in Risk Function document\n", + " weight_denominator = 0 \n", + " for line in test_results:\n", + " weight_denominator += n_features_total - line[4] + 1\n", + " elif weight_logic==\"individual\":\n", + " #S_i in Risk Function document\n", + " weight_denominator = np.sum([x[4] for x in test_results]) \n", + " else:\n", + " raise Exception('Only \"group\" or \"individual\" are allowed for parameter weight_logic')\n", + "\n", + "\n", + " hazard = 0\n", + " for line in test_results:\n", + " if weight_logic==\"group\":\n", + " c_info = n_features_total - line[4] + 1\n", + " weight = c_info/weight_denominator\n", + " elif weight_logic==\"individual\":\n", + " weight = line[4]/weight_denominator\n", + " else:\n", + " raise Exception('Only \"group\" or \"individual\" are allowed for parameter weight_logic')\n", + "\n", + " delta = 1 if line[3]==False else 0\n", + " q = line[2]/tot_observations\n", + " e = line[0] - line[1]\n", + " hazard += delta * weight * q * e * line[1]\n", + " \n", + " hazard_overall+= hazard\n", + " \n", + " return hazard_overall" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "d6e084dc", + "metadata": {}, + "outputs": [], + "source": [ + "def risk_function(test_hazards):\n", + " # test_hazards = [list_of_hazards]\n", + " \n", + " risk = np.sum(test_hazards)/len(test_hazards)**2\n", + " \n", + " return risk" + ] + }, + { + "cell_type": "markdown", + "id": "0e6e5723", + "metadata": {}, + "source": [ + "### Test 1: TVD, A1=high" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "38346302", + "metadata": {}, + "outputs": [], + "source": [ + "bd_1 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"high\")" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "ebde5b3d", + "metadata": {}, + "outputs": [], + "source": [ + "overall_1 = bd_1.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "9dc1af6e", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_1 = bd_1.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "e4ad51ba", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_1 = hazard_function(\n", + " overall_1, \n", + " conditioned_1, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "f24335e4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.662715426591436e-05" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hazard_test_1" + ] + }, + { + "cell_type": "markdown", + "id": "e7914be4", + "metadata": {}, + "source": [ + "### Test 2 (TVD, low)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "e8377772", + "metadata": {}, + "outputs": [], + "source": [ + "bd_2 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"low\")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "14e80b7e", + "metadata": {}, + "outputs": [], + "source": [ + "overall_2 = bd_2.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "468b603a", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_2 = bd_2.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "4016a74d", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_2 = hazard_function(\n", + " overall_2, \n", + " conditioned_2, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "markdown", + "id": "847b9871", + "metadata": {}, + "source": [ + "### Test 3 (JS, high)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "e8ce1a46", + "metadata": {}, + "outputs": [], + "source": [ + "bd_3 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"high\")" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "5817e2d8", + "metadata": {}, + "outputs": [], + "source": [ + "overall_3 = bd_3.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "ff84ad8a", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_3 = bd_3.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "1043e2b1", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_3 = hazard_function(\n", + " overall_3, \n", + " conditioned_3, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "markdown", + "id": "e65d63c0", + "metadata": {}, + "source": [ + "### Test 4 (JS, low)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "8bd6ad0f", + "metadata": {}, + "outputs": [], + "source": [ + "bd_4 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"low\")" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "f35b30be", + "metadata": {}, + "outputs": [], + "source": [ + "overall_4 = bd_4.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "3ba5c71c", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_4 = bd_4.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "b11aedbb", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_4 = hazard_function(\n", + " overall_4, \n", + " conditioned_4, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "markdown", + "id": "6b08c2f2", + "metadata": {}, + "source": [ + "## Risk results" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "0c8805e1", + "metadata": {}, + "outputs": [], + "source": [ + "hazards = [hazard_test_1, hazard_test_2, hazard_test_3, hazard_test_4]" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "df958149", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.1655148018808247e-06" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "risk_function(hazards)" + ] + }, + { + "cell_type": "markdown", + "id": "811da932", + "metadata": {}, + "source": [ + "# Experiments with 3 models" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "3022aa0b", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"./trained_model_for_testing/RF_12_200.pkl\", \"rb\") as file:\n", + " classifier_1 = load(file)\n", + " \n", + "with open(\"./trained_model_for_testing/RF_37_10.pkl\", \"rb\") as file:\n", + " classifier_2 = load(file)\n", + " \n", + "with open(\"./trained_model_for_testing/Tree_depth2.pkl\", \"rb\") as file:\n", + " classifier_3 = load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "b985b114", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_prob_1 = classifier_1.predict_proba(X_test_ohe)\n", + "predicted_values_1 = classifier_1.predict(X_test_ohe)\n", + "df_with_predictions_1 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_1)], axis=1).rename(columns={0:\"predictions\"})\n", + "\n", + "predicted_prob_2 = classifier_2.predict_proba(X_test_ohe)\n", + "predicted_values_2 = classifier_2.predict(X_test_ohe)\n", + "df_with_predictions_2 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_2)], axis=1).rename(columns={0:\"predictions\"})\n", + "\n", + "predicted_prob_3 = classifier_3.predict_proba(X_test_ohe)\n", + "predicted_values_3 = classifier_3.predict(X_test_ohe)\n", + "df_with_predictions_3 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_3)], axis=1).rename(columns={0:\"predictions\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "23ba3a67", + "metadata": {}, + "outputs": [], + "source": [ + "def test_model(data_frame):\n", + " ### Test 1: TVD, A1=high\n", + "\n", + " bd_1 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"high\")\n", + "\n", + " overall_1 = bd_1.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_1 = bd_1.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_1 = hazard_function(\n", + " overall_1, \n", + " conditioned_1, \n", + " data_frame.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")\n", + " \n", + " print(\"Test 1 (TVD, A1=high) hazard: \", hazard_test_1)\n", + "\n", + " ### Test 2 (TVD, low)\n", + "\n", + " bd_2 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"low\")\n", + "\n", + " overall_2 = bd_2.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_2 = bd_2.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_2 = hazard_function(\n", + " overall_2, \n", + " conditioned_2, \n", + " data_frame.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")\n", + " \n", + " print(\"Test 2 (TVD, A1=low) hazard: \", hazard_test_2)\n", + "\n", + " ### Test 3 (JS, high)\n", + "\n", + " bd_3 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"high\")\n", + "\n", + " overall_3 = bd_3.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_3 = bd_3.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_3 = hazard_function(\n", + " overall_3, \n", + " conditioned_3, \n", + " data_frame.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")\n", + " \n", + " print(\"Test 3 (JS, A1=high) hazard: \", hazard_test_3)\n", + "\n", + " ### Test 4 (JS, low)\n", + "\n", + " bd_4 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"low\")\n", + "\n", + " overall_4 = bd_4.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_4 = bd_4.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_4 = hazard_function(\n", + " overall_4, \n", + " conditioned_4, \n", + " data_frame.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")\n", + " \n", + " print(\"Test 4 (JS, A1=low) hazard: \", hazard_test_4)\n", + " \n", + " hazards = [hazard_test_1, hazard_test_2, hazard_test_3, hazard_test_4]\n", + " \n", + " return risk_function(hazards)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "7f9c5d36", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test 1 (TVD, A1=high) hazard: 3.662715426591436e-05\n", + "Test 2 (TVD, A1=low) hazard: 1.4001756250959011e-05\n", + "Test 3 (JS, A1=high) hazard: 1.932631321983019e-08\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_12_200: 3.1655148018808247e-06\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 3.231114243613055e-05\n", + "Test 2 (TVD, A1=low) hazard: 8.844513845377398e-06\n", + "Test 3 (JS, A1=high) hazard: 7.713366782296505e-10\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_37_10: 2.572276726136636e-06\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 1.0247396005717305e-05\n", + "Test 2 (TVD, A1=low) hazard: 3.7820077895012226e-06\n", + "Test 3 (JS, A1=high) hazard: 3.654431188743626e-08\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model Tree_depth2: 8.791217566941227e-07\n", + "\n", + "\n" + ] + } + ], + "source": [ + "for model, df in zip([\"RF_12_200\", \"RF_37_10\", \"Tree_depth2\"],\n", + " [df_with_predictions_1, df_with_predictions_2, df_with_predictions_3]):\n", + " print(f\"Overall risk measure for model {model}: \", test_model(df))\n", + " print(\"\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "6f0b3966", + "metadata": {}, + "source": [ + "## Freq Vs Ref" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "4b3771a0", + "metadata": {}, + "outputs": [], + "source": [ + "bd_ref = FreqVsRefBiasDetector()" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "24f7cf26", + "metadata": {}, + "outputs": [], + "source": [ + "male_0_ref = 55/100\n", + "male_1_ref = 45/100\n", + "\n", + "female_0_ref = 50/100\n", + "female_1_ref = 50/100\n", + "\n", + "ref_distribution = [np.array([female_0_ref, female_1_ref]), np.array([male_0_ref, male_1_ref])]" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "7dfb89a5", + "metadata": {}, + "outputs": [], + "source": [ + "overall_ref = bd_ref.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " #threshold=0.1,\n", + " reference_distribution=ref_distribution\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "a094a694", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_ref = bd_ref.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables,\n", + " #threshold=0.1,\n", + " min_obs_per_group=30,\n", + " reference_distribution=ref_distribution)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "b9aefa9b", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_ref = hazard_function(\n", + " overall_ref, \n", + " conditioned_ref, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "4f4a0f26", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0022374318004642693" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hazard_test_ref" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/RiskMeasure_experiments_4.ipynb b/notebooks/RiskMeasure_experiments_4.ipynb new file mode 100644 index 0000000..b27d7c1 --- /dev/null +++ b/notebooks/RiskMeasure_experiments_4.ipynb @@ -0,0 +1,821 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "aa617bce", + "metadata": {}, + "source": [ + "Replica of experiments_3, but using the RiskCalculator and HazardFromBiasDetectionCalculator classes" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "0b134d6e", + "metadata": {}, + "outputs": [], + "source": [ + "import os, sys\n", + "dir2 = os.path.abspath('')\n", + "dir1 = os.path.dirname(dir2)\n", + "if not dir1 in sys.path: sys.path.append(dir1)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "77c1e269", + "metadata": {}, + "outputs": [], + "source": [ + "from brio.utils.Preprocessing import Preprocessing\n", + "from sklearn.model_selection import train_test_split\n", + "from pickle import dump, load\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "from brio.bias.FreqVsFreqBiasDetector import FreqVsFreqBiasDetector\n", + "from brio.bias.FreqVsRefBiasDetector import FreqVsRefBiasDetector\n", + "from brio.risk.HazardFromBiasDetectionCalculator import HazardFromBiasDetectionCalculator\n", + "from brio.risk.RiskCalculator import RiskCalculator" + ] + }, + { + "cell_type": "markdown", + "id": "68af6499", + "metadata": {}, + "source": [ + "## Importing Data and Trained Classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "66127e6c", + "metadata": {}, + "outputs": [], + "source": [ + "input_data_path = \"../data/raw_data/uci-default-of-credit-card/data/data.csv\"\n", + "local_path_save = '../data/mlflow_artifacts/'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bf0e3b01", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/davideposillipo/.pyenv/versions/3.10.9/envs/prova/lib/python3.10/site-packages/sklearn/base.py:329: UserWarning: Trying to unpickle estimator OneHotEncoder from version 1.2.1 when using version 1.0.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/modules/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n", + "/Users/davideposillipo/.pyenv/versions/3.10.9/envs/prova/lib/python3.10/site-packages/sklearn/base.py:329: UserWarning: Trying to unpickle estimator StandardScaler from version 1.2.1 when using version 1.0.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/modules/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "fitted_ohe = load(open(local_path_save + '_ohe.pkl', 'rb')) \n", + "fitted_scaler = load(open(local_path_save + '_scaler.pkl', 'rb'))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6646c312", + "metadata": {}, + "outputs": [], + "source": [ + "pp = Preprocessing(input_data_path, \"default\")\n", + "X, Y = pp.read_dataframe()\n", + "\n", + "X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size=0.3, random_state=420)\n", + "\n", + "X_test_ohe, _, _ = pp.preprocess_for_classification(df=X_test, \n", + " fit_ohe=True, \n", + " fitted_ohe=fitted_ohe,\n", + " perform_scaling=True,\n", + " fitted_scaler=fitted_scaler)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "ba010d39", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"./mlruns/1/1e4a0667c7a64cbe8c7b023410e5781c/artifacts/model/model.pkl\", \"rb\") as file:\n", + " classifier = load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "04cacf92", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_prob = classifier.predict_proba(X_test_ohe)\n", + "predicted_values = classifier.predict(X_test_ohe)" + ] + }, + { + "cell_type": "markdown", + "id": "01057c6d", + "metadata": {}, + "source": [ + "#### Definition of conditioning variables" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "d7e96a84", + "metadata": {}, + "outputs": [], + "source": [ + "def age_buckets(x):\n", + " if x < 30:\n", + " return 1\n", + " elif x < 40:\n", + " return 2\n", + " else:\n", + " return 3\n", + "\n", + "X_test['age_buckets'] = X.x5_age.apply(age_buckets)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c24a0c9c", + "metadata": {}, + "outputs": [], + "source": [ + "conditioning_variables = ['x3_education', 'x4_marriage', 'age_buckets']" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7950602d", + "metadata": {}, + "outputs": [], + "source": [ + "df_with_predictions = pd.concat(\n", + " [X_test.reset_index(drop=True), pd.Series(predicted_values)], axis=1).rename(columns={0:\"predictions\"})" + ] + }, + { + "cell_type": "markdown", + "id": "f6f951a0", + "metadata": {}, + "source": [ + "## Testing Risk Calculator" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "0f3e064c", + "metadata": {}, + "outputs": [], + "source": [ + "rc = RiskCalculator()\n", + "hc = HazardFromBiasDetectionCalculator()" + ] + }, + { + "cell_type": "markdown", + "id": "0e6e5723", + "metadata": {}, + "source": [ + "### Test 1: TVD, A1=high" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "38346302", + "metadata": {}, + "outputs": [], + "source": [ + "bd_1 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"high\")" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "ebde5b3d", + "metadata": {}, + "outputs": [], + "source": [ + "overall_1 = bd_1.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "9dc1af6e", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_1 = bd_1.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "e4ad51ba", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_1 = hc.compute_hazard_from_freqvsfreq_or_freqvsref(\n", + " overall_1, \n", + " conditioned_1, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "f24335e4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.009333101114095434" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hazard_test_1" + ] + }, + { + "cell_type": "markdown", + "id": "e7914be4", + "metadata": {}, + "source": [ + "### Test 2 (TVD, low)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "e8377772", + "metadata": {}, + "outputs": [], + "source": [ + "bd_2 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"low\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "14e80b7e", + "metadata": {}, + "outputs": [], + "source": [ + "overall_2 = bd_2.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "468b603a", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_2 = bd_2.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "4016a74d", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_2 = hc.compute_hazard_from_freqvsfreq_or_freqvsref(\n", + " overall_2, \n", + " conditioned_2, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "markdown", + "id": "847b9871", + "metadata": {}, + "source": [ + "### Test 3 (JS, high)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "e8ce1a46", + "metadata": {}, + "outputs": [], + "source": [ + "bd_3 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"high\")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "5817e2d8", + "metadata": {}, + "outputs": [], + "source": [ + "overall_3 = bd_3.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "ff84ad8a", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_3 = bd_3.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "1043e2b1", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_3 = hc.compute_hazard_from_freqvsfreq_or_freqvsref(\n", + " overall_3, \n", + " conditioned_3, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "markdown", + "id": "e65d63c0", + "metadata": {}, + "source": [ + "### Test 4 (JS, low)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "8bd6ad0f", + "metadata": {}, + "outputs": [], + "source": [ + "bd_4 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"low\")" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "f35b30be", + "metadata": {}, + "outputs": [], + "source": [ + "overall_4 = bd_4.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "3ba5c71c", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_4 = bd_4.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "b11aedbb", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_4 = hc.compute_hazard_from_freqvsfreq_or_freqvsref(\n", + " overall_4, \n", + " conditioned_4, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "markdown", + "id": "6b08c2f2", + "metadata": {}, + "source": [ + "## Risk results" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "0c8805e1", + "metadata": {}, + "outputs": [], + "source": [ + "hazards = [hazard_test_1, hazard_test_2, hazard_test_3, hazard_test_4]" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "df958149", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0028434304317325647" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "rc.compute_risk(hazards)" + ] + }, + { + "cell_type": "markdown", + "id": "811da932", + "metadata": {}, + "source": [ + "# Experiments with 3 models" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "3022aa0b", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"./trained_model_for_testing/RF_12_200.pkl\", \"rb\") as file:\n", + " classifier_1 = load(file)\n", + " \n", + "with open(\"./trained_model_for_testing/RF_37_10.pkl\", \"rb\") as file:\n", + " classifier_2 = load(file)\n", + " \n", + "with open(\"./trained_model_for_testing/Tree_depth2.pkl\", \"rb\") as file:\n", + " classifier_3 = load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "b985b114", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_prob_1 = classifier_1.predict_proba(X_test_ohe)\n", + "predicted_values_1 = classifier_1.predict(X_test_ohe)\n", + "df_with_predictions_1 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_1)], axis=1).rename(columns={0:\"predictions\"})\n", + "\n", + "predicted_prob_2 = classifier_2.predict_proba(X_test_ohe)\n", + "predicted_values_2 = classifier_2.predict(X_test_ohe)\n", + "df_with_predictions_2 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_2)], axis=1).rename(columns={0:\"predictions\"})\n", + "\n", + "predicted_prob_3 = classifier_3.predict_proba(X_test_ohe)\n", + "predicted_values_3 = classifier_3.predict(X_test_ohe)\n", + "df_with_predictions_3 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_3)], axis=1).rename(columns={0:\"predictions\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "23ba3a67", + "metadata": {}, + "outputs": [], + "source": [ + "def test_model(data_frame):\n", + " ### Test 1: TVD, A1=high\n", + "\n", + " bd_1 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"high\")\n", + "\n", + " overall_1 = bd_1.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_1 = bd_1.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_1 = hc.compute_hazard_from_freqvsfreq_or_freqvsref(\n", + " overall_1, \n", + " conditioned_1, \n", + " data_frame.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")\n", + " \n", + " print(\"Test 1 (TVD, A1=high) hazard: \", hazard_test_1)\n", + "\n", + " ### Test 2 (TVD, low)\n", + "\n", + " bd_2 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"low\")\n", + "\n", + " overall_2 = bd_2.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_2 = bd_2.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_2 = hc.compute_hazard_from_freqvsfreq_or_freqvsref(\n", + " overall_2, \n", + " conditioned_2, \n", + " data_frame.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")\n", + " \n", + " print(\"Test 2 (TVD, A1=low) hazard: \", hazard_test_2)\n", + "\n", + " ### Test 3 (JS, high)\n", + "\n", + " bd_3 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"high\")\n", + "\n", + " overall_3 = bd_3.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_3 = bd_3.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_3 = hc.compute_hazard_from_freqvsfreq_or_freqvsref(\n", + " overall_3, \n", + " conditioned_3, \n", + " data_frame.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")\n", + " \n", + " print(\"Test 3 (JS, A1=high) hazard: \", hazard_test_3)\n", + "\n", + " ### Test 4 (JS, low)\n", + "\n", + " bd_4 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"low\")\n", + "\n", + " overall_4 = bd_4.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_4 = bd_4.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_4 = hc.compute_hazard_from_freqvsfreq_or_freqvsref(\n", + " overall_4, \n", + " conditioned_4, \n", + " data_frame.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")\n", + " \n", + " print(\"Test 4 (JS, A1=low) hazard: \", hazard_test_4)\n", + " \n", + " hazards = [hazard_test_1, hazard_test_2, hazard_test_3, hazard_test_4]\n", + " \n", + " return rc.compute_risk(hazards)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "7f9c5d36", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test 1 (TVD, A1=high) hazard: 0.009333101114095434\n", + "Test 2 (TVD, A1=low) hazard: 0.0020279631068363525\n", + "Test 3 (JS, A1=high) hazard: 1.2657505998471251e-05\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_12_200: 0.0028434304317325647\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.00873354115132899\n", + "Test 2 (TVD, A1=low) hazard: 0.0014683531134022521\n", + "Test 3 (JS, A1=high) hazard: 3.5455676319511333e-06\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_37_10: 0.002551359958090798\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.0022889741320904415\n", + "Test 2 (TVD, A1=low) hazard: 0.0006153636933853124\n", + "Test 3 (JS, A1=high) hazard: 1.9261143460997856e-05\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model Tree_depth2: 0.000730899742234188\n", + "\n", + "\n" + ] + } + ], + "source": [ + "for model, df in zip([\"RF_12_200\", \"RF_37_10\", \"Tree_depth2\"],\n", + " [df_with_predictions_1, df_with_predictions_2, df_with_predictions_3]):\n", + " print(f\"Overall risk measure for model {model}: \", test_model(df))\n", + " print(\"\\n\")" + ] + }, + { + "cell_type": "markdown", + "id": "6f0b3966", + "metadata": {}, + "source": [ + "## Freq Vs Ref" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "4b3771a0", + "metadata": {}, + "outputs": [], + "source": [ + "bd_ref = FreqVsRefBiasDetector()" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "24f7cf26", + "metadata": {}, + "outputs": [], + "source": [ + "male_0_ref = 55/100\n", + "male_1_ref = 45/100\n", + "\n", + "female_0_ref = 50/100\n", + "female_1_ref = 50/100\n", + "\n", + "ref_distribution = [np.array([female_0_ref, female_1_ref]), np.array([male_0_ref, male_1_ref])]" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "7dfb89a5", + "metadata": {}, + "outputs": [], + "source": [ + "overall_ref = bd_ref.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " #threshold=0.1,\n", + " reference_distribution=ref_distribution\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "a094a694", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_ref = bd_ref.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables,\n", + " #threshold=0.1,\n", + " min_obs_per_group=30,\n", + " reference_distribution=ref_distribution)" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "b9aefa9b", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_ref = hc.compute_hazard_from_freqvsfreq_or_freqvsref(\n", + " overall_ref, \n", + " conditioned_ref, \n", + " df_with_predictions.shape[0],\n", + " conditioning_variables,\n", + " weight_logic=\"group\")" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "4f4a0f26", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.0687693765858981" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hazard_test_ref" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/RiskMeasure_implementation_and_experiments.ipynb b/notebooks/RiskMeasure_implementation_and_experiments.ipynb new file mode 100644 index 0000000..019e3ed --- /dev/null +++ b/notebooks/RiskMeasure_implementation_and_experiments.ipynb @@ -0,0 +1,721 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "0b134d6e", + "metadata": {}, + "outputs": [], + "source": [ + "import os, sys\n", + "dir2 = os.path.abspath('')\n", + "dir1 = os.path.dirname(dir2)\n", + "if not dir1 in sys.path: sys.path.append(dir1)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "77c1e269", + "metadata": {}, + "outputs": [], + "source": [ + "from brio.utils.Preprocessing import Preprocessing\n", + "from sklearn.model_selection import train_test_split\n", + "from pickle import dump, load\n", + "import pandas as pd\n", + "import numpy as np\n", + "\n", + "from brio.bias.FreqVsFreqBiasDetector import FreqVsFreqBiasDetector" + ] + }, + { + "cell_type": "markdown", + "id": "68af6499", + "metadata": {}, + "source": [ + "## Importing Data and Trained Classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "66127e6c", + "metadata": {}, + "outputs": [], + "source": [ + "input_data_path = \"../data/raw_data/uci-default-of-credit-card/data/data.csv\"\n", + "local_path_save = '../data/mlflow_artifacts/'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "bf0e3b01", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/davideposillipo/.pyenv/versions/3.10.9/envs/prova/lib/python3.10/site-packages/sklearn/base.py:329: UserWarning: Trying to unpickle estimator OneHotEncoder from version 1.2.1 when using version 1.0.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/modules/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n", + "/Users/davideposillipo/.pyenv/versions/3.10.9/envs/prova/lib/python3.10/site-packages/sklearn/base.py:329: UserWarning: Trying to unpickle estimator StandardScaler from version 1.2.1 when using version 1.0.2. This might lead to breaking code or invalid results. Use at your own risk. For more info please refer to:\n", + "https://scikit-learn.org/stable/modules/model_persistence.html#security-maintainability-limitations\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "fitted_ohe = load(open(local_path_save + '_ohe.pkl', 'rb')) \n", + "fitted_scaler = load(open(local_path_save + '_scaler.pkl', 'rb'))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6646c312", + "metadata": {}, + "outputs": [], + "source": [ + "pp = Preprocessing(input_data_path, \"default\")\n", + "X, Y = pp.read_dataframe()\n", + "\n", + "X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size=0.3, random_state=420)\n", + "\n", + "X_test_ohe, _, _ = pp.preprocess_for_classification(df=X_test, \n", + " fit_ohe=True, \n", + " fitted_ohe=fitted_ohe,\n", + " perform_scaling=True,\n", + " fitted_scaler=fitted_scaler)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "ba010d39", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"./mlruns/1/1e4a0667c7a64cbe8c7b023410e5781c/artifacts/model/model.pkl\", \"rb\") as file:\n", + " classifier = load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "04cacf92", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_prob = classifier.predict_proba(X_test_ohe)\n", + "predicted_values = classifier.predict(X_test_ohe)" + ] + }, + { + "cell_type": "markdown", + "id": "01057c6d", + "metadata": {}, + "source": [ + "#### Definition of conditioning variables" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "d7e96a84", + "metadata": {}, + "outputs": [], + "source": [ + "def age_buckets(x):\n", + " if x < 30:\n", + " return 1\n", + " elif x < 40:\n", + " return 2\n", + " else:\n", + " return 3\n", + "\n", + "X_test['age_buckets'] = X.x5_age.apply(age_buckets)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c24a0c9c", + "metadata": {}, + "outputs": [], + "source": [ + "conditioning_variables = ['x3_education', 'x4_marriage', 'age_buckets']" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7950602d", + "metadata": {}, + "outputs": [], + "source": [ + "df_with_predictions = pd.concat(\n", + " [X_test.reset_index(drop=True), pd.Series(predicted_values)], axis=1).rename(columns={0:\"predictions\"})" + ] + }, + { + "cell_type": "markdown", + "id": "d6f80bfb", + "metadata": {}, + "source": [ + "## Hazard and risk functions" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "7e6183a2", + "metadata": {}, + "outputs": [], + "source": [ + "def hazard_function(overall_result, conditioned_results, tot_observations):\n", + " \n", + " # test result, threshold, num_samples, boolean\n", + " test_results = []\n", + " test_results.append((overall_result[0], \n", + " overall_result[2], \n", + " tot_observations, \n", + " overall_result[1]))\n", + " \n", + " for group in conditioned_results.values():\n", + " if (group[1] is not None):\n", + " test_results.append((group[1], group[3], group[0], group[2]))\n", + " \n", + " hazard = 0\n", + " for line in test_results:\n", + " weight = 1 #to be implemented\n", + " delta = 1 if line[3]==False else 0\n", + " q = line[2]/tot_observations\n", + " e = line[0] - line[1]\n", + " hazard += delta * weight * q * e\n", + " \n", + " average_threshold = np.mean([x[1] for x in test_results])\n", + " \n", + " return hazard, average_threshold" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "9dec052f", + "metadata": {}, + "outputs": [], + "source": [ + "def risk_function(test_hazards, average_thresholds):\n", + " # test_hazards = [list_of_hazards]\n", + " # average_thresholds = [mean(thresholds_of_test1), mean(thresholds_of_a_test2), ...], \n", + " # needed if automatic threshold is used\n", + " risk = 0\n", + " for hazard, threshold in zip(test_hazards, average_thresholds):\n", + " risk += hazard * threshold\n", + " \n", + " risk = risk/len(test_hazards)**2\n", + " \n", + " return risk" + ] + }, + { + "cell_type": "markdown", + "id": "0e6e5723", + "metadata": {}, + "source": [ + "### Test 1: TVD, A1=high" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "38346302", + "metadata": {}, + "outputs": [], + "source": [ + "bd_1 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"high\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "ebde5b3d", + "metadata": {}, + "outputs": [], + "source": [ + "overall_1 = bd_1.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "9dc1af6e", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_1 = bd_1.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "e4ad51ba", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_1, average_threshold_1 = hazard_function(\n", + " overall_1, \n", + " conditioned_1, \n", + " df_with_predictions.shape[0])" + ] + }, + { + "cell_type": "markdown", + "id": "e7914be4", + "metadata": {}, + "source": [ + "### Test 2 (TVD, low)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "e8377772", + "metadata": {}, + "outputs": [], + "source": [ + "bd_2 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"low\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "14e80b7e", + "metadata": {}, + "outputs": [], + "source": [ + "overall_2 = bd_2.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "468b603a", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_2 = bd_2.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "4016a74d", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_2, average_threshold_2 = hazard_function(\n", + " overall_2, \n", + " conditioned_2, \n", + " df_with_predictions.shape[0])" + ] + }, + { + "cell_type": "markdown", + "id": "847b9871", + "metadata": {}, + "source": [ + "### Test 3 (JS, high)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "e8ce1a46", + "metadata": {}, + "outputs": [], + "source": [ + "bd_3 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"high\")" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "5817e2d8", + "metadata": {}, + "outputs": [], + "source": [ + "overall_3 = bd_3.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "ff84ad8a", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_3 = bd_3.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "1043e2b1", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_3, average_threshold_3 = hazard_function(\n", + " overall_3, \n", + " conditioned_3, \n", + " df_with_predictions.shape[0])" + ] + }, + { + "cell_type": "markdown", + "id": "e65d63c0", + "metadata": {}, + "source": [ + "### Test 4 (JS, low)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "8bd6ad0f", + "metadata": {}, + "outputs": [], + "source": [ + "bd_4 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"low\")" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "f35b30be", + "metadata": {}, + "outputs": [], + "source": [ + "overall_4 = bd_4.compare_root_variable_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "3ba5c71c", + "metadata": {}, + "outputs": [], + "source": [ + "conditioned_4 = bd_4.compare_root_variable_conditioned_groups(\n", + " dataframe=df_with_predictions,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "b11aedbb", + "metadata": {}, + "outputs": [], + "source": [ + "hazard_test_4, average_threshold_4 = hazard_function(\n", + " overall_4, \n", + " conditioned_4, \n", + " df_with_predictions.shape[0])" + ] + }, + { + "cell_type": "markdown", + "id": "6b08c2f2", + "metadata": {}, + "source": [ + "## Risk results" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "0c8805e1", + "metadata": {}, + "outputs": [], + "source": [ + "hazards = [hazard_test_1, hazard_test_2, hazard_test_3, hazard_test_4]\n", + "average_thresholds = [average_threshold_1, average_threshold_2, average_threshold_3, average_threshold_4]" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "df958149", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.00015458111237839916" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "risk_function(hazards, average_thresholds)" + ] + }, + { + "cell_type": "markdown", + "id": "811da932", + "metadata": {}, + "source": [ + "# Experiments with 3 models" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "3022aa0b", + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"./trained_model_for_testing/RF_12_200.pkl\", \"rb\") as file:\n", + " classifier_1 = load(file)\n", + " \n", + "with open(\"./trained_model_for_testing/RF_37_10.pkl\", \"rb\") as file:\n", + " classifier_2 = load(file)\n", + " \n", + "with open(\"./trained_model_for_testing/Tree_depth2.pkl\", \"rb\") as file:\n", + " classifier_3 = load(file)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "b985b114", + "metadata": {}, + "outputs": [], + "source": [ + "predicted_prob_1 = classifier_1.predict_proba(X_test_ohe)\n", + "predicted_values_1 = classifier_1.predict(X_test_ohe)\n", + "df_with_predictions_1 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_1)], axis=1).rename(columns={0:\"predictions\"})\n", + "\n", + "predicted_prob_2 = classifier_2.predict_proba(X_test_ohe)\n", + "predicted_values_2 = classifier_2.predict(X_test_ohe)\n", + "df_with_predictions_2 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_2)], axis=1).rename(columns={0:\"predictions\"})\n", + "\n", + "predicted_prob_3 = classifier_3.predict_proba(X_test_ohe)\n", + "predicted_values_3 = classifier_3.predict(X_test_ohe)\n", + "df_with_predictions_3 = pd.concat(\n", + " [X_test.reset_index(drop=True), \n", + " pd.Series(predicted_values_3)], axis=1).rename(columns={0:\"predictions\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "23ba3a67", + "metadata": {}, + "outputs": [], + "source": [ + "def test_model(data_frame):\n", + " ### Test 1: TVD, A1=high\n", + "\n", + " bd_1 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"high\")\n", + "\n", + " overall_1 = bd_1.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_1 = bd_1.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_1, average_threshold_1 = hazard_function(\n", + " overall_1, \n", + " conditioned_1, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 1 (TVD, A1=high) hazard: \", hazard_test_1)\n", + "\n", + " ### Test 2 (TVD, low)\n", + "\n", + " bd_2 = FreqVsFreqBiasDetector(distance=\"TVD\", A1=\"low\")\n", + "\n", + " overall_2 = bd_2.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_2 = bd_2.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_2, average_threshold_2 = hazard_function(\n", + " overall_2, \n", + " conditioned_2, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 2 (TVD, A1=low) hazard: \", hazard_test_2)\n", + "\n", + " ### Test 3 (JS, high)\n", + "\n", + " bd_3 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"high\")\n", + "\n", + " overall_3 = bd_3.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_3 = bd_3.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_3, average_threshold_3 = hazard_function(\n", + " overall_3, \n", + " conditioned_3, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 3 (JS, A1=high) hazard: \", hazard_test_3)\n", + "\n", + " ### Test 4 (JS, low)\n", + "\n", + " bd_4 = FreqVsFreqBiasDetector(distance=\"JS\", A1=\"low\")\n", + "\n", + " overall_4 = bd_4.compare_root_variable_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex')\n", + "\n", + " conditioned_4 = bd_4.compare_root_variable_conditioned_groups(\n", + " dataframe=data_frame,\n", + " target_variable='predictions',\n", + " root_variable='x2_sex',\n", + " conditioning_variables=conditioning_variables)\n", + "\n", + " hazard_test_4, average_threshold_4 = hazard_function(\n", + " overall_4, \n", + " conditioned_4, \n", + " data_frame.shape[0])\n", + " \n", + " print(\"Test 4 (JS, A1=low) hazard: \", hazard_test_4)\n", + " \n", + " hazards = [hazard_test_1, hazard_test_2, hazard_test_3, hazard_test_4]\n", + " average_thresholds = [average_threshold_1, \n", + " average_threshold_2, average_threshold_3, average_threshold_4]\n", + " \n", + " return risk_function(hazards, average_thresholds)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "7f9c5d36", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test 1 (TVD, A1=high) hazard: 0.09976465885178575\n", + "Test 2 (TVD, A1=low) hazard: 0.02015304845287825\n", + "Test 3 (JS, A1=high) hazard: 0.00011458216656976323\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_12_200: 0.00015458111237839916\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.09085147869902101\n", + "Test 2 (TVD, A1=low) hazard: 0.014801760181546463\n", + "Test 3 (JS, A1=high) hazard: 1.52371151916934e-06\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model RF_37_10: 0.00013193466737245095\n", + "\n", + "\n", + "Test 1 (TVD, A1=high) hazard: 0.03355105791241006\n", + "Test 2 (TVD, A1=low) hazard: 0.006384298991373367\n", + "Test 3 (JS, A1=high) hazard: 0.00014383137973982362\n", + "Test 4 (JS, A1=low) hazard: 0.0\n", + "Overall risk measure for model Tree_depth2: 5.113018082906323e-05\n", + "\n", + "\n" + ] + } + ], + "source": [ + "for model, df in zip([\"RF_12_200\", \"RF_37_10\", \"Tree_depth2\"],\n", + " [df_with_predictions_1, df_with_predictions_2, df_with_predictions_3]):\n", + " print(f\"Overall risk measure for model {model}: \", test_model(df))\n", + " print(\"\\n\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e6f6f9ae", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notes on risk/main.aux b/notes on risk/main.aux new file mode 100644 index 0000000..78a600f --- /dev/null +++ b/notes on risk/main.aux @@ -0,0 +1,27 @@ +\relax +\@writefile{toc}{\contentsline {section}{\numberline {1}Overview}{1}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Risk associated to a single test}{2}{}\protected@file@percent } +\newlabel{risk_single}{{1.1}{2}} +\newlabel{risk_single@cref}{{[subsection][1][1]1.1}{[1][2][]2}} +\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Risk associated to a battery of tests}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {section}{\numberline {2}Execution of the module}{3}{}\protected@file@percent } +\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Pipeline}{3}{}\protected@file@percent } +\bibdata{temp} +\bibcite{DBLP:conf/beware/CoragliaDGGPPQ23}{CDG{$^{+}$}23} +\newlabel{qui}{{2}{4}} +\newlabel{qui@cref}{{[enumi][2][]2}{[1][4][]4}} +\newlabel{qui2}{{3}{4}} +\newlabel{qui2@cref}{{[enumi][3][]3}{[1][4][]4}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Strategy}{4}{}\protected@file@percent } +\newlabel{strategy}{{2.2}{4}} +\newlabel{strategy@cref}{{[subsection][2][2]2.2}{[1][4][]4}} +\newlabel{quy}{{1}{4}} +\newlabel{quy@cref}{{[enumi][1][]1}{[1][4][]4}} +\newlabel{bad_record}{{3}{4}} +\newlabel{bad_record@cref}{{[enumi][3][]3}{[1][4][]4}} +\newlabel{quy2}{{4}{4}} +\newlabel{quy2@cref}{{[enumi][4][]4}{[1][4][]4}} +\bibcite{dkl}{KL51} +\bibcite{lin_divergence}{Lin91} +\bibstyle{alpha} +\gdef \@abspage@last{5} diff --git a/notes on risk/main.bbl b/notes on risk/main.bbl new file mode 100644 index 0000000..1ba1ec8 --- /dev/null +++ b/notes on risk/main.bbl @@ -0,0 +1,26 @@ +\newcommand{\etalchar}[1]{$^{#1}$} +\begin{thebibliography}{CDG{\etalchar{+}}23} + +\bibitem[CDG{\etalchar{+}}23]{DBLP:conf/beware/CoragliaDGGPPQ23} +Greta Coraglia, Fabio~Aurelio D'Asaro, Francesco~Antonio Genco, Davide + Giannuzzi, Davide Posillipo, Giuseppe Primiero, and Christian Quaggio. +\newblock Brioxalkemy: a bias detecting tool. +\newblock In Guido Boella, Fabio~Aurelio D'Asaro, Abeer Dyoub, Laura Gorrieri, + Francesca~A. Lisi, Chiara Manganini, and Giuseppe Primiero, editors, {\em + Proceedings of the 2nd Workshop on Bias, Ethical AI, Explainability and the + role of Logic and Logic Programming co-located with the 22nd International + Conference of the Italian Association for Artificial Intelligence (AI*IA + 2023), Rome, Italy, November 6, 2023}, volume 3615 of {\em {CEUR} Workshop + Proceedings}, pages 44--60. CEUR-WS.org, 2023. + +\bibitem[KL51]{dkl} +S.~Kullback and R.~A. Leibler. +\newblock {On Information and Sufficiency}. +\newblock {\em The Annals of Mathematical Statistics}, 22(1):79 -- 86, 1951. + +\bibitem[Lin91]{lin_divergence} +J.~Lin. +\newblock Divergence measures based on the shannon entropy. +\newblock {\em IEEE Transactions on Information Theory}, 37(1):145--151, 1991. + +\end{thebibliography} diff --git a/notes on risk/main.blg b/notes on risk/main.blg new file mode 100644 index 0000000..3fe7aa3 --- /dev/null +++ b/notes on risk/main.blg @@ -0,0 +1,59 @@ +This is BibTeX, Version 0.99d +Capacity: max_strings=200000, hash_size=200000, hash_prime=170003 +The top-level auxiliary file: main.aux +Reallocating 'name_of_file' (item size: 1) to 5 items. +Reallocating 'name_of_file' (item size: 1) to 6 items. +The style file: alpha.bst +Database file #1: temp.bib +I was expecting a `,' or a `}'---line 2949 of file temp.bib + : + : @article{Castelnovo_2022, +(Error may have been on previous line) +I'm skipping whatever remains of this entry +I was expecting a `,' or a `}'---line 2973 of file temp.bib + : + : % incol due to presence of booktitle +(Error may have been on previous line) +I'm skipping whatever remains of this entry +You've used 3 entries, + 2543 wiz_defined-function locations, + 845 strings with 10756 characters, +and the built_in function-call counts, 1584 in all, are: += -- 147 +> -- 95 +< -- 3 ++ -- 32 +- -- 32 +* -- 137 +:= -- 270 +add.period$ -- 10 +call.type$ -- 3 +change.case$ -- 22 +chr.to.int$ -- 3 +cite$ -- 3 +duplicate$ -- 54 +empty$ -- 104 +format.name$ -- 35 +if$ -- 318 +int.to.chr$ -- 1 +int.to.str$ -- 0 +missing$ -- 3 +newline$ -- 19 +num.names$ -- 11 +pop$ -- 17 +preamble$ -- 1 +purify$ -- 25 +quote$ -- 0 +skip$ -- 43 +stack$ -- 0 +substring$ -- 91 +swap$ -- 13 +text.length$ -- 3 +text.prefix$ -- 1 +top$ -- 0 +type$ -- 24 +warning$ -- 0 +while$ -- 15 +width$ -- 5 +write$ -- 44 +(There were 2 error messages) diff --git a/notes on risk/main.pdf b/notes on risk/main.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b6c0714fc96f3e302001d7a16e2c1cb1d2773f65 GIT binary patch literal 221411 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 literal 0 HcmV?d00001 diff --git a/notes on risk/main.synctex.gz b/notes on risk/main.synctex.gz new file mode 100644 index 0000000000000000000000000000000000000000..91d9ea038d991a7dbf26a60f8d4f1a1a37dcd686 GIT binary patch literal 34124 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\texttt{C}_0$ and returns to \ref{qui}. +\end{enumerate} + +\subsection{Strategy}\label{strategy} +Now we only need to provide a suitable way of using the \texttt{freqvfreq} option in our bias module. The check proceeds breadth first. For a line in the output (that is, the $j$s in \ref{risk_single}) the algorithm +\begin{enumerate} +\item starts computing the line,\label{quy} +\item if it succeeds in time $\leq\texttt{T}$, it moves on to \ref{quy2}, if not +\item it records the `bad' combination of features, and closes it for extension\footnote{Meaning that if we have conditioning $\{a,b,c,d,e\}$ and it fails at $abc$, then to the `bad' record one adds $\{abc, abcd, abce\}$, then iterate\dots},\label{bad_record} +\item $j=j+1$,\label{quy2} +\item if the combination in $j$ is in the `bad' record, go straight to \ref{quy2}, +\item go back to \ref{quy}. +\end{enumerate} +This way, it is possible to combinatorially estimate an upper bound for the computation time\footnote{Modulo everything else, that should not account for much.} (possible combinations $\times$ \texttt{T}), and depending on the user's computational capability they can decide whether they want to proceed to the calculus or not. This procedure also guarantees that failure of a check aborts all possible checks that are `extensions' of it, so that, all in all, the runtime will usually be \emph{way below} that calculated. + +\bibliography{temp} +\bibliographystyle{alpha} + +\end{document} + + diff --git a/notes on risk/main.toc b/notes on risk/main.toc new file mode 100644 index 0000000..2b33e1b --- /dev/null +++ b/notes on risk/main.toc @@ -0,0 +1,6 @@ +\contentsline {section}{\numberline {1}Overview}{1}{}% +\contentsline {subsection}{\numberline {1.1}Risk associated to a single test}{2}{}% +\contentsline {subsection}{\numberline {1.2}Risk associated to a battery of tests}{3}{}% +\contentsline {section}{\numberline {2}Execution of the module}{3}{}% +\contentsline {subsection}{\numberline {2.1}Pipeline}{3}{}% +\contentsline {subsection}{\numberline {2.2}Strategy}{4}{}% diff --git a/notes on risk/temp.bib b/notes on risk/temp.bib new file mode 100644 index 0000000..025e4b3 --- /dev/null +++ b/notes on risk/temp.bib @@ -0,0 +1,1945 @@ + +% Journals + +% First the Full Name is given, then the abbreviation used in the AMS Math +% Reviews, with an indication if it could not be found there. +% Note the 2nd overwrites the 1st, so swap them if you want the full name. + + %{AMS} + @String{AMSTrans = "American Mathematical Society Translations" } + @String{AMSTrans = "Amer. Math. Soc. Transl." } + @String{BullAMS = "Bulletin of the American Mathematical Society" } + @String{BullAMS = "Bull. Amer. Math. Soc." } + @String{ProcAMS = "Proceedings of the American Mathematical Society" } + @String{ProcAMS = "Proc. Amer. Math. Soc." } + @String{TransAMS = "Transactions of the American Mathematical Society" } + @String{TransAMS = "Trans. Amer. Math. Soc." } + + %ACM + @String{CACM = "Communications of the {ACM}" } + @String{CACM = "Commun. {ACM}" } + @String{CompServ = "Comput. Surveys" } + @String{JACM = "J. ACM" } + @String{ACMMathSoft = "{ACM} Transactions on Mathematical Software" } + @String{ACMMathSoft = "{ACM} Trans. Math. Software" } + @String{SIGNUM = "{ACM} {SIGNUM} Newsletter" } + @String{SIGNUM = "{ACM} {SIGNUM} Newslett." } + + @String{AmerSocio = "American Journal of Sociology" } + @String{AmerStatAssoc = "Journal of the American Statistical Association" } + @String{AmerStatAssoc = "J. Amer. Statist. Assoc." } + @String{ApplMathComp = "Applied Mathematics and Computation" } + @String{ApplMathComp = "Appl. Math. Comput." } + @String{AmerMathMonthly = "American Mathematical Monthly" } + @String{AmerMathMonthly = "Amer. Math. Monthly" } + @String{BIT = "{BIT}" } + @String{BritStatPsych = "British Journal of Mathematical and Statistical + Psychology" } + @String{BritStatPsych = "Brit. J. Math. Statist. Psych." } + @String{CanMathBull = "Canadian Mathematical Bulletin" } + @String{CanMathBull = "Canad. Math. Bull." } + @String{CompApplMath = "Journal of Computational and Applied Mathematics" } + @String{CompApplMath = "J. Comput. Appl. Math." } + @String{CompPhys = "Journal of Computational Physics" } + @String{CompPhys = "J. Comput. Phys." } + @String{CompStruct = "Computers and Structures" } + @String{CompStruct = "Comput. \& Structures" } + @String{CompJour = "The Computer Journal" } + @String{CompJour = "Comput. J." } + @String{CompSysSci = "Journal of Computer and System Sciences" } + @String{CompSysSci = "J. Comput. System Sci." } + @String{Computing = "Computing" } + @String{ContempMath = "Contemporary Mathematics" } + @String{ContempMath = "Contemp. Math." } + @String{Crelle = "Crelle's Journal" } + @String{GiornaleMath = "Giornale di Mathematiche" } + @String{GiornaleMath = "Giorn. Mat." } % didn't find in AMS MR., ibid. + + %IEEE + @String{Computer = "{IEEE} Computer" } + @String{IEEETransComp = "{IEEE} Transactions on Computers" } + @String{IEEETransComp = "{IEEE} Trans. Comput." } + @String{IEEETransAC = "{IEEE} Transactions on Automatic Control" } + @String{IEEETransAC = "{IEEE} Trans. Automat. Control" } + @String{IEEESpec = "{IEEE} Spectrum" } % didn't find in AMS MR + @String{ProcIEEE = "Proceedings of the {IEEE}" } + @String{ProcIEEE = "Proc. {IEEE}" } % didn't find in AMS MR + @String{IEEETransAeroElec = "{IEEE} Transactions on Aerospace and Electronic + Systems" } + @String{IEEETransAeroElec = "{IEEE} Trans. Aerospace Electron. Systems" } + + @String{IMANumerAna = "{IMA} Journal of Numerical Analysis" } + @String{IMANumerAna = "{IMA} J. Numer. Anal." } + @String{InfProcLet = "Information Processing Letters" } + @String{InfProcLet = "Inform. Process. Lett." } + @String{InstMathApp = "Journal of the Institute of Mathematics and + its Applications" } + @String{InstMathApp = "J. Inst. Math. Appl." } + @String{IntControl = "International Journal of Control" } + @String{IntControl = "Internat. J. Control" } + @String{IntNumerEng = "International Journal for Numerical Methods in + Engineering" } + @String{IntNumerEng = "Internat. J. Numer. Methods Engrg." } + @String{IntSuper = "International Journal of Supercomputing Applications" } + @String{IntSuper = "Internat. J. Supercomputing Applic." } % didn't find +%% in AMS MR + @String{Kibernetika = "Kibernetika" } + @String{JResNatBurStand = "Journal of Research of the National Bureau + of Standards" } + @String{JResNatBurStand = "J. Res. Nat. Bur. Standards" } + @String{LinAlgApp = "Linear Algebra and its Applications" } + @String{LinAlgApp = "Linear Algebra Appl." } + @String{MathAnaAppl = "Journal of Mathematical Analysis and Applications" } + @String{MathAnaAppl = "J. Math. Anal. Appl." } + @String{MathAnnalen = "Mathematische Annalen" } + @String{MathAnnalen = "Math. Ann." } + @String{MathPhys = "Journal of Mathematical Physics" } + @String{MathPhys = "J. Math. Phys." } + @String{MathComp = "Mathematics of Computation" } + @String{MathComp = "Math. Comp." } + @String{MathScand = "Mathematica Scandinavica" } + @String{MathScand = "Math. Scand." } + @String{TablesAidsComp = "Mathematical Tables and Other Aids to Computation" } + @String{TablesAidsComp = "Math. Tables Aids Comput." } + @String{NumerMath = "Numerische Mathematik" } + @String{NumerMath = "Numer. Math." } + @String{PacificMath = "Pacific Journal of Mathematics" } + @String{PacificMath = "Pacific J. Math." } + @String{ParDistComp = "Journal of Parallel and Distributed Computing" } + @String{ParDistComp = "J. Parallel and Distrib. Comput." } % didn't find +%% in AMS MR + @String{ParComputing = "Parallel Computing" } + @String{ParComputing = "Parallel Comput." } + @String{PhilMag = "Philosophical Magazine" } + @String{PhilMag = "Philos. Mag." } + @String{ProcNAS = "Proceedings of the National Academy of Sciences + of the USA" } + @String{ProcNAS = "Proc. Nat. Acad. Sci. U. S. A." } + @String{Psychometrika = "Psychometrika" } + @String{QuartMath = "Quarterly Journal of Mathematics, Oxford, Series (2)" } + @String{QuartMath = "Quart. J. Math. Oxford Ser. (2)" } + @String{QuartApplMath = "Quarterly of Applied Mathematics" } + @String{QuartApplMath = "Quart. Appl. Math." } + @String{RevueInstStat = "Review of the International Statisical Institute" } + @String{RevueInstStat = "Rev. Inst. Internat. Statist." } + + %SIAM + @String{JSIAM = "Journal of the Society for Industrial and Applied + Mathematics" } + @String{JSIAM = "J. Soc. Indust. Appl. Math." } + @String{JSIAMB = "Journal of the Society for Industrial and Applied + Mathematics, Series B, Numerical Analysis" } + @String{JSIAMB = "J. Soc. Indust. Appl. Math. Ser. B Numer. Anal." } + @String{SIAMAlgMeth = "{SIAM} Journal on Algebraic and Discrete Methods" } + @String{SIAMAlgMeth = "{SIAM} J. Algebraic Discrete Methods" } + @String{SIAMAppMath = "{SIAM} Journal on Applied Mathematics" } + @String{SIAMAppMath = "{SIAM} J. Appl. Math." } + @String{SIAMComp = "{SIAM} Journal on Computing" } + @String{SIAMComp = "{SIAM} J. Comput." } + @String{SIAMMatrix = "{SIAM} Journal on Matrix Analysis and Applications" } + @String{SIAMMatrix = "{SIAM} J. Matrix Anal. Appl." } + @String{SIAMNumAnal = "{SIAM} Journal on Numerical Analysis" } + @String{SIAMNumAnal = "{SIAM} J. Numer. Anal." } + @String{SIAMReview = "{SIAM} Review" } + @String{SIAMReview = "{SIAM} Rev." } + @String{SIAMSciStat = "{SIAM} Journal on Scientific and Statistical + Computing" } + @String{SIAMSciStat = "{SIAM} J. Sci. Statist. Comput." } + + @String{SoftPracExp = "Software Practice and Experience" } + @String{SoftPracExp = "Software Prac. Experience" } % didn't find in AMS MR + @String{StatScience = "Statistical Science" } + @String{StatScience = "Statist. Sci." } + @String{Techno = "Technometrics" } + @String{USSRCompMathPhys = "{USSR} Computational Mathematics and Mathematical + Physics" } + @String{USSRCompMathPhys = "{U. S. S. R.} Comput. Math. and Math. Phys." } + @String{VLSICompSys = "Journal of {VLSI} and Computer Systems" } + @String{VLSICompSys = "J. {VLSI} Comput. Syst." } + @String{ZAngewMathMech = "Zeitschrift fur Angewandte Mathematik und + Mechanik" } + @String{ZAngewMathMech = "Z. Angew. Math. Mech." } + @String{ZAngewMathPhys = "Zeitschrift fur Angewandte Mathematik und Physik" } + @String{ZAngewMathPhys = "Z. Angew. Math. Phys." } + +% Publishers % ================================================= | + + @String{Academic = "Academic Press" } + @String{ACMPress = "{ACM} Press" } + @String{AdamHilger = "Adam Hilger" } + @String{AddisonWesley = "Addison-Wesley" } + @String{AllynBacon = "Allyn and Bacon" } + @String{AMS = "American Mathematical Society" } + @String{Birkhauser = "Birkha{\"u}ser" } + @String{CambridgePress = "Cambridge University Press" } + @String{Chelsea = "Chelsea" } + @String{ClaredonPress = "Claredon Press" } + @String{DoverPub = "Dover Publications" } + @String{Eyolles = "Eyolles" } + @String{HoltRinehartWinston = "Holt, Rinehart and Winston" } + @String{Interscience = "Interscience" } + @String{JohnsHopkinsPress = "The Johns Hopkins University Press" } + @String{JohnWileySons = "John Wiley and Sons" } + @String{Macmillan = "Macmillan" } + @String{MathWorks = "The Math Works Inc." } + @String{McGrawHill = "McGraw-Hill" } + @String{NatBurStd = "National Bureau of Standards" } + @String{NorthHolland = "North-Holland" } + @String{OxfordPress = "Oxford University Press" } %address Oxford or London? + @String{PergamonPress = "Pergamon Press" } + @String{PlenumPress = "Plenum Press" } + @String{PrenticeHall = "Prentice-Hall" } + @String{SIAMPub = "{SIAM} Publications" } + @String{Springer = "Springer-Verlag" } + @String{TexasPress = "University of Texas Press" } + @String{VanNostrand = "Van Nostrand" } + @String{WHFreeman = "W. H. Freeman and Co." } + +%Entries + + +@inproceedings{DBLP:conf/beware/CoragliaDGGPPQ23, + author = {Greta Coraglia and + Fabio Aurelio D'Asaro and + Francesco Antonio Genco and + Davide Giannuzzi and + Davide Posillipo and + Giuseppe Primiero and + Christian Quaggio}, + editor = {Guido Boella and + Fabio Aurelio D'Asaro and + Abeer Dyoub and + Laura Gorrieri and + Francesca A. Lisi and + Chiara Manganini and + Giuseppe Primiero}, + title = {BRIOxAlkemy: a Bias Detecting Tool}, + booktitle = {Proceedings of the 2nd Workshop on Bias, Ethical AI, Explainability + and the role of Logic and Logic Programming co-located with the 22nd + International Conference of the Italian Association for Artificial + Intelligence (AI*IA 2023), Rome, Italy, November 6, 2023}, + series = {{CEUR} Workshop Proceedings}, + volume = {3615}, + pages = {44--60}, + publisher = {CEUR-WS.org}, + year = {2023}, + url = {https://ceur-ws.org/Vol-3615/paper4.pdf}, + timestamp = {Thu, 25 Jan 2024 16:38:44 +0100}, + biburl = {https://dblp.org/rec/conf/beware/CoragliaDGGPPQ23.bib}, + bibsource = {dblp computer science bibliography, https://dblp.org} +} + + + +@article{gp23, + author = {Genco, F.A. and Primiero, G.}, + title = {A Typed Lambda-Calculus for Establishing Trust in Probabilistic Programs}, + journal={{A}rXiv e-prints}, + year = {2023}} + +@article{dagp22, + title={Checking Trustworthiness of Probabilistic Computations in a Typed Natural Deduction System}, + author={D'Asaro, F.A. and Genco, F.A. and Primiero, G.}, + journal={{A}rXiv e-prints}, + year={2022} +} + +@article{pk16, + title={The Semantics of Untrustworthiness}, + author={Primiero, G. and Kosolosky, L.}, + journal={Topoi}, + volume={35}, + pages={253--266}, + year={2016} +} + + +@inproceedings{dap21, + title={Probabilistic typed natural deduction for trustworthy computations}, + author={D’Asaro, F.A. and Primiero, G.}, + booktitle={Proceedings of the 22nd International Workshop on Trust in Agent Societies (TRUST2021@ AAMAS)}, + year={2021} +} + + +@article{YEH20092473, + abstract = {This research aimed at the case of customers' default payments in Taiwan and compares the predictive accuracy of probability of default among six data mining methods. From the perspective of risk management, the result of predictive accuracy of the estimated probability of default will be more valuable than the binary result of classification - credible or not credible clients. Because the real probability of default is unknown, this study presented the novel ``Sorting Smoothing Method'' to estimate the real probability of default. With the real probability of default as the response variable (Y), and the predictive probability of default as the independent variable (X), the simple linear regression result (Y=A+BX) shows that the forecasting model produced by artificial neural network has the highest coefficient of determination; its regression intercept (A) is close to zero, and regression coefficient (B) to one. Therefore, among the six data mining techniques, artificial neural network is the only one that can accurately estimate the real probability of default.}, + author = {I-Cheng Yeh and {Che-hui} Lien}, + doi = {https://doi.org/10.1016/j.eswa.2007.12.020}, + issn = {0957-4174}, + journal = {Expert Systems with Applications}, + keywords = {Banking, Neural network, Probability, Data mining}, + number = {2, Part 1}, + pages = {2473-2480}, + title = {The comparisons of data mining techniques for the predictive accuracy of probability of default of credit card clients}, + url = {https://www.sciencedirect.com/science/article/pii/S0957417407006719}, + volume = {36}, + year = {2009}, + bdsk-url-1 = {https://www.sciencedirect.com/science/article/pii/S0957417407006719}, + bdsk-url-2 = {https://doi.org/10.1016/j.eswa.2007.12.020}} + + + +@Article{Abril07, + author = "Patricia S. Abril and Robert Plant", + title = "The patent holder's dilemma: Buy, sell, or troll?", + journal = "Communications of the ACM", + volume = "50", + number = "1", + month = jan, + year = "2007", + pages = "36--44", + doi = "10.1145/1188913.1188915", + OPTurl = "http://doi.acm.org/10.1145/1219092.1219093", + note = "", +} + +@book{levin2017markov, + title={Markov Chains and Mixing Times}, + author={Levin, D.A. and Peres, Y.}, + isbn={9781470429621}, + lccn={2017017451}, + series={MBK}, + url={https://books.google.ch/books?id=f208DwAAQBAJ}, + year={2017}, + publisher={American Mathematical Society} +} + + +@ARTICLE{lin_divergence, + + author={Lin, J.}, + + journal={IEEE Transactions on Information Theory}, + + title={Divergence measures based on the Shannon entropy}, + + year={1991}, + + volume={37}, + + number={1}, + + pages={145-151}, + + doi={10.1109/18.61115}} + + +@Article{Cohen07, + author = "Sarah Cohen and Werner Nutt and Yehoshua Sagic", + title = "Deciding equivalances among conjunctive aggregate queries", + journal = JACM, + articleno = "5", + numpages = "50", + volume = "54", + number = "2", + month = apr, + year = "2007", + doi = "10.1145/1219092.1219093", + OPTurl = "http://doi.acm.org/10.1145/1219092.1219093", + acmid = "1219093", + note = "", +} + + +@Proceedings{JCohen96, + key = "Cohen", + editor = "Jacques Cohen", + title = "Special issue: Digital Libraries", + journal = CACM, + volume = "39", + number = "11", + month = nov, + year = "1996", +} + + +@Book{Kosiur01, + author = "David Kosiur", + title = "Understanding Policy-Based Networking", + publisher = "Wiley", + year = "2001", + address = "New York, NY", + edition = "2nd.", + editor = "", + volume = "", + number = "", + series = "", + month = "", + note = "", +} + + +@Book{Harel79, + author = "David Harel", + year = "1979", + title = "First-Order Dynamic Logic", + series = "Lecture Notes in Computer Science", + volume = "68", + address = "New York, NY", + publisher = "Springer-Verlag", + doi = "10.1007/3-540-09237-4", + OPTurl = "http://dx.doi.org/10.1007/3-540-09237-4", + editor = "", + number = "", + month = "", + note = "", +} + + +@Inbook{Editor00, + author = "", + editor = "Ian Editor", + title = "The title of book one", + subtitle = "The book subtitle", + series = "The name of the series one", + year = "2007", + volume = "9", + address = "Chicago", + edition = "1st.", + publisher = "University of Chicago Press", + doi = "10.1007/3-540-09237-4", + OPTurl = "http://dx.doi.org/10.1007/3-540-09456-9", + chapter = "", + pages = "", + number = "", + type = "", + month = "", + note = "", +} + +% +@InBook{Editor00a, + author = "", + editor = "Ian Editor", + title = "The title of book two", + subtitle = "The book subtitle", + series = "The name of the series two", + year = "2008", + address = "Chicago", + edition = "2nd.", + publisher = "University of Chicago Press", + doi = "10.1007/3-540-09237-4", + OPTurl = "http://dx.doi.org/10.1007/3-540-09456-9", + volume = "", + chapter = "100", + pages = "", + number = "", + type = "", + month = "", + note = "", +} + + +% incollection (has an editor, title, and possibly a booktitle) +@Incollection{Spector90, + author = "Asad Z. Spector", + title = "Achieving application requirements", + booktitle = "Distributed Systems", + publisher = "ACM Press", + address = "New York, NY", + year = "1990", + edition = "2nd.", + chapter = "", + editor = "Sape Mullender", + pages = "19--33", + doi = "10.1145/90417.90738", + OPTurl = "http://doi.acm.org/10.1145/90417.90738", + volume = "", + number = "", + series = "", + type = "", + month = "", + note = "", +} + + +@INPROCEEDINGS{6413831, + + author={Kamiran, Faisal and Karim, Asim and Zhang, Xiangliang}, + + booktitle={2012 IEEE 12th International Conference on Data Mining}, + + title={Decision Theory for Discrimination-Aware Classification}, + + year={2012}, + + volume={}, + + number={}, + + pages={924-929}, + + doi={10.1109/ICDM.2012.45}} + + + +@inproceedings{NIPS2017_b8b9c74a, + author = {Pleiss, Geoff and Raghavan, Manish and Wu, Felix and Kleinberg, Jon and Weinberger, Kilian Q}, + booktitle = {Advances in Neural Information Processing Systems}, + editor = {I. Guyon and U. Von Luxburg and S. Bengio and H. Wallach and R. Fergus and S. Vishwanathan and R. Garnett}, + pages = {}, + publisher = {Curran Associates, Inc.}, + title = {On Fairness and Calibration}, + url = {https://proceedings.neurips.cc/paper_files/paper/2017/file/b8b9c74ac526fffbeb2d39ab038d1cd7-Paper.pdf}, + volume = {30}, + year = {2017} +} + + + +@inproceedings{NIPS2016_9d268236, + author = {Hardt, Moritz and Price, Eric and Price, Eric and Srebro, Nati}, + booktitle = {Advances in Neural Information Processing Systems}, + editor = {D. Lee and M. Sugiyama and U. Luxburg and I. Guyon and R. Garnett}, + pages = {}, + publisher = {Curran Associates, Inc.}, + title = {Equality of Opportunity in Supervised Learning}, + url = {https://proceedings.neurips.cc/paper_files/paper/2016/file/9d2682367c3935defcb1f9e247a97c0d-Paper.pdf}, + volume = {29}, + year = {2016} +} + + +@article{dAlessandro2017ConscientiousCA, + title={Conscientious Classification: A Data Scientist's Guide to Discrimination-Aware Classification}, + author={Brian d'Alessandro and Cathy O'Neil and Tom LaGatta}, + journal={Big data}, + year={2017}, + volume={5 2}, + pages={ + 120-134 + }, + url={https://api.semanticscholar.org/CorpusID:4414223} +} + +@ARTICLE{beletal2019, + author={Bellamy, R. K. E. and Dey, K. and Hind, M. and Hoffman, S. C. and Houde, S. and Kannan, K. and Lohia, P. and Martino, J. and Mehta, S. and Mojsilović, A. and Nagar, S. and Ramamurthy, K. Natesan and Richards, J. and Saha, D. and Sattigeri, P. and Singh, M. and Varshney, K. R. and Zhang, Y.}, + journal={IBM Journal of Research and Development}, + title={AI Fairness 360: An extensible toolkit for detecting and mitigating algorithmic bias}, + year={2019}, + volume={63}, + number={4/5}, + pages={4:1-15}, + doi={10.1147/JRD.2019.2942287}} + +@ARTICLE{fuetal2020, +author={Runshan Fu and Yan Huang and Param Vir Singh}, +journal={INFORMS TutORials in Operations Research}, +title={Artificial Intelligence and Algorithmic Bias: Source, Detection, Mitigation, and Implications}, +year={2020}, +pages={39-63} +} + + +@INPROCEEDINGS{6413831, + + author={Kamiran, Faisal and Karim, Asim and Zhang, Xiangliang}, + + booktitle={2012 IEEE 12th International Conference on Data Mining}, + + title={Decision Theory for Discrimination-Aware Classification}, + + year={2012}, + + volume={}, + + number={}, + + pages={924-929}, + + doi={10.1109/ICDM.2012.45}} + + + +@inproceedings{NIPS2017_b8b9c74a, + author = {Pleiss, Geoff and Raghavan, Manish and Wu, Felix and Kleinberg, Jon and Weinberger, Kilian Q}, + booktitle = {Advances in Neural Information Processing Systems}, + editor = {I. Guyon and U. Von Luxburg and S. Bengio and H. Wallach and R. Fergus and S. Vishwanathan and R. Garnett}, + pages = {}, + publisher = {Curran Associates, Inc.}, + title = {On Fairness and Calibration}, + url = {https://proceedings.neurips.cc/paper_files/paper/2017/file/b8b9c74ac526fffbeb2d39ab038d1cd7-Paper.pdf}, + volume = {30}, + year = {2017} +} + + + +@inproceedings{NIPS2016_9d268236, + author = {Hardt, Moritz and Price, Eric and Price, Eric and Srebro, Nati}, + booktitle = {Advances in Neural Information Processing Systems}, + editor = {D. Lee and M. Sugiyama and U. Luxburg and I. Guyon and R. Garnett}, + pages = {}, + publisher = {Curran Associates, Inc.}, + title = {Equality of Opportunity in Supervised Learning}, + url = {https://proceedings.neurips.cc/paper_files/paper/2016/file/9d2682367c3935defcb1f9e247a97c0d-Paper.pdf}, + volume = {29}, + year = {2016} +} + + +@article{dAlessandro2017ConscientiousCA, + title={Conscientious Classification: A Data Scientist's Guide to Discrimination-Aware Classification}, + author={Brian d'Alessandro and Cathy O'Neil and Tom LaGatta}, + journal={Big data}, + year={2017}, + volume={5 2}, + pages={ + 120-134 + }, + url={https://api.semanticscholar.org/CorpusID:4414223} +} + +@misc{hrw, + title = {EU: Artificial Intelligence Regulation Should Protect People’s Rights}, + author = {{Human Rights Watch}}, + year = 2023, + note = {\url{https://www.hrw.org/news/2023/07/12/eu-artificial-intelligence-regulation-should-protect-peoples-rights} [Accessed: October 2023]} +} + +@article{NINOADAN2021115424, +title = {Feature weighting methods: A review}, +journal = {Expert Systems with Applications}, +volume = {184}, +pages = {115424}, +year = {2021}, +issn = {0957-4174}, +doi = {https://doi.org/10.1016/j.eswa.2021.115424}, +url = {https://www.sciencedirect.com/science/article/pii/S0957417421008423}, +author = {Iratxe Niño-Adan and Diana Manjarres and Itziar Landa-Torres and Eva Portillo}, +keywords = {Feature weighting, Feature importance, Feature relevance, Review}, +abstract = {In the last decades, a wide portfolio of Feature Weighting (FW) methods have been proposed in the literature. Their main potential is the capability to transform the features in order to contribute to the Machine Learning (ML) algorithm metric proportionally to their estimated relevance for inferring the output pattern. Nevertheless, the extensive number of FW related works makes difficult to do a scientific study in this field of knowledge. Therefore, in this paper a global taxonomy for FW methods is proposed by focusing on: (1) the learning approach (supervised or unsupervised), (2) the methodology used to calculate the weights (global or local), and (3) the feedback obtained from the ML algorithm when estimating the weights (filter or wrapper). Among the different taxonomy levels, an extensive review of the state-of-the-art is presented, followed by some considerations and guide points for the FW strategies selection regarding significant aspects of real-world data analysis problems. Finally, a summary of conclusions and challenges in the FW field is briefly outlined.} +} + + +% incollection (has an editor, title, and possibly a booktitle) +@Incollection{Douglass98, + author = "Bruce P. Douglass and David Harel and Mark B. Trakhtenbrot", + title = "Statecarts in use: structured analysis and object-orientation", + series = "Lecture Notes in Computer Science", + booktitle = "Lectures on Embedded Systems", + publisher = "Springer-Verlag", + address = "London", + volume = "1494", + year = "1998", + chapter = "", + editor = "Grzegorz Rozenberg and Frits W. Vaandrager", + pages = "368--394", + doi = "10.1007/3-540-65193-4_29", + OPTurl = "http://dx.doi.org/10.1007/3-540-65193-4_29", + edition = "", + number = "", + type = "", + month = "", + note = "", +} + + +@Book{Knuth97, + author = "Donald E. Knuth", + title = "The Art of Computer Programming, Vol. 1: Fundamental Algorithms (3rd. ed.)", + publisher = "Addison Wesley Longman Publishing Co., Inc.", + year = "1997", + address = "", + edition = "", + editor = "", + volume = "", + number = "", + series = "", + month = "", + note = "", +} + + +@Book{Knuth98, + author = "Donald E. Knuth", + year = "1998", + title = "The Art of Computer Programming", + series = "Fundamental Algorithms", + volume = "1", + edition = "3rd", + address = "", + publisher = "Addison Wesley Longman Publishing Co., Inc.", + doi = "", + url = "", + editor = "", + number = "", + month = "", + note = "(book)", +} + +%Inbook{Knuth97, +% author = "Donald E. Knuth", +% title = "The Art of Computer Programming", +% booktitle = "the booktitle", +% edition = "3", +% volume = "1", +% year = "1997", +% publisher = "Addison Wesley Longman Publishing Co., Inc.", +% editor = "", +% number = "", +% series = "Fundamental Algorithms", +% type = "", +% chapter = "", +% pages = "", +% address = "", +% month = "", +% note = "(inbook)", +%} + +%INBOOK{DK:73-inbook-full, +% author = "Donald E. Knuth", +% title = "Fundamental Algorithms (inbook w series)", +% volume = 1, +% series = "The Art of Computer Programming", +% publisher = "Addison-Wesley", +% address = "Reading, Massachusetts", +% edition = "Second", +% month = "10~" # jan, +% year = "1973", +% type = "Section", +% chapter = "1.2", +% pages = "10--119", +% note = "Full INBOOK entry (w series)", +%} + +%INcollection{DK:74-incoll, +% author = "Donald E. Knuth", +% title = "Fundamental Algorithms (incoll)", +% volume = 1, +% booktitle = "The Art of Computer Programming", +% publisher = "Addison-Wesley", +% address = "Reading, Massachusetts", +% month = "10~" # jan, +% year = "1974", +% pages = "10--119", +% editor = "Bernard Rous", +% note = "This is a full incoll entry with an editor", +%} + +%INcollection{DK:75-incollws, +% author = "Donald E. Knuth", +% title = "Fundamental Algorithms (incoll w series)", +% volume = 1, +% booktitle = "The Art of Computer Programming", +% series = "The Art of Computer Programming", +% publisher = "Addison-Wesley", +% address = "Reading, Massachusetts", +% month = "10~" # jan, +% year = "1975", +% pages = "10--119", +% editor = "Bernard Rous", +% note = "This is a full incoll entry with an editor and series", +%} + + +@incollection{GM05, +Author= "Dan Geiger and Christopher Meek", +Title= "Structured Variational Inference Procedures and their Realizations (as incol)", +Year= 2005, +Booktitle="Proceedings of Tenth International Workshop on Artificial Intelligence and Statistics, {\rm The Barbados}", +Publisher="The Society for Artificial Intelligence and Statistics", +Month= jan, +Editors= "Z. Ghahramani and R. Cowell" +} + +@Inproceedings{Smith10, + author = "Stan W. Smith", + title = "An experiment in bibliographic mark-up: Parsing metadata for XML export", + booktitle = "Proceedings of the 3rd. annual workshop on Librarians and Computers", + series = "LAC '10", + editor = "Reginald N. Smythe and Alexander Noble", + volume = "3", + year = "2010", + publisher = "Paparazzi Press", + address = "Milan Italy", + pages = "422--431", + doi = "99.9999/woot07-S422", + OPTurl = "http://dx.doi.org/99.0000/woot07-S422", + number = "", + month = "", + organization = "", + note = "", +} + +@Inproceedings{VanGundy07, + author = "Matthew Van Gundy and Davide Balzarotti and Giovanni Vigna", + year = "2007", + title = "Catch me, if you can: Evading network signatures with web-based polymorphic worms", + booktitle = "Proceedings of the first USENIX workshop on Offensive Technologies", + series = "WOOT '07", + publisher = "USENIX Association", + address = "Berkley, CA", + articleno = "7", + numpages = "9", + editor = "", + volume = "", + number = "", + pages = "", + month = "", + organization = "", + note = "", +} + +@Inproceedings{VanGundy08, + author = "Matthew Van Gundy and Davide Balzarotti and Giovanni Vigna", + year = "2008", + title = "Catch me, if you can: Evading network signatures with web-based polymorphic worms", + booktitle = "Proceedings of the first USENIX workshop on Offensive Technologies", + series = "WOOT '08", + publisher = "USENIX Association", + address = "Berkley, CA", + articleno = "7", + numpages = "2", + editor = "", + volume = "", + number = "", + pages = "99-100", + month = "", + organization = "", + note = "", +} + +@Inproceedings{VanGundy09, + author = "Matthew Van Gundy and Davide Balzarotti and Giovanni Vigna", + year = "2009", + title = "Catch me, if you can: Evading network signatures with web-based polymorphic worms", + booktitle = "Proceedings of the first USENIX workshop on Offensive Technologies", + series = "WOOT '09", + publisher = "USENIX Association", + address = "Berkley, CA", + articleno = "", + numpages = "", + editor = "", + volume = "", + number = "", + pages = "90--100", + month = "", + organization = "", + note = "", +} + +@Inproceedings{Andler79, + author = "Sten Andler", + title = "Predicate Path expressions", + booktitle = "Proceedings of the 6th. ACM SIGACT-SIGPLAN symposium on Principles of Programming Languages", + series = "POPL '79", + year = "1979", + publisher = "ACM Press", + address = "New York, NY", + pages = "226--236", + doi = "10.1145/567752.567774", + OPTurl = "http://doi.acm.org/10.1145/567752.567774", + editor = "", + volume = "", + number = "", + month = "", + organization = "", + note = "", +} + +@Techreport{Harel78, + author = "David Harel", + year = "1978", + title = "LOGICS of Programs: AXIOMATICS and DESCRIPTIVE POWER", + institution = "Massachusetts Institute of Technology", + type = "MIT Research Lab Technical Report", + number = "TR-200", + address = "Cambridge, MA", + month = "", + note = "", +} + +@MASTERSTHESIS{anisi03, +author = {David A. Anisi}, +title = {Optimal Motion Control of a Ground Vehicle}, +school = {Royal Institute of Technology (KTH), Stockholm, Sweden}, +intitution = {FOI-R-0961-SE, Swedish Defence Research Agency (FOI)}, +year = {2003}, +} + + +@Phdthesis{Clarkson85, + author = "Kenneth L. Clarkson", + year = "1985", + title = "Algorithms for Closest-Point Problems (Computational Geometry)", + school = "Stanford University", + address = "Palo Alto, CA", + note = "UMI Order Number: AAT 8506171", + type = "", + month = "", +} + + +@misc{Thornburg01, + author = "Harry Thornburg", + year = "2001", + title = "Introduction to Bayesian Statistics", + url = "http://ccrma.stanford.edu/~jos/bayes/bayes.html", + month = mar, + lastaccessed = "March 2, 2005", +} + + +@misc{Ablamowicz07, + author = "Rafal Ablamowicz and Bertfried Fauser", + year = "2007", + title = "CLIFFORD: a Maple 11 Package for Clifford Algebra Computations, version 11", + url = "http://math.tntech.edu/rafal/cliff11/index.html", + lastaccessed = "February 28, 2008", +} + + +@misc{Poker06, + author = "Poker-Edge.Com", + year = "2006", + month = mar, + title = "Stats and Analysis", + lastaccessed = "June 7, 2006", + url = "http://www.poker-edge.com/stats.php", +} + +@misc{Obama08, + author = "Barack Obama", + year = "2008", + title = "A more perfect union", + howpublished = "Video", + day = "5", + url = "http://video.google.com/videoplay?docid=6528042696351994555", + month = mar, + lastaccessed = "March 21, 2008", + note = "", +} + +@misc{JoeScientist001, + author = "Joseph Scientist", + year = "2009", + title = "The fountain of youth", + note = "Patent No. 12345, Filed July 1st., 2008, Issued Aug. 9th., 2009", + url = "", + howpublished = "", + month = aug, + lastaccessed = "", +} + + +@Inproceedings{Novak03, + author = "Dave Novak", + title = "Solder man", + booktitle = "ACM SIGGRAPH 2003 Video Review on Animation theater Program: Part I - Vol. 145 (July 27--27, 2003)", + year = "2003", + publisher = "ACM Press", + address = "New York, NY", + pages = "4", + month = "March 21, 2008", + doi = "99.9999/woot07-S422", + url = "http://video.google.com/videoplay?docid=6528042696351994555", + note = "", + howpublished = "Video", + editor = "", + volume = "", + number = "", + series = "", + organization = "", +} + + +@article{Lee05, + author = "Newton Lee", + year = "2005", + title = "Interview with Bill Kinder: January 13, 2005", + journal = "Comput. Entertain.", + eid = "4", + volume = "3", + number = "1", + month = "Jan.-March", + doi = "10.1145/1057270.1057278", + OPTurl = "http://doi.acm.org/10.1145/1057270.1057278", + howpublished = "Video", + note = "", +} + +@article{Rous08, + author = "Bernard Rous", + year = "2008", + title = "The Enabling of Digital Libraries", + journal = "Digital Libraries", + volume = "12", + number = "3", + month = jul, + articleno = "5", + doi = "", + url = "", + howpublished = "", + note = "To appear", +} + +@article{384253, + author = {Werneck,, Renato and Setubal,, Jo\~{a}o and da Conceic\~{a}o,, Arlindo}, + title = {(old) Finding minimum congestion spanning trees}, + journal = {J. Exp. Algorithmics}, + volume = {5}, + year = {2000}, + issn = {1084-6654}, + pages = {11}, + doi = {10.1145/351827.384253}, + publisher = {ACM}, + address = {New York, NY, USA}, + } + + +@article{Werneck:2000:FMC:351827.384253, + author = {Werneck, Renato and Setubal, Jo\~{a}o and da Conceic\~{a}o, Arlindo}, + title = {(new) Finding minimum congestion spanning trees}, + journal = {J. Exp. Algorithmics}, + volume = {5}, + month = dec, + year = {2000}, + issn = {1084-6654}, + articleno = {11}, + OPTurl = {http://portal.acm.org/citation.cfm?id=351827.384253}, + doi = {10.1145/351827.384253}, + acmid = {384253}, + publisher = {ACM}, + address = {New York, NY, USA}, +} + +@article{1555162, + author = {Conti, Mauro and Di Pietro, Roberto and Mancini, Luigi V. and Mei, Alessandro}, + title = {(old) Distributed data source verification in wireless sensor networks}, + journal = {Inf. Fusion}, + volume = {10}, + number = {4}, + year = {2009}, + issn = {1566-2535}, + pages = {342--353}, + doi = {10.1016/j.inffus.2009.01.002}, + publisher = {Elsevier Science Publishers B. V.}, + address = {Amsterdam, The Netherlands, The Netherlands}, + } + +@article{Conti:2009:DDS:1555009.1555162, + author = {Conti, Mauro and Di Pietro, Roberto and Mancini, Luigi V. and Mei, Alessandro}, + title = {(new) Distributed data source verification in wireless sensor networks}, + journal = {Inf. Fusion}, + volume = {10}, + number = {4}, + month = oct, + year = {2009}, + issn = {1566-2535}, + pages = {342--353}, + numpages = {12}, + OPTurl = {http://portal.acm.org/citation.cfm?id=1555009.1555162}, + doi = {10.1016/j.inffus.2009.01.002}, + acmid = {1555162}, + publisher = {Elsevier Science Publishers B. V.}, + address = {Amsterdam, The Netherlands, The Netherlands}, + keywords = {Clone detection, Distributed protocol, Securing data fusion, Wireless sensor networks}, +} + +@inproceedings{Li:2008:PUC:1358628.1358946, + author = {Li, Cheng-Lun and Buyuktur, Ayse G. and Hutchful, David K. and Sant, Natasha B. and Nainwal, Satyendra K.}, + title = {Portalis: using competitive online interactions to support aid initiatives for the homeless}, + booktitle = {CHI '08 extended abstracts on Human factors in computing systems}, + year = {2008}, + isbn = {978-1-60558-012-X}, + location = {Florence, Italy}, + pages = {3873--3878}, + numpages = {6}, + OPTurl = {http://portal.acm.org/citation.cfm?id=1358628.1358946}, + doi = {10.1145/1358628.1358946}, + acmid = {1358946}, + publisher = {ACM}, + address = {New York, NY, USA}, + keywords = {cscw, distributed knowledge acquisition, incentive design, online games, recommender systems, reputation systems, user studies, virtual community}, +} + +@book{Hollis:1999:VBD:519964, + author = {Hollis, Billy S.}, + title = {Visual Basic 6: Design, Specification, and Objects with Other}, + year = {1999}, + isbn = {0130850845}, + edition = {1st}, + publisher = {Prentice Hall PTR}, + address = {Upper Saddle River, NJ, USA}, + } + + +@book{Goossens:1999:LWC:553897, + author = {Goossens, Michel and Rahtz, S. P. and Moore, Ross and Sutor, Robert S.}, + title = {The Latex Web Companion: Integrating TEX, HTML, and XML}, + year = {1999}, + isbn = {0201433117}, + edition = {1st}, + publisher = {Addison-Wesley Longman Publishing Co., Inc.}, + address = {Boston, MA, USA}, + } + +% need to test genres for errant isbn output + +% techreport +@techreport{897367, + author = {Buss, Jonathan F. and Rosenberg, Arnold L. and Knott, Judson D.}, + title = {Vertex Types in Book-Embeddings}, + year = {1987}, + source = {http://www.ncstrl.org:8900/ncstrl/servlet/search?formname=detail\&id=oai%3Ancstrlh%3Aumass_cs%3Ancstrl.umassa_cs%2F%2FUM-CS-1987-018}, + publisher = {University of Massachusetts}, + address = {Amherst, MA, USA}, + } + +@techreport{Buss:1987:VTB:897367, + author = {Buss, Jonathan F. and Rosenberg, Arnold L. and Knott, Judson D.}, + title = {Vertex Types in Book-Embeddings}, + year = {1987}, + source = {http://www.ncstrl.org:8900/ncstrl/servlet/search?formname=detail\&id=oai%3Ancstrlh%3Aumass_cs%3Ancstrl.umassa_cs%2F%2FUM-CS-1987-018}, + publisher = {University of Massachusetts}, + address = {Amherst, MA, USA}, + } + +% whole proceedings + +@proceedings{Czerwinski:2008:1358628, + author = {}, + note = {General Chair-Czerwinski, Mary and General Chair-Lund, Arnie and Program Chair-Tan, Desney}, + title = {CHI '08: CHI '08 extended abstracts on Human factors in computing systems}, + year = {2008}, + isbn = {978-1-60558-012-X}, + location = {Florence, Italy}, + order_no = {608085}, + publisher = {ACM}, + address = {New York, NY, USA}, + } + +% phdthesis + +@phdthesis{Clarkson:1985:ACP:911891, + author = {Clarkson, Kenneth Lee}, + advisor = {Yao, Andrew C.}, + title = {Algorithms for Closest-Point Problems (Computational Geometry)}, + year = {1985}, + note = {AAT 8506171}, + school = {Stanford University}, + address = {Stanford, CA, USA}, + } +% school is being picked up -- but not publisher (which is OK) +% Also -- the title is NOT being output in italics !!! Arrrrgh! - I fixed it. :-) + + +%%% compare with 'old' +%%% atsign-Phdthesis{Clarkson85, +%%% author = "Kenneth L. Clarkson", +%%% year = "1985", +%%% title = "Algorithms for Closest-Point Problems (Computational Geometry)", +%%% school = "Stanford University", +%%% address = "Palo Alto, CA", +%%% note = "UMI Order Number: AAT 8506171", +%%% type = "", +%%% month = "", +%%%} + +% A bibliography +@Article{1984:1040142, + key = {{$\!\!$}}, + journal = {SIGCOMM Comput. Commun. Rev.}, + year = {1984}, + issn = {0146-4833}, + volume = {13-14}, + number = {5-1}, + issue_date = {January/April 1984}, + publisher = {ACM}, + address = {New York, NY, USA}, + } + + +% grinder +@inproceedings{2004:ITE:1009386.1010128, + key = {IEEE}, + title = {IEEE TCSC Executive Committee}, + booktitle = {Proceedings of the IEEE International Conference on Web Services}, + series = {ICWS '04}, + year = {2004}, + isbn = {0-7695-2167-3}, + pages = {21--22}, + OPTurl = {http://dx.doi.org/10.1109/ICWS.2004.64}, + doi = {10.1109/ICWS.2004.64}, + acmid = {1010128}, + publisher = {IEEE Computer Society}, + address = {Washington, DC, USA}, +} + +% div book +@book{Mullender:1993:DS(:302430, + editor = {Mullender, Sape}, + title = {Distributed systems (2nd Ed.)}, + year = {1993}, + isbn = {0-201-62427-3}, + publisher = {ACM Press/Addison-Wesley Publishing Co.}, + address = {New York, NY, USA}, + } + +% master thesis (as techreport and thesis) + +@techreport{Petrie:1986:NAD:899644, + author = {Petrie, Charles J.}, + title = {New Algorithms for Dependency-Directed Backtracking (Master's thesis)}, + year = {1986}, + source = {http://www.ncstrl.org:8900/ncstrl/servlet/search?formname=detail\&id=oai%3Ancstrlh%3Autexas_cs%3AUTEXAS_CS%2F%2FAI86-33}, + publisher = {University of Texas at Austin}, + address = {Austin, TX, USA}, + } + +@MASTERSTHESIS{Petrie:1986:NAD:12345, + author = {Petrie, Charles J.}, + title = {New Algorithms for Dependency-Directed Backtracking (Master's thesis)}, + year = {1986}, + source = {http://www.ncstrl.org:8900/ncstrl/servlet/search?formname=detail\&id=oai%3Ancstrlh%3Autexas_cs%3AUTEXAS_CS%2F%2FAI86-33}, + school = {University of Texas at Austin}, + address = {Austin, TX, USA}, + } + + + + +@BOOK{book-minimal, + author = "Donald E. Knuth", + title = "Seminumerical Algorithms", + publisher = "Addison-Wesley", + year = "1981", +} + +% incollection (has an editor, title, and possibly a booktitle) +@INcollection{KA:2001, + author = {Kong, Wei-Chang}, + Title = {The implementation of electronic commerce in SMEs in Singapore (as Incoll)}, + booktitle = {E-commerce and cultural values}, + year = {2001}, + isbn = {1-59140-056-2}, + pages = {51--74}, + numpages = {24}, + OPTurl = {http://portal.acm.org/citation.cfm?id=887006.887010}, + acmid = {887010}, + publisher = {IGI Publishing}, + address = {Hershey, PA, USA}, +} + + +% with bibfield 'type' before chapter (note no editor) +@INBOOK{KAGM:2001, + author = {Kong, Wei-Chang}, + type = {Name of Chapter:}, + chapter = {The implementation of electronic commerce in SMEs in Singapore (Inbook-w-chap-w-type)}, + title = {E-commerce and cultural values}, + year = {2001}, + isbn = {1-59140-056-2}, + pages = {51--74}, + numpages = {24}, + OPTurl = {http://portal.acm.org/citation.cfm?id=887006.887010}, + acmid = {887010}, + publisher = {IGI Publishing}, + address = {Hershey, PA, USA}, +} + +%%% Notes! This is because the atsign-INBOOK citation type specifies EITHER +%%% editor or author, but not both. In my experiments with the harvard/dcu +%%% bibtex style (and presumably this applies to other styles too), bibtex +%%% ignores the editor information if author information exists in an +%%% atsign-INBOOK entry. atsign-INCOLLECTION is far more commonly used in my references, +%%% and in the absence of an editor I believe most bibtex styles will just +%%% ommit the editor from the reference - the chapter information will not +%%% end up in the in-text citation as you suggest it should be but at least +%%% there is a place to put the editor if necessary. + + + +% was 'Inbook' -- changed to incollection - (editor is different to author) - need to tell Asad to codify as such. +@incollection{Kong:2002:IEC:887006.887010, + author = {Kong, Wei-Chang}, + editor = {Theerasak Thanasankit}, + title = {Chapter 9}, + booktitle = {E-commerce and cultural values (Incoll-w-text (chap 9) 'title')}, + year = {2002}, + address = {Hershey, PA, USA}, + publisher = {IGI Publishing}, + OPTurl = {http://portal.acm.org/citation.cfm?id=887006.887010}, + pages = {51--74}, + numpages = {24}, + acmid = {887010}, + isbn = {1-59140-056-2}, + number = "", + type = "", + month = "", + note = "", +} + +% incol when the chapter is 'text' - due to presence of editor (different to author) +@incollection{Kong:2003:IEC:887006.887011, + author = {Kong, Wei-Chang}, + title = {The implementation of electronic commerce in SMEs in Singapore (Incoll)}, + booktitle = {E-commerce and cultural values}, + editor = {Thanasankit, Theerasak}, + year = {2003}, + isbn = {1-59140-056-2}, + pages = {51--74}, + numpages = {24}, + OPTurl = {http://portal.acm.org/citation.cfm?id=887006.887010}, + acmid = {887010}, + publisher = {IGI Publishing}, + address = {Hershey, PA, USA}, +} + +% ------ test +%incollection{Kong:2003:IEC:887006.887010, +% author = {Kong, Wei-Chang}, +% chapter = {The implementation of electronic commerce in SMEs in Singapore (Incoll-text-in-chap)}, +% booktitle = {booktitle E-commerce and cultural values}, +% title = {The title}, +% editor = {Thanasankit, Theerasak}, +% year = {2003}, +% isbn = {1-59140-056-2}, +% pages = {51--74}, +% numpages = {24}, +% url = {http://portal.acm.org/citation.cfm?id=887006.887010}, +% acmid = {887010}, +% publisher = {IGI Publishing}, +% address = {Hershey, PA, USA}, +%} + + +% --------- + + + + + +% Need inbook with num in chapter + +% and inbook with number in chapter +@InBook{Kong:2004:IEC:123456.887010, + author = {Kong, Wei-Chang}, + editor = {Theerasak Thanasankit}, + title = {E-commerce and cultural values - (InBook-num-in-chap)}, + chapter = {9}, + year = {2004}, + address = {Hershey, PA, USA}, + publisher = {IGI Publishing}, + OPTurl = {http://portal.acm.org/citation.cfm?id=887006.887010}, + pages = {51--74}, + numpages = {24}, + acmid = {887010}, + isbn = {1-59140-056-2}, + number = "", + type = "", + month = "", + note = "", +} + + +% and inbook with text in chapter +@Inbook{Kong:2005:IEC:887006.887010, + author = {Kong, Wei-Chang}, + editor = {Theerasak Thanasankit}, + title = {E-commerce and cultural values (Inbook-text-in-chap)}, + chapter = {The implementation of electronic commerce in SMEs in Singapore}, + year = {2005}, + address = {Hershey, PA, USA}, + publisher = {IGI Publishing}, + OPTurl = {http://portal.acm.org/citation.cfm?id=887006.887010}, + type = {Chapter:}, + pages = {51--74}, + numpages = {24}, + acmid = {887010}, + isbn = {1-59140-056-2}, + number = "", + month = "", + note = "", +} + + +% and inbook with a num and type field +@Inbook{Kong:2006:IEC:887006.887010, + author = {Kong, Wei-Chang}, + editor = {Theerasak Thanasankit}, + title = {E-commerce and cultural values (Inbook-num chap)}, + chapter = {22}, + year = {2006}, + address = {Hershey, PA, USA}, + publisher = {IGI Publishing}, + OPTurl = {http://portal.acm.org/citation.cfm?id=887006.887010}, + type = {Chapter (in type field)}, + pages = {51--74}, + numpages = {24}, + acmid = {887010}, + isbn = {1-59140-056-2}, + number = "", + month = "", + note = "", +} + + +% and incol coz we have a BLANK chapter - due to presence of editor +%atIncollection{Kong:2006:IEC:887006.887011, +% author = {Kong, Wei-Chang}, +% editor = {Theerasak Thanasankit}, +% title = "The title" +% booktitle = {E-commerce and cultural values (Incol-coz-blank-chap)}, +% year = {2006}, +% address = {Hershey, PA, USA}, +% publisher = {IGI Publishing}, +% url = {http://portal.acm.org/citation.cfm?id=887006.887010}, +% type = {Type!}, +% chapter = {}, +% pages = {51--74}, +% numpages = {24}, +% acmid = {887010}, +% isbn = {1-59140-056-2}, +% number = "", +% month = "", +% note = "", +%} + +@article{SaeediMEJ10, + author = {Mehdi Saeedi and Morteza Saheb Zamani and Mehdi Sedighi}, + title = {A library-based synthesis methodology for reversible logic}, + journal = {Microelectron. J.}, + volume = {41}, + number = {4}, + month = apr, + year = {2010}, + pages = {185--194}, +} + +@ARTICLE{SaeediJETC10, + author = {Mehdi Saeedi and Morteza Saheb Zamani and Mehdi Sedighi and Zahra Sasanian}, + title = {Synthesis of Reversible Circuit Using Cycle-Based Approach}, + journal = {J. Emerg. Technol. Comput. Syst.}, + volume = {6}, + number = {4}, + month = dec, + year = {2010} + } + +% Asad's new version +@article{Kirschmer:2010:AEI:1958016.1958018, + author = {Kirschmer, Markus and Voight, John}, + title = {Algorithmic Enumeration of Ideal Classes for Quaternion Orders}, + journal = {SIAM J. Comput.}, + issue_date = {January 2010}, + volume = {39}, + number = {5}, + month = jan, + year = {2010}, + issn = {0097-5397}, + pages = {1714--1747}, + numpages = {34}, + url = {http://dx.doi.org/10.1137/080734467}, + doi = {10.1137/080734467}, + acmid = {1958018}, + publisher = {Society for Industrial and Applied Mathematics}, + address = {Philadelphia, PA, USA}, + keywords = {ideal classes, maximal orders, number theory, quaternion algebras}, +} + +@inproceedings{10.1145/3194770.3194776, +author = {Verma, Sahil and Rubin, Julia}, +title = {Fairness Definitions Explained}, +year = {2018}, +isbn = {9781450357463}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +url = {https://doi.org/10.1145/3194770.3194776}, +doi = {10.1145/3194770.3194776}, +abstract = {Algorithm fairness has started to attract the attention of researchers in AI, Software Engineering and Law communities, with more than twenty different notions of fairness proposed in the last few years. Yet, there is no clear agreement on which definition to apply in each situation. Moreover, the detailed differences between multiple definitions are difficult to grasp. To address this issue, this paper collects the most prominent definitions of fairness for the algorithmic classification problem, explains the rationale behind these definitions, and demonstrates each of them on a single unifying case-study. Our analysis intuitively explains why the same case can be considered fair according to some definitions and unfair according to others.}, +booktitle = {Proceedings of the International Workshop on Software Fairness}, +pages = {1–7}, +numpages = {7}, +location = {Gothenburg, Sweden}, +series = {FairWare '18} +} + +@misc{chouldechova2018frontiers, + title={The Frontiers of Fairness in Machine Learning}, + author={Alexandra Chouldechova and Aaron Roth}, + year={2018}, + eprint={1810.08810}, + archivePrefix={arXiv}, + primaryClass={cs.LG} +} + +@online{fairness_catalogue, + author = {OECD.AI}, + title = {Catalogue of Tools and Metrics for Trustworthy AI}, + url = {https://oecd.ai/en/catalogue/metrics?objectiveIds=2&page=1 +} + +@article{Castelnovo_2022, + doi = {10.1038/s41598-022-07939-1}, +title = {The Zoo of Fairness Metrics in Machine Learning}, +author={Alessandro Castelnovo and Riccardo Crupi and Greta Greco and Daniele Regoli and Ilaria Giuseppina Penco and Andrea Claudio Cosentini}, + url = {https://doi.org/10.1038%2Fs41598-022-07939-1}, + + year = 2022, + month = {mar}, + + publisher = {Springer Science and Business Media {LLC} +} + +% incol due to presence of booktitle +@incollection{Hoare:1972:CIN:1243380.1243382, + author = {Hoare, C. A. R.}, + title = {Chapter II: Notes on data structuring}, + booktitle = {Structured programming (incoll)}, + editor = {Dahl, O. J. and Dijkstra, E. W. and Hoare, C. A. R.}, + year = {1972}, + isbn = {0-12-200550-3}, + pages = {83--174}, + numpages = {92}, + OPTurl = {http://portal.acm.org/citation.cfm?id=1243380.1243382}, + acmid = {1243382}, + publisher = {Academic Press Ltd.}, + address = {London, UK, UK}, +} + +% incol due to presence of booktitle +@incollection{Lee:1978:TQA:800025.1198348, + author = {Lee, Jan}, + title = {Transcript of question and answer session}, + booktitle = {History of programming languages I (incoll)}, + editor = {Wexelblat, Richard L.}, + year = {1981}, + isbn = {0-12-745040-8}, + pages = {68--71}, + numpages = {4}, + OPTurl = {http://doi.acm.org/10.1145/800025.1198348}, + doi = {10.1145/800025.1198348}, + acmid = {1198348}, + publisher = {ACM}, + address = {New York, NY, USA}, +} + +% incol due to booktitle +@incollection{Dijkstra:1979:GSC:1241515.1241518, + author = {Dijkstra, E.}, + title = {Go to statement considered harmful}, + booktitle = {Classics in software engineering (incoll)}, + year = {1979}, + isbn = {0-917072-14-6}, + pages = {27--33}, + numpages = {7}, + OPTurl = {http://portal.acm.org/citation.cfm?id=1241515.1241518}, + acmid = {1241518}, + publisher = {Yourdon Press}, + address = {Upper Saddle River, NJ, USA}, +} + +% incol due to booktitle +@incollection{Wenzel:1992:TVA:146022.146089, + author = {Wenzel, Elizabeth M.}, + title = {Three-dimensional virtual acoustic displays}, + booktitle = {Multimedia interface design (incoll)}, + year = {1992}, + isbn = {0-201-54981-6}, + pages = {257--288}, + numpages = {32}, + OPTurl = {http://portal.acm.org/citation.cfm?id=146022.146089}, + doi = {10.1145/146022.146089}, + acmid = {146089}, + publisher = {ACM}, + address = {New York, NY, USA}, +} + +% incol due to booktitle +@incollection{Mumford:1987:MES:54905.54911, + author = {Mumford, E.}, + title = {Managerial expert systems and organizational change: some critical research issues}, + booktitle = {Critical issues in information systems research (incoll)}, + year = {1987}, + isbn = {0-471-91281-6}, + pages = {135--155}, + numpages = {21}, + OPTurl = {http://portal.acm.org/citation.cfm?id=54905.54911}, + acmid = {54911}, + publisher = {John Wiley \& Sons, Inc.}, + address = {New York, NY, USA}, +} + +@book{McCracken:1990:SSC:575315, + author = {McCracken, Daniel D. and Golden, Donald G.}, + title = {Simplified Structured COBOL with Microsoft/MicroFocus COBOL}, + year = {1990}, + isbn = {0471514071}, + publisher = {John Wiley \& Sons, Inc.}, + address = {New York, NY, USA}, +} + +% Let's include Boris / BBeeton entries (multi-volume works) + +@book {MR781537, + AUTHOR = {H{\"o}rmander, Lars}, + TITLE = {The analysis of linear partial differential operators. {III}}, + SERIES = {Grundlehren der Mathematischen Wissenschaften [Fundamental + Principles of Mathematical Sciences]}, + VOLUME = {275}, + NOTE = {Pseudodifferential operators}, +PUBLISHER = {Springer-Verlag}, + ADDRESS = {Berlin, Germany}, + YEAR = {1985}, + PAGES = {viii+525}, + ISBN = {3-540-13828-5}, + MRCLASS = {35-02 (35Sxx 47G05 58G15)}, + MRNUMBER = {781536 (87d:35002a)}, +MRREVIEWER = {Min You Qi}, +} + +@book {MR781536, + AUTHOR = {H{\"o}rmander, Lars}, + TITLE = {The analysis of linear partial differential operators. {IV}}, + SERIES = {Grundlehren der Mathematischen Wissenschaften [Fundamental + Principles of Mathematical Sciences]}, + VOLUME = {275}, + NOTE = {Fourier integral operators}, +PUBLISHER = {Springer-Verlag}, + ADDRESS = {Berlin, Germany}, + YEAR = {1985}, + PAGES = {vii+352}, + ISBN = {3-540-13829-3}, + MRCLASS = {35-02 (35Sxx 47G05 58G15)}, + MRNUMBER = {781537 (87d:35002b)}, +MRREVIEWER = {Min You Qi}, +} + +%%%%%%%%%%%%%%%%%%%%%% Start of Aptara sample bib entries + +% acmsmall-sam.bib +@InProceedings{Adya-01, + author = {A. Adya and P. Bahl and J. Padhye and A.Wolman and L. Zhou}, + title = {A multi-radio unification protocol for {IEEE} 802.11 wireless networks}, + booktitle = {Proceedings of the IEEE 1st International Conference on Broadnets Networks (BroadNets'04)}, + publisher = "IEEE", + address = "Los Alamitos, CA", + year = {2004}, + pages = "210--217" +} + +@article{Akyildiz-01, + author = {I. F. Akyildiz and W. Su and Y. Sankarasubramaniam and E. Cayirci}, + title = {Wireless Sensor Networks: A Survey}, + journal = {Comm. ACM}, + volume = 38, + number = "4", + year = {2002}, + pages = "393--422" +} + +@article{Akyildiz-02, + author = {I. F. Akyildiz and T. Melodia and K. R. Chowdhury}, + title = {A Survey on Wireless Multimedia Sensor Networks}, + journal = {Computer Netw.}, + volume = 51, + number = "4", + year = {2007}, + pages = "921--960" +} + +@InProceedings{Bahl-02, + author = {P. Bahl and R. Chancre and J. Dungeon}, + title = {{SSCH}: Slotted Seeded Channel Hopping for Capacity Improvement in {IEEE} 802.11 Ad-Hoc Wireless Networks}, + booktitle = {Proceeding of the 10th International Conference on Mobile Computing and Networking (MobiCom'04)}, + publisher = "ACM", + address = "New York, NY", + year = {2004}, + pages = "112--117" +} + +@misc{CROSSBOW, + key = {CROSSBOW}, + title = {{XBOW} Sensor Motes Specifications}, + note = {http://www.xbow.com}, + year = 2008 +} + +@article{Culler-01, + author = {D. Culler and D. Estrin and M. Srivastava}, + title = {Overview of Sensor Networks}, + journal = {IEEE Comput.}, + volume = 37, + number = "8 (Special Issue on Sensor Networks)", + publisher = "IEEE", + address = "Los Alamitos, CA", + year = {2004}, + pages = "41--49" +} + +@misc{Harvard-01, + key = {Harvard CodeBlue}, + title = {{CodeBlue}: Sensor Networks for Medical Care}, + note = {http://www.eecs.harvard.edu/mdw/ proj/codeblue/}, + year = 2008 +} + +@InProceedings{Natarajan-01, + author = {A. Natarajan and M. Motani and B. de Silva and K. Yap and K. C. Chua}, + title = {Investigating Network Architectures for Body Sensor Networks}, + booktitle = {Network Architectures}, + editor = {G. Whitcomb and P. Neece}, + publisher = "Keleuven Press", + address = "Dayton, OH", + year = {2007}, + pages = "322--328", + eprint = "960935712", + primaryclass = "cs", +} + +@techreport{Tzamaloukas-01, + author = {A. Tzamaloukas and J. J. Garcia-Luna-Aceves}, + title = {Channel-Hopping Multiple Access}, + number = {I-CA2301}, + institution = {Department of Computer Science, University of California}, + address = {Berkeley, CA}, + year = {2000} +} + +@BOOK{Zhou-06, + author = {G. Zhou and J. Lu and C.-Y. Wan and M. D. Yarvis and J. A. Stankovic}, + title = {Body Sensor Networks}, + publisher = "MIT Press", + address = "Cambridge, MA", + year = {2008} +} + +@mastersthesis{ko94, +author = "Jacob Kornerup", +title = "Mapping Powerlists onto Hypercubes", +school = "The University of Texas at Austin", +note = "(In preparation)", +year = "1994"} +%month = "dec",} + +@PhdThesis{gerndt:89, + author = "Michael Gerndt", + title = "Automatic Parallelization for Distributed-Memory + Multiprocessing Systems", + school = "University of Bonn", + year = 1989, + address = "Bonn, Germany", + month = dec +} + +@article{6:1:1, +author = "J. E. {Archer, Jr.} and R. Conway and F. B. Schneider", +title = "User recovery and reversal in interactive systems", +journal = "ACM Trans. Program. Lang. Syst.", +volume = "6", +number = "1", +month = jan, +year = 1984, +pages = "1--19"} + +@article{7:1:137, +author = "D. D. Dunlop and V. R. Basili", +title = "Generalizing specifications for uniformly implemented loops", +journal = "ACM Trans. Program. Lang. Syst.", +volume = "7", +number = "1", +month = jan, +year = 1985, +pages = "137--158"} + +@article{7:2:183, +author = "J. Heering and P. Klint", +title = "Towards monolingual programming environments", +journal = "ACM Trans. Program. Lang. Syst.", +volume = "7", +number = "2", +month = apr, +year = 1985, +pages = "183--213"} + +@book{knuth:texbook, +author = "Donald E. Knuth", +title = "The {\TeX{}book}", +publisher = "Addison-Wesley", +address = "Reading, MA.", +year = 1984} + +@article{6:3:380, +author = "E. Korach and D. Rotem and N. Santoro", +title = "Distributed algorithms for finding centers and medians in networks", +journal = "ACM Trans. Program. Lang. Syst.", +volume = "6", +number = "3", +month = jul, +year = 1984, +pages = "380--401"} + +@book{lamport:latex, +author = "Leslie Lamport", +title = "{\LaTeX}: A Document Preparation System", +publisher = "Addison-Wesley", +address = "Reading, MA.", +year = 1986} + +@article{7:3:359, +author = "F. Nielson", +title = "Program transformations in a denotational setting", +journal = "ACM Trans. Program. Lang. Syst.", +volume = "7", +number = "3", +month = jul, +year = 1985, +pages = "359--379"} + +%testing +@BOOK{test, + author = "Donald E. Knuth", + title = "Seminumerical Algorithms", + volume = 2, + series = "The Art of Computer Programming", + publisher = "Addison-Wesley", + address = "Reading, MA", + edition = "2nd", + month = "10~" # jan, + year = "1981", +} + +@article{dkl, +author = {S. Kullback and R. A. Leibler}, +title = {{On Information and Sufficiency}}, +volume = {22}, +journal = {The Annals of Mathematical Statistics}, +number = {1}, +publisher = {Institute of Mathematical Statistics}, +pages = {79 -- 86}, +year = {1951}, +doi = {10.1214/aoms/1177729694}, +URL = {https://doi.org/10.1214/aoms/1177729694} +} + + +@inproceedings{reid:scribe, +author = "Brian K. Reid", +title = "A high-level approach to computer document formatting", +booktitle = "Proceedings of the 7th Annual Symposium on Principles of + Programming Languages", +month = jan, +year = 1980, +publisher = "ACM", +address = "New York", +pages = "24--31"} + +@article{Zhou:2010:MMS:1721695.1721705, + author = {Zhou, Gang and Wu, Yafeng and Yan, Ting and He, Tian and Huang, Chengdu and Stankovic, John A. and Abdelzaher, Tarek F.}, + title = {A multifrequency MAC specially designed for wireless sensor network applications}, + journal = {ACM Trans. Embed. Comput. Syst.}, + issue_date = {March 2010}, + volume = 9, + number = 4, + month = {April}, + year = 2010, + issn = {1539-9087}, + pages = {39:1--39:41}, + articleno = 39, + numpages = 41, + OPTurl = {http://doi.acm.org/10.1145/1721695.1721705}, + doi = {10.1145/1721695.1721705}, + acmid = 1721705, + publisher = {ACM}, + address = {New York, NY, USA}, + keywords = {Wireless sensor networks, media access control, multi-channel, radio interference, time synchronization}, +} + + +@misc{TUGInstmem, + key = {TUG}, + year = 2017, + title = "Institutional members of the {\TeX} Users Group", + url = "http://www.tug.org/instmem.html", + lastaccessed = "May 27, 2017", +} + +@ARTICLE{bowman:reasoning, + author = {Bowman, Mic and Debray, Saumya K. and Peterson, Larry L.}, + title = {Reasoning About Naming Systems}, + journal = {ACM Trans. Program. Lang. Syst.}, + volume = {15}, + number = {5}, + pages = {795-825}, + month = {November}, + year = {1993}, + doi = {10.1145/161468.161471}, +} + +@ARTICLE{braams:babel, + author = {Braams, Johannes}, + title = {Babel, a Multilingual Style-Option System for Use with LaTeX's Standard Document Styles}, + journal = {TUGboat}, + volume = {12}, + number = {2}, + pages = {291-301}, + month = {June}, + year = {1991}, +} + +@INPROCEEDINGS{clark:pct, + AUTHOR = "Malcolm Clark", + TITLE = "Post Congress Tristesse", + BOOKTITLE = "TeX90 Conference Proceedings", + PAGES = "84-89", + ORGANIZATION = "TeX Users Group", + MONTH = "March", + YEAR = {1991} +} + +@ARTICLE{herlihy:methodology, + author = {Herlihy, Maurice}, + title = {A Methodology for Implementing Highly Concurrent Data Objects}, + journal = {ACM Trans. Program. Lang. Syst.}, + volume = {15}, + number = {5}, + pages = {745-770}, + month = {November}, + year = {1993}, + doi = {10.1145/161468.161469}, +} + +@BOOK{salas:calculus, + AUTHOR = "S.L. Salas and Einar Hille", + TITLE = "Calculus: One and Several Variable", + PUBLISHER = "John Wiley and Sons", + ADDRESS = "New York", + YEAR = "1978" +} + +@MANUAL{Fear05, + title = {Publication quality tables in {\LaTeX}}, + author = {Simon Fear}, + month = {April}, + year = 2005, + note = {\url{http://www.ctan.org/pkg/booktabs}} +} + +@Manual{Amsthm15, + title = {Using the amsthm Package}, + organization = {American Mathematical Society}, + month = {April}, + year = 2015, + note = {\url{http://www.ctan.org/pkg/amsthm}} +} + +@misc{R, + title = {R: A Language and Environment for Statistical Computing}, + author = {{R Core Team}}, + organization = {R Foundation for Statistical Computing}, + address = {Vienna, Austria}, + year = {2019}, + url = {https://www.R-project.org/}, +} + +@misc{UMassCitations, + author = {Sam Anzaroot and Andrew McCallum}, + title = {{UMass} Citation Field Extraction Dataset}, + year = 2013, + url = + {http://www.iesl.cs.umass.edu/data/data-umasscitationfield}, + lastaccessed = {May 27, 2019} +} diff --git a/tests/unit/TestBiasDetector.py b/tests/unit/TestBiasDetector.py index 56318b5..3b73142 100644 --- a/tests/unit/TestBiasDetector.py +++ b/tests/unit/TestBiasDetector.py @@ -1,6 +1,6 @@ import unittest import sys -from pickle import load +from pickle import load, dump from sklearn.model_selection import train_test_split import pandas as pd import numpy as np @@ -68,9 +68,14 @@ def test_compare_root_variable_groups_with_TVD(self): target_variable='predictions', root_variable='x2_sex', threshold=0.1) + + # Saving results for Risk tests + with open("./tests/unit/test_data/results_test_compare_root_variable_groups_with_TVD.pkl", "wb") as file: + dump(results, file) self.assertEqual(results[0], 0.025269625352224545) + def test_compare_root_variable_groups_with_JS(self): ''' Test the compare_root_variable_groups method against a @@ -85,6 +90,10 @@ def test_compare_root_variable_groups_with_JS(self): target_variable='predictions', root_variable='x2_sex', threshold=0.1) + + # Saving results for Risk tests + with open("./tests/unit/test_data/results_test_compare_root_variable_groups_with_JS.pkl", "wb") as file: + dump(results, file) self.assertEqual(results[0], 0.0011441803173238346) @@ -120,6 +129,11 @@ def test_compare_root_variable_groups_with_KL_and_ref_distribution(self): root_variable='x2_sex', threshold=0.1, reference_distribution=self.ref) + + # Saving results for Risk tests + with open("./tests/unit/test_data/results_test_compare_root_variable_groups_with_KL_and_ref_distribution.pkl", "wb") as file: + dump(results, file) + self.assertEqual(results[0], [0.07485260878313427, 0.11543085607355452]) def test_compare_root_variable_groups_with_KL_and_ref_distribution_probs(self): @@ -160,6 +174,10 @@ def test_compare_root_variable_conditioned_groups_with_TVD(self): ['x3_education', 'x4_marriage'], 0.1, min_obs_per_group=30) + + # Saving results for Risk tests + with open("./tests/unit/test_data/results_test_compare_root_variable_conditioned_groups_with_TVD.pkl", "wb") as file: + dump(results, file) violations = {k: v for k, v in results.items() if not v[2]} @@ -229,6 +247,10 @@ def test_compare_root_variable_conditioned_groups_with_KL_and_ref_distribution(s reference_distribution=self.ref, min_obs_per_group=30, threshold=0.1) + + # Saving results for Risk tests + with open("./tests/unit/test_data/results_test_compare_root_variable_conditioned_groups_with_KL_and_ref_distribution.pkl", "wb") as file: + dump(results, file) violations = {k: v for k, v in results.items() if (not v[2][0] or not v[2][1])} self.assertEqual(len(violations), 9) diff --git a/tests/unit/TestRiskCalculator.py b/tests/unit/TestRiskCalculator.py new file mode 100644 index 0000000..5f628d1 --- /dev/null +++ b/tests/unit/TestRiskCalculator.py @@ -0,0 +1,58 @@ +import unittest +from pickle import load +from sklearn.model_selection import train_test_split + +from brio.utils.Preprocessing import Preprocessing +from brio.risk.RiskCalculator import RiskCalculator +from brio.risk.HazardFromBiasDetectionCalculator import HazardFromBiasDetectionCalculator + +class TestRiskCalculator(unittest.TestCase): + + def setUp(self): + input_data_path = "./tests/unit/test_data/data.csv" + pp = Preprocessing(input_data_path, "default") + X, Y = pp.read_dataframe() + X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=420) + self.n_obs = X_test.shape[0] + self.conditioning_variables = ['x3_education', 'x4_marriage'] + + #### Import FreqVsRef results #### + with open("./tests/unit/test_data/results_test_compare_root_variable_conditioned_groups_with_KL_and_ref_distribution.pkl", "rb") as file: + self.results_ref_conditioned = load(file) + + with open("./tests/unit/test_data/results_test_compare_root_variable_groups_with_KL_and_ref_distribution.pkl", "rb") as file: + self.results_ref_overall = load(file) + + #### Import FreqVsFreq results #### + with open("./tests/unit/test_data/results_test_compare_root_variable_groups_with_TVD.pkl", "rb") as file: + self.results_freq_overall = load(file) + + with open("./tests/unit/test_data/results_test_compare_root_variable_conditioned_groups_with_TVD.pkl", "rb") as file: + self.results_freq_conditioned = load(file) + + + def test_risk_calculator(self): + ''' + Test the risk_calculator method, using a set of FreqVsFreq and + FreqVsRef results. The overall risk measure is a combination + coming from all the input results. + ''' + hc = HazardFromBiasDetectionCalculator() + + hazard_ref = hc.compute_hazard_from_freqvsfreq_or_freqvsref(self.results_ref_overall, + self.results_ref_conditioned, + self.n_obs, + self.conditioning_variables) + + hazard_freq = hc.compute_hazard_from_freqvsfreq_or_freqvsref(self.results_freq_overall, + self.results_freq_conditioned, + self.n_obs, + self.conditioning_variables) + + rc = RiskCalculator() + risk = rc.compute_risk(test_hazards=[hazard_ref, hazard_freq]) + + self.assertAlmostEqual(risk, 0.018531866342260846, delta=1e-8) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/tests/unit/test_data/results_test_compare_root_variable_conditioned_groups_with_KL_and_ref_distribution.pkl b/tests/unit/test_data/results_test_compare_root_variable_conditioned_groups_with_KL_and_ref_distribution.pkl new file mode 100644 index 0000000000000000000000000000000000000000..8b882a28dc752df331681afbe8c4d6c46ea3598b GIT binary patch literal 2666 zcmZo*nHtZ<00y;FGc7eaCWeX|ZBoA@fdxybg`4J0=bFwty^Hy_YIKflx-aliZ$ zh19(K()0|4{G{U4qB3x5DxT7g5fcVeyqO`oGQ5GZd=)0~xxj>#nV6mmNqi6a;jX-J z`9-0&$rfZ+c6jNl9~a+)ud#N?xFZ1}R<`#6J}?2+cwcr3)D+xUU~wjpPILJc$-c7$3JdC~%I#fn8P5%pp_ zk*zSe@2Ii=5j1YV#U+8r#_$F(WI<7lBVf5D_9ATPARD@NCk;7rCChr>}a17G)2Rkxrfnail3jK z*MA@Y6W$CZQ<9uH7^cfyl|4Gieo7lqT?R`Adk<5RA+oj_Y}yzZ!Rp=Zcg_TXS$-u` z&|Pi}bop&opov`092R11ErmB1KrIo+r_BhcZI%E;TgdLq#(cZx5u?on=tm8RE=X81 zFhG2S*D_O}E^mmg1()QeREBLN#xAod-h6&N;(qxh3aNSdrRf<8`ANm8MP=Y9E1uGh z5flbfyqWzn^nen46(;eyz_`myOizVG?n8cv{R$;>#NTY5jMaWrU7!%UCIr#7B=(G9 zw*vNnMb!n24)1t~rW4Zndp;gpO@viIhYLX*u7H*-71R_kyb{C$F+V`r%`NKMRIKI` zG6&?jOY9JH9E6Y5?~;QhP1J}aWRCF^Z!Y3o4)h}b>! z2js^@4u~HW{`vP;%wI&7IiO@~0Zk6|jDK0bEGNqtU;r>-4FD6&0Pq$hPNmTlZ&Bh@ z0wan@+kx(6z-p!`raLvfbs+)MBH+ZK*g{lV#4rZv30dMS1bPB{KEW^(rzgxXJ>kuc v)piV(Kz9 zlvEa^f<&0oET(jJv`-0|qT$Wl!)PgAT^lw>9r6(v?q>0v8QPRvOxnlgDx4=Y#+ zkWMM7EJy{3Fr`^c>Fj8q5;R4_o4JS4W{RJmpVxmN02AH}B~y}|IVR-nOX||xY(J$9 zs4jy!gVUMg2Ghy(2R(ZsLa9LOfx>J(Oi6~wrqy6Gjgb*%jHojs1DKuaZohLT2+V4q Gq6YxDv|D5V literal 0 HcmV?d00001 diff --git a/tests/unit/test_data/results_test_compare_root_variable_groups_with_TVD.pkl b/tests/unit/test_data/results_test_compare_root_variable_groups_with_TVD.pkl new file mode 100644 index 0000000000000000000000000000000000000000..78c4b06f5a90b5ba62abf2b5de1397a1bd5cb84f GIT binary patch literal 177 zcmZo*nYxSt0yKI=^Gb6ID)o}{i&FJ+OLIyx6N`!xE2s3Z6(=X=Bo zlvEa^f<&0oET(jJv`-0|qT$Wl!)PfP;k&IEy3ekD`%0QMVAkN^Mx literal 0 HcmV?d00001 From 50552b4f394b54953657b4a8e44e4ea6a6ae5e7b Mon Sep 17 00:00:00 2001 From: Andrea Tumbarello Date: Wed, 11 Dec 2024 11:21:43 +0100 Subject: [PATCH 2/2] Fixed bug about aggregating_function value sent in the FreqVsFreqBiasDetector constructor --- frontend/views/bias_route/FreqvsFreq.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/views/bias_route/FreqvsFreq.py b/frontend/views/bias_route/FreqvsFreq.py index fd0ec0c..0303bca 100644 --- a/frontend/views/bias_route/FreqvsFreq.py +++ b/frontend/views/bias_route/FreqvsFreq.py @@ -62,6 +62,8 @@ def freqvsfreq(): dict_vars['predictions'] = request.form['predictions'] if 'agg_func' in list(request.form.keys()): dict_vars['agg_func'] = request.form['agg_func'] + else: + dict_vars['agg_func'] = max if float(request.form['Slider']) > 0: dict_vars['thr'] = float(request.form['Slider']) else: @@ -83,6 +85,7 @@ def results_fvf(): bd = FreqVsFreqBiasDetector( distance=dict_vars['distance'], + aggregating_function=dict_vars['agg_func'], A1=dict_vars['a1_param'], target_variable_type=dict_vars['target_type'] )