From e5f63297008643c42d2f9c567d0993372bd37d77 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 16 Feb 2022 13:36:45 +0000 Subject: [PATCH 1/4] #54 Update doc strings --- README.md | 2 +- requirements.txt | 1 + src/algorithms/q_learning.py | 12 ++++++------ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4fd54a5..31eb42b 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ The images below show the overall running distortion average and running reward The following packages are required. -- NumPy +- NumPy - Sphinx - Python Pandas diff --git a/requirements.txt b/requirements.txt index 4c41cc6..3f89435 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ numpy==1.20.2 pandas==1.1.3 gym==0.18.0 textdistance==4.2.0 +numpydoc==1.2 diff --git a/src/algorithms/q_learning.py b/src/algorithms/q_learning.py index 7132dfc..e8a4739 100644 --- a/src/algorithms/q_learning.py +++ b/src/algorithms/q_learning.py @@ -14,9 +14,7 @@ class QLearnConfig(object): - """ - Configuration for Q-learning - """ + """Configuration for Q-learning""" def __init__(self): self.gamma: float = 1.0 self.alpha: float = 0.1 @@ -25,11 +23,13 @@ def __init__(self): class QLearning(WithMaxActionMixin): - """ - Q-learning algorithm implementation - """ + """Q-learning algorithm implementation""" def __init__(self, algo_config: QLearnConfig): + """ + Constructor. Constructs an untrained agent + :param algo_config: Configuration parameters + """ super(QLearning, self).__init__() self.q_table = {} self.config = algo_config From 846eb41733d7c69dba367da0d4ed4443a9c2fed2 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 16 Feb 2022 13:37:16 +0000 Subject: [PATCH 2/4] #54 Add script for documentation build --- build_sphinx_doc.sh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100755 build_sphinx_doc.sh diff --git a/build_sphinx_doc.sh b/build_sphinx_doc.sh new file mode 100755 index 0000000..11d46a6 --- /dev/null +++ b/build_sphinx_doc.sh @@ -0,0 +1,4 @@ +#sphinx-quickstart docs + +sphinx-apidoc -f -o docs/source docs/projectdir +#sphinx-build -b html docs/source/ docs/build/html From b67dce13d65c6e1e4398bc81acf27e6e6df38161 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 17 Feb 2022 14:22:46 +0000 Subject: [PATCH 3/4] Update documentation docstrings --- src/spaces/actions.py | 138 +++++++++++++++++++++++++++++++----------- 1 file changed, 102 insertions(+), 36 deletions(-) diff --git a/src/spaces/actions.py b/src/spaces/actions.py index 1ca4d78..0c8a6ba 100644 --- a/src/spaces/actions.py +++ b/src/spaces/actions.py @@ -1,29 +1,21 @@ +# -*- coding: utf-8 -*- +"""The actions module. This module includes +various actions to be applied by the implemented RL agents + +""" + import abc import enum from typing import List, TypeVar, Any - import numpy as np -from src.utils.hierarchy_base import HierarchyBase from src.utils.mixins import WithHierarchyTable Hierarchy = TypeVar("Hierarchy") -def move_next(iterators: List) -> None: - """ - Loop over the iterators and move them - to the next item - :param iterators: The list of iterators to propagate - :return: None - """ - for item in iterators: - next(item) - - class ActionType(enum.IntEnum): - """ - Defines the status of an Action + """Defines the status of an Action """ INVALID_TYPE = -1 @@ -53,11 +45,18 @@ def restore(self) -> bool: class ActionBase(metaclass=abc.ABCMeta): - """ - Base class for actions + """Base class for actions """ def __init__(self, column_name: str, action_type: ActionType) -> None: + """Constructor + + Parameters + ---------- + column_name : The name of the column this is acting on + action_type : The type of the action + + """ self.column_name = column_name self.action_type = action_type self.idx = None @@ -65,27 +64,52 @@ def __init__(self, column_name: str, action_type: ActionType) -> None: @abc.abstractmethod def act(self, **ops) -> Any: - """ - Perform an action - :return: + """Perform the action + + Parameters + ---------- + ops : The data to distort + + Returns + ------- + Typically the action returns the distorted subset of the data + """ class ActionIdentity(ActionBase): - """ - Implements the identity action + """Implements the identity action. Use this action + to signal that no distortion should be applied. + """ def __init__(self, column_name: str) -> None: + """Constructor + + Parameters + ---------- + column_name : The name of the column this is acting on + + """ super(ActionIdentity, self).__init__(column_name=column_name, action_type=ActionType.IDENTITY) self.called = False def act(self, **ops) -> Any: + """Perform the action + + Parameters + ---------- + ops : The data to distort + + Returns + ------- + + The distorted column + """ - Perform the action - :return: - """ + self.called = True + return ops['data'] class ActionRestore(ActionBase, WithHierarchyTable): @@ -160,20 +184,35 @@ def act(self, **ops) -> None: class ActionStringGeneralize(ActionBase, WithHierarchyTable): - """ - Implements the generalization action. The generalization_table + """Implements the generalization action. The generalization_table must implement the __getitem__ function + """ - def __init__(self, column_name: str, generalization_table: Hierarchy): - super(ActionStringGeneralize, self).__init__(column_name=column_name, action_type=ActionType.GENERALIZE) + def __init__(self, column_name: str, generalization_table: Hierarchy) -> None: + """Constructor - self.table = generalization_table + Parameters + ---------- + column_name : The column name this action is acting on + generalization_table : The hierarchy for the generalization - def act(self, **ops): """ - Perform an action - :return: + super(ActionStringGeneralize, self).__init__(column_name=column_name, action_type=ActionType.GENERALIZE) + self.table = generalization_table + + def act(self, **ops) -> Any: + """Performs the action + + Parameters + ---------- + ops : The data to distort + + Returns + ------- + + The distorted data + """ # get the values of the column @@ -191,12 +230,33 @@ def act(self, **ops): return ops['data'] def add(self, key: Any, value: Any) -> None: + """Add a new item in the underlying hierarchy + + Parameters + ---------- + key : The key to use for the new item + value : The value of the new item + + Returns + ------- + + None + """ self.table.add(key, value) class ActionNumericBinGeneralize(ActionBase, WithHierarchyTable): + """Generalization Action for numeric columns using bins + """ def __init__(self, column_name: str, generalization_table: Hierarchy): + """ + Constructor + Parameters + ---------- + column_name : The name of the column this is acting on + generalization_table : The bins to use + """ super(ActionNumericBinGeneralize, self).__init__(column_name=column_name, action_type=ActionType.GENERALIZE) self.table = generalization_table @@ -207,10 +267,16 @@ def __init__(self, column_name: str, generalization_table: Hierarchy): self.bins.append((start, self.table[i])) start = self.table[i] - def act(self, **ops): + def act(self, **ops) -> Any: """ - Perform an action - :return: + Perform the action + Parameters + ---------- + ops : The data to distort + + Returns + ------- + Typically the action returns the distorted subset of the data """ # get the values of the column From 88706b7b2a06fbbcbc0b49db0df81fc649df4a05 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 17 Feb 2022 14:24:19 +0000 Subject: [PATCH 4/4] Add documentation files --- docs/source/API/actions.rst | 44 +++++++++++++++++++++++++++++++++++++ docs/source/examples.rst | 7 ++++++ docs/source/index.rst | 30 +++++++++++++++++++++++++ docs/source/install.rst | 27 +++++++++++++++++++++++ docs/source/modules.rst | 22 +++++++++++++++++++ docs/source/overview.rst | 25 +++++++++++++++++++++ 6 files changed, 155 insertions(+) create mode 100644 docs/source/API/actions.rst create mode 100644 docs/source/examples.rst create mode 100644 docs/source/index.rst create mode 100644 docs/source/install.rst create mode 100644 docs/source/modules.rst create mode 100644 docs/source/overview.rst diff --git a/docs/source/API/actions.rst b/docs/source/API/actions.rst new file mode 100644 index 0000000..138327d --- /dev/null +++ b/docs/source/API/actions.rst @@ -0,0 +1,44 @@ +actions +======= + +.. automodule:: actions + + + + + + + + + + + + .. rubric:: Classes + + .. autosummary:: + +.. autoclass:: ActionBase + :members: __init__, act + +.. autoclass:: ActionIdentity + :members: __init__, act + + ActionNumericBinGeneralize + ActionNumericStepGeneralize + ActionRestore + +.. autoclass:: ActionStringGeneralize + :members: __init__, act, add + + ActionSuppress + ActionTransform + ActionType + + + + + + + + + diff --git a/docs/source/examples.rst b/docs/source/examples.rst new file mode 100644 index 0000000..2655cff --- /dev/null +++ b/docs/source/examples.rst @@ -0,0 +1,7 @@ +Examples +======== + +Some examples can be found below + +- `Qlearning agent on a three columns dataset `_ +- `N-step semi-gradient SARSA on a three columns dataset `_ diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..7be542a --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,30 @@ +.. RL Anonymity (with Python) documentation master file, created by + sphinx-quickstart on Tue Feb 15 17:55:45 2022. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to RL Anonymity (with Python)'s documentation! +====================================================== + +An experimental effort to use reinforcement learning techniques for data anonymization. + +Contents +-------- + +.. toctree:: + :maxdepth: 2 + + + overview + install + examples + modules + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + + diff --git a/docs/source/install.rst b/docs/source/install.rst new file mode 100644 index 0000000..f1f8c73 --- /dev/null +++ b/docs/source/install.rst @@ -0,0 +1,27 @@ +Installation +============ + +The following packages are required: + +- `NumPy `_ +- `Sphinx `_ +- `Python Pandas `_ + +.. code-block:: console + + pip install -r requirements.txt + + +Generate documentation +====================== + +You will need `Sphinx `_ in order to generate the API documentation. Assuming that Sphinx is already installed +on your machine execute the following commands (see also `Sphinx tutorial `_). + +.. code-block:: console + + sphinx-quickstart docs + sphinx-build -b html docs/source/ docs/build/html + + + diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 0000000..d43fc22 --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,22 @@ +API +=== + +.. toctree:: + :maxdepth: 4 + + API/actions + generated/action_space + generated/q_estimator + generated/q_learning + generated/trainer + generated/sarsa_semi_gradient + generated/exceptions + generated/action_space + generated/actions + generated/column_type + generated/discrete_state_environment + generated/observation_space + generated/state + generated/time_step + generated/tiled_environment + diff --git a/docs/source/overview.rst b/docs/source/overview.rst new file mode 100644 index 0000000..92c12c1 --- /dev/null +++ b/docs/source/overview.rst @@ -0,0 +1,25 @@ +Conceptual overview +=================== + +The term data anonymization refers to techiniques that can be applied on a given dataset, D, such that after +the latter has been submitted to such techniques, it makes it difficult for a third party to identify or infer the existence +of specific individuals in D. Anonymization techniques, typically result into some sort of distortion +of the original dataset. This means that in order to maintain some utility of the transformed dataset, the transofrmations +applied should be constrained in some sense. In the end, it can be argued, that data anonymization is an optimization problem +meaning striking the right balance between data utility and privacy. + +Reinforcement learning is a learning framework based on accumulated experience. In this paradigm, an agent is learning by iteracting with an environment +without (to a large extent) any supervision. The following image describes, schematically, the reinforcement learning framework . + +![RL paradigm](images/agent_environment_interface.png "Reinforcement learning paradigm") + +The agent chooses an action, ```a_t```, to perform out of predefined set of actions ```A```. The chosen action is executed by the environment +instance and returns to the agent a reward signal, ```r_t```, as well as the new state, ```s_t```, that the enviroment is in. +The framework has successfully been used to many recent advances in control, robotics, games and elsewhere. + + +Let's assume that we have in our disposal two numbers a minimum distortion, ```MIN_DIST``` that should be applied to the dataset +for achieving privacy and a maximum distortion, ```MAX_DIST```, that should be applied to the dataset in order to maintain some utility. +Let's assume also that any overall dataset distortion in ```[MIN_DIST, MAX_DIST]``` is acceptable in order to cast the dataset as +preserving privacy and preserving dataset utility. We can then train a reinforcement learning agent to distort the dataset +such that the aforementioned objective is achieved.