Skip to content

Commit

Permalink
Merge branch 'main' into lira_carlini
Browse files Browse the repository at this point in the history
Signed-off-by: Richard Preen <rpreen@gmail.com>
  • Loading branch information
rpreen committed Jun 11, 2024
2 parents e3c0b9b + cb1ab69 commit 2f2aab5
Show file tree
Hide file tree
Showing 61 changed files with 531 additions and 831 deletions.
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ ignore:
- "setup.py"
- "aisdc/safemodel/classifiers/new_model_template.py"
- "aisdc/preprocessing"
- "user_stories"
...
1 change: 1 addition & 0 deletions aisdc/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tools for managing the statistical disclosure control of trained ML models."""
1 change: 1 addition & 0 deletions aisdc/attacks/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Collection of attacks for assessing the privacy of trained ML models."""
10 changes: 5 additions & 5 deletions aisdc/attacks/attack.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Attack.py - base class for an attack object."""
"""Base class for an attack object."""

import inspect
import json
Expand All @@ -13,14 +13,15 @@ def __init__(self):
self.attack_config_json_file_name = None

def attack(self, target: Target) -> None:
"""Method to run an attack."""
"""Run an attack."""
raise NotImplementedError

def __str__(self):
"""Return the string representation of an attack."""
raise NotImplementedError

def _update_params_from_config_file(self) -> None:
"""Reads a configuration file and loads it into a dictionary object."""
"""Read a configuration file and load it into a dictionary object."""
with open(self.attack_config_json_file_name, encoding="utf-8") as f:
config = json.loads(f.read())
for key, value in config.items():
Expand All @@ -38,8 +39,7 @@ def _get_param_names(cls):
return parameters

def get_params(self):
"""
Get parameters for this attack.
"""Get parameters for this attack.
Returns
-------
Expand Down
54 changes: 23 additions & 31 deletions aisdc/attacks/attack_report_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ def cleanup_files_for_release(
release_dir="release_files",
artefacts_dir="training_artefacts",
):
"""
Function that will move any files created throughout the release process and
sort them into appropriate folders.
"""

"""Move files created during the release process into appropriate folders."""
if not os.path.exists(release_dir):
os.makedirs(release_dir)

Expand All @@ -44,7 +40,7 @@ def cleanup_files_for_release(


class GenerateJSONModule:
"""Module that creates and appends to a JSON file."""
"""Create and append to a JSON file."""

def __init__(self, filename=None):
self.filename = filename
Expand All @@ -63,7 +59,6 @@ def __init__(self, filename=None):

def add_attack_output(self, incoming_json, class_name):
"""Add a section of JSON to the file which is already open."""

# Read the contents of the file and then clear the file
with open(self.filename, "r+", encoding="utf-8") as f:
file_contents = f.read()
Expand All @@ -85,7 +80,7 @@ def add_attack_output(self, incoming_json, class_name):
json.dump(file_data, f)

def get_output_filename(self):
"""Returns the filename of the JSON file which has been created."""
"""Return the filename of the JSON file which has been created."""
return self.filename

def clean_file(self):
Expand All @@ -106,19 +101,20 @@ def __init__(self):
self.support_release = []

def process_dict(self):
"""Function that produces a risk summary output based on analysis in this module."""
"""Produce a risk summary output based on analysis in this module."""
raise NotImplementedError()

def get_recommendation(self):
"""Function that returns the three recommendation buckets created by this module."""
"""Return the three recommendation buckets created by this module."""
return self.immediate_rejection, self.support_rejection, self.support_release

def __str__(self):
"""Return the string representation of an analysis module."""
raise NotImplementedError()


class FinalRecommendationModule(AnalysisModule): # pylint: disable=too-many-instance-attributes
"""Module that generates the first layer of a recommendation report."""
"""Generate the first layer of a recommendation report."""

def __init__(self, report: dict):
super().__init__()
Expand Down Expand Up @@ -239,6 +235,7 @@ def _statistically_significant_auc(
self.support_release.append(msg)

def process_dict(self):
"""Return a dictionary summarising the metrics."""
self._tree_min_samples_leaf(self.MIN_SAMPLES_LEAF_SCORE)
self._statistically_significant_auc(
self.P_VAL_THRESH,
Expand All @@ -258,19 +255,15 @@ def process_dict(self):
summarised_score = self.INSTANCE_MODEL_WEIGHTING_SCORE

output = {}

# msg = "Final score (scale of 0-5, where 0 is least disclosive and 5 is recommend
# rejection)"
# output[msg] = summarised_score

return output

def __str__(self):
"""Return string representation of the final recommendation."""
return "Final Recommendation"


class SummariseUnivariateMetricsModule(AnalysisModule):
"""Module that summarises a set of chosen univariate metrics from the output dictionary."""
"""Summarise a set of chosen univariate metrics from the output dictionary."""

def __init__(self, report: dict, metrics_list=None):
super().__init__()
Expand All @@ -282,6 +275,7 @@ def __init__(self, report: dict, metrics_list=None):
self.metrics_list = metrics_list

def process_dict(self):
"""Return a dictionary summarising the metrics."""
output_dict = {}

for k in self.report.keys():
Expand All @@ -305,11 +299,12 @@ def process_dict(self):
return output_dict

def __str__(self):
"""Return the string representation of a univariate metrics module."""
return "Summary of Univarite Metrics"


class SummariseAUCPvalsModule(AnalysisModule):
"""Module that summarises a list of AUC values."""
"""Summarise a list of AUC values."""

def __init__(self, report: dict, p_thresh: float = 0.05, correction: str = "bh"):
super().__init__()
Expand All @@ -319,10 +314,7 @@ def __init__(self, report: dict, p_thresh: float = 0.05, correction: str = "bh")
self.correction = correction

def _n_sig(self, p_val_list: list[float], correction: str = "none") -> int:
"""Compute the number of significant p-vals in a list with different corrections for
multiple testing.
"""

"""Compute the number of significant p-vals with different corrections."""
if correction == "none":
return len(np.where(np.array(p_val_list) <= self.p_thresh)[0])
if correction == "bh":
Expand Down Expand Up @@ -362,6 +354,7 @@ def process_dict(self):
return output

def __str__(self):
"""Return the string representation of a AUC p-values module."""
return f"Summary of AUC p-values at p = ({self.p_thresh})"


Expand All @@ -377,11 +370,12 @@ def get_metric_list(self, input_dict: dict) -> list[float]:
return metric_list

def __str__(self):
"""Return the string representation of a FDIF p-values module."""
return f"Summary of FDIF p-values at p = ({self.p_thresh})"


class LogLogROCModule(AnalysisModule):
"""Module that generates a log-log plot."""
"""Generate a log-log plot."""

def __init__(self, report: dict, output_folder=None, include_mean=True):
super().__init__()
Expand Down Expand Up @@ -438,11 +432,12 @@ def process_dict(self):
return msg

def __str__(self):
"""Return the string representation of a ROC log plot module."""
return "ROC Log Plot"


class GenerateTextReport:
"""Module that generates a text report from a JSON input."""
"""Generate a text report from a JSON input."""

def __init__(self):
self.text_out = []
Expand All @@ -455,8 +450,7 @@ def __init__(self):
self.support_release = []

def _process_target_json(self):
"""Function that creates a summary of a target model JSON file."""

"""Create a summary of a target model JSON file."""
model_params_of_interest = [
"C",
"kernel",
Expand Down Expand Up @@ -502,8 +496,7 @@ def _process_target_json(self):
self.text_out.append(output_string)

def pretty_print(self, report: dict, title) -> str:
"""Function that formats JSON code to make it more readable for TREs."""

"""Format JSON code to make it more readable for TREs."""
returned_string = str(title) + "\n"

for key in report.keys():
Expand All @@ -515,7 +508,7 @@ def pretty_print(self, report: dict, title) -> str:
def process_attack_target_json(
self, attack_filename: str, target_filename: str = None
):
"""Function that creates a neat summary of an attack JSON file."""
"""Create a neat summary of an attack JSON file."""
self.attack_json_filename = attack_filename

with open(attack_filename, encoding="utf-8") as f:
Expand Down Expand Up @@ -575,8 +568,7 @@ def export_to_file( # pylint: disable=too-many-arguments
release_dir="release_files",
artefacts_dir="training_artefacts",
):
"""Function that takes the input strings collected and combines into a neat text file."""

"""Take the input strings collected and combine into a neat text file."""
copy_of_text_out = self.text_out
self.text_out = []

Expand Down
Loading

0 comments on commit 2f2aab5

Please sign in to comment.