Skip to content

Commit

Permalink
Merge branch 'main' into gaugup/AddSupport3.12
Browse files Browse the repository at this point in the history
  • Loading branch information
gaugup committed Nov 6, 2023
2 parents 100f2bb + 0ff6831 commit f97290d
Show file tree
Hide file tree
Showing 62 changed files with 1,306 additions and 1,190 deletions.
21 changes: 9 additions & 12 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package

on:
release:
types: [created]
workflow_dispatch:

jobs:
deploy:

pypi-publish:
name: upload release to PyPI
runs-on: ubuntu-latest

# Specifying a GitHub environment is optional, but strongly encouraged
environment: release
permissions:
# IMPORTANT: this permission is mandatory for trusted publishing
id-token: write
steps:
- uses: actions/checkout@v3
- name: Set up Python
Expand All @@ -24,9 +23,7 @@ jobs:
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
26 changes: 26 additions & 0 deletions dice_ml/data_interfaces/base_data_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from abc import ABC, abstractmethod

import pandas as pd
from raiutils.exceptions import UserConfigValidationException

from dice_ml.utils.exception import SystemException
Expand Down Expand Up @@ -71,6 +72,31 @@ def _validate_and_set_permitted_range(self, params, features_dict=None):
)
self.permitted_range, _ = self.get_features_range(input_permitted_range, features_dict)

def ensure_consistent_type(self, output_df, query_instance):
qdf = self.query_instance_to_df(query_instance)
output_df = output_df.astype(qdf.dtypes.to_dict())
return output_df

def query_instance_to_df(self, query_instance):
if isinstance(query_instance, list):
if isinstance(query_instance[0], dict): # prepare a list of query instances
test = pd.DataFrame(query_instance, columns=self.feature_names)

else: # prepare a single query instance in list
query_instance = {'row1': query_instance}
test = pd.DataFrame.from_dict(
query_instance, orient='index', columns=self.feature_names)

elif isinstance(query_instance, dict):
test = pd.DataFrame({k: [v] for k, v in query_instance.items()}, columns=self.feature_names)

elif isinstance(query_instance, pd.DataFrame):
test = query_instance.copy()

else:
raise ValueError("Query instance should be a dict, a pandas dataframe, a list, or a list of dicts")
return test

@abstractmethod
def __init__(self, params):
"""The init method needs to be implemented by the inherting classes."""
Expand Down
7 changes: 5 additions & 2 deletions dice_ml/data_interfaces/private_data_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,7 @@ def prepare_df_for_ohe_encoding(self):

return df

def prepare_query_instance(self, query_instance):
"""Prepares user defined test input(s) for DiCE."""
def query_instance_to_df(self, query_instance):
if isinstance(query_instance, list):
if isinstance(query_instance[0], dict): # prepare a list of query instances
test = pd.DataFrame(query_instance, columns=self.feature_names)
Expand All @@ -370,7 +369,11 @@ def prepare_query_instance(self, query_instance):

else:
raise ValueError("Query instance should be a dict, a pandas dataframe, a list, or a list of dicts")
return test

def prepare_query_instance(self, query_instance):
"""Prepares user defined test input(s) for DiCE."""
test = self.query_instance_to_df(query_instance)
test = test.reset_index(drop=True)
return test

Expand Down
19 changes: 1 addition & 18 deletions dice_ml/data_interfaces/public_data_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,24 +451,7 @@ def prepare_df_for_ohe_encoding(self):

def prepare_query_instance(self, query_instance):
"""Prepares user defined test input(s) for DiCE."""
if isinstance(query_instance, list):
if isinstance(query_instance[0], dict): # prepare a list of query instances
test = pd.DataFrame(query_instance, columns=self.feature_names)

else: # prepare a single query instance in list
query_instance = {'row1': query_instance}
test = pd.DataFrame.from_dict(
query_instance, orient='index', columns=self.feature_names)

elif isinstance(query_instance, dict):
test = pd.DataFrame({k: [v] for k, v in query_instance.items()}, columns=self.feature_names)

elif isinstance(query_instance, pd.DataFrame):
test = query_instance.copy()

else:
raise ValueError("Query instance should be a dict, a pandas dataframe, a list, or a list of dicts")

test = self.query_instance_to_df(query_instance)
test = test.reset_index(drop=True)
# encode categorical and numerical columns
test = self._set_feature_dtypes(test,
Expand Down
8 changes: 8 additions & 0 deletions dice_ml/explainer_interfaces/explainer_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ def generate_counterfactuals(self, query_instances, total_CFs,
posthoc_sparsity_algorithm=posthoc_sparsity_algorithm,
verbose=verbose,
**kwargs)
res.test_instance_df = self.data_interface.ensure_consistent_type(
res.test_instance_df, query_instance)
if res.final_cfs_df is not None and len(res.final_cfs_df) > 0:
res.final_cfs_df = self.data_interface.ensure_consistent_type(
res.final_cfs_df, query_instance)
if res.final_cfs_df_sparse is not None and len(res.final_cfs_df_sparse) > 0:
res.final_cfs_df_sparse = self.data_interface.ensure_consistent_type(
res.final_cfs_df_sparse, query_instance)
cf_examples_arr.append(res)
self._check_any_counterfactuals_computed(cf_examples_arr=cf_examples_arr)

Expand Down
12 changes: 11 additions & 1 deletion dice_ml/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,17 @@ def load_outcome_not_last_column_dataset():


def load_custom_testing_dataset_binary():
data = [['a', 1, 0], ['b', 5, 1], ['c', 2, 0], ['a', 3, 0], ['c', 4, 1]]
data = [
['a', 1, 0],
['b', 5, 1],
['c', 2, 0],
['a', 3, 0],
['c', 4, 1],
['c', 10, 0],
['a', 7, 0],
['c', 8, 1],
['b', 10, 1],
]
return pd.DataFrame(data, columns=['Categorical', 'Numerical', 'Outcome'])


Expand Down
4 changes: 1 addition & 3 deletions docs/_modules/dice_ml/constants.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>dice_ml.constants &mdash; DiCE 0.9 documentation</title>
<title>dice_ml.constants &mdash; DiCE 0.11 documentation</title>
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
Expand Down Expand Up @@ -50,8 +50,6 @@
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_model_agnostic_CFs.html">Generating counterfactual explanations with any ML model</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_with_private_data.html">Generating counterfactual explanations without access to training data</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_with_advanced_options.html">Advanced options to customize Counterfactual Explanations</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_getting_started_feasible.html">Generate feasible counterfactual explanations using a VAE</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_getting_started_feasible.html#Adding-feasibility-constraints">Adding feasibility constraints</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Package:</span></p>
<ul>
Expand Down
2 changes: 1 addition & 1 deletion docs/_modules/dice_ml/counterfactual_explanations.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>dice_ml.counterfactual_explanations &mdash; DiCE 0.10 documentation</title>
<title>dice_ml.counterfactual_explanations &mdash; DiCE 0.11 documentation</title>
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
Expand Down
12 changes: 5 additions & 7 deletions docs/_modules/dice_ml/data.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>dice_ml.data &mdash; DiCE 0.9 documentation</title>
<title>dice_ml.data &mdash; DiCE 0.11 documentation</title>
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
<!--[if lt IE 9]>
Expand Down Expand Up @@ -50,8 +50,6 @@
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_model_agnostic_CFs.html">Generating counterfactual explanations with any ML model</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_with_private_data.html">Generating counterfactual explanations without access to training data</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_with_advanced_options.html">Advanced options to customize Counterfactual Explanations</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_getting_started_feasible.html">Generate feasible counterfactual explanations using a VAE</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/DiCE_getting_started_feasible.html#Adding-feasibility-constraints">Adding feasibility constraints</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">Package:</span></p>
<ul>
Expand Down Expand Up @@ -95,23 +93,23 @@ <h1>Source code for dice_ml.data</h1><div class="highlight"><pre>


<div class="viewcode-block" id="Data"><a class="viewcode-back" href="../../dice_ml.html#dice_ml.data.Data">[docs]</a><span class="k">class</span> <span class="nc">Data</span><span class="p">(</span><span class="n">_BaseData</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Class containing all required information about the data for DiCE.&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Class containing all required information about the data for DiCE.&quot;&quot;&quot;</span>

<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">params</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Init method</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Init method</span>

<span class="sd"> :param **params: a dictionary of required parameters.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">decide_implementation_type</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>

<div class="viewcode-block" id="Data.decide_implementation_type"><a class="viewcode-back" href="../../dice_ml.html#dice_ml.data.Data.decide_implementation_type">[docs]</a> <span class="k">def</span> <span class="nf">decide_implementation_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Decides if the Data class is for public or private data.&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Decides if the Data class is for public or private data.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span> <span class="o">=</span> <span class="n">decide</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">params</span><span class="p">)</span></div></div>


<div class="viewcode-block" id="decide"><a class="viewcode-back" href="../../dice_ml.html#dice_ml.data.decide">[docs]</a><span class="k">def</span> <span class="nf">decide</span><span class="p">(</span><span class="n">params</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Decides if the Data class is for public or private data.</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Decides if the Data class is for public or private data.</span>

<span class="sd"> To add new implementations of Data, add the class in data_interfaces</span>
<span class="sd"> subpackage and import-and-return the class in an elif loop as shown</span>
Expand Down

0 comments on commit f97290d

Please sign in to comment.