Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ 3.8, 3.9, 3.11 ]
python-version: [ '3.10', '3.11', '3.12' ]
java-version: [ 17 ]
maven-version: [ '3.8.6' ]
steps:
Expand Down
21 changes: 11 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description = "Python bindings to the TrustyAI explainability library."
authors = [{ name = "Rui Vieira", email = "[email protected]" }]
license = { text = "Apache License Version 2.0" }
readme = "README.md"
requires-python = ">=3.8"
requires-python = ">=3.10"

keywords = ["trustyai", "xai", "explainability", "ml"]

Expand All @@ -15,19 +15,20 @@ classifiers = [
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Programming Language :: Java",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Topic :: Software Development :: Libraries :: Java Libraries",
]

dependencies = [
"Jpype1==1.5.0",
"pyarrow==17.0.0",
"matplotlib~=3.6.3",
"pyarrow==20.0.0",
"matplotlib~=3.10.3",
"pandas~=1.5.3",
"numpy~=1.24.1",
"jupyter-bokeh~=3.0.5",
"numpy==1.26.4",
"jupyter-bokeh~=3.0.7",
]

[project.optional-dependencies]
Expand All @@ -38,15 +39,15 @@ dev = [
"joblib~=1.2.0",
"jupyterlab~=3.5.3",
"numpydoc==1.5.0",
"pylint==2.15.6",
"pylint==3.2.0",
"pytest~=7.2.1",
"pytest-benchmark==4.0.0",
"pytest-forked~=1.6.0",
"scikit-learn~=1.2.1",
"scikit-learn~=1.7.0",
"setuptools",
"twine==3.4.2",
"wheel~=0.38.4",
"xgboost==1.4.2",
"xgboost~=3.0.2",
]
extras = ["aix360[default,tsice,tslime,tssaliency]==0.3.0"]

Expand Down
3 changes: 2 additions & 1 deletion src/trustyai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
def init():
"""Deprecated manual initializer for the JVM. This function has been replaced by
automatic initialization when importing the components of the module that require
JVM access, or by manual user initialization via :func:`trustyai`initializer.init`."""
JVM access, or by manual user initialization via :func:`trustyai`initializer.init`.
"""
warnings.warn(
"trustyai.init() is now deprecated; the trustyai library will now "
+ "automatically initialize. For manual initialization options, see "
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/explainers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Explainers module"""

# pylint: disable=duplicate-code
from .counterfactuals import CounterfactualResult, CounterfactualExplainer
from .lime import LimeExplainer, LimeResults
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/explainers/counterfactuals.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Explainers.countefactual module"""

# pylint: disable = import-error, too-few-public-methods, wrong-import-order, line-too-long,
# pylint: disable = unused-argument
from typing import Optional, Union, List
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/explainers/explanation_results.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Generic class for Explanation and Saliency results"""

from abc import ABC, abstractmethod

import pandas as pd
Expand Down
7 changes: 5 additions & 2 deletions src/trustyai/explainers/extras/tsice.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Wrapper module for TSICEExplainer from aix360.
Original at https://github.com/Trusted-AI/AIX360/
"""

# pylint: disable=too-many-arguments,import-error
from typing import Callable, List, Optional, Union

Expand Down Expand Up @@ -46,7 +47,8 @@ def as_html(self) -> pd.io.formats.style.Styler:

def plot_forecast(self, variable): # pylint: disable=too-many-locals
"""Plots the explanation.
Based on https://github.com/Trusted-AI/AIX360/blob/master/examples/tsice/plots.py"""
Based on https://github.com/Trusted-AI/AIX360/blob/master/examples/tsice/plots.py
"""
forecast_horizon = self.explanation["current_forecast"].shape[0]
original_ts = pd.DataFrame(
data={variable: self.explanation["data_x"][variable]}
Expand Down Expand Up @@ -161,7 +163,8 @@ def _add_timeseries(

def plot_impact(self, feature_per_row=2):
"""Plot the impace.
Based on https://github.com/Trusted-AI/AIX360/blob/master/examples/tsice/plots.py"""
Based on https://github.com/Trusted-AI/AIX360/blob/master/examples/tsice/plots.py
"""

n_row = int(np.ceil(len(self.explanation["feature_names"]) / feature_per_row))
feat_values = np.array(self.explanation["feature_values"])
Expand Down
3 changes: 2 additions & 1 deletion src/trustyai/explainers/extras/tslime.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ def as_html(self) -> Styler:

def plot(self):
"""Plot TSLime explanation for the time-series instance. Based on
https://github.com/Trusted-AI/AIX360/blob/master/examples/tslime/tslime_univariate_demo.ipynb"""
https://github.com/Trusted-AI/AIX360/blob/master/examples/tslime/tslime_univariate_demo.ipynb
"""
relevant_history = self.explanation["history_weights"].shape[0]
input_data = self.explanation["input_data"]
relevant_df = input_data[-relevant_history:]
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/explainers/lime.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Explainers.lime module"""

# pylint: disable = import-error, too-few-public-methods, wrong-import-order, line-too-long,
# pylint: disable = unused-argument, duplicate-code, consider-using-f-string, invalid-name
from typing import Dict, Union
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/explainers/pdp.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Explainers.pdp module"""

import math
import pandas as pd
from pandas.io.formats.style import Styler
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/explainers/shap.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Explainers.shap module"""

# pylint: disable = import-error, too-few-public-methods, wrong-import-order, line-too-long,
# pylint: disable = unused-argument, consider-using-f-string, invalid-name
from typing import Dict, Optional, Union
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/language/detoxify/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
"""Language detoxification module."""

from trustyai.language.detoxify.tmarco import TMaRCo
2 changes: 1 addition & 1 deletion src/trustyai/language/detoxify/tmarco.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# pylint: disable = invalid-name, line-too-long, use-dict-literal, consider-using-f-string, too-many-nested-blocks, self-assigning-variable
# pylint: disable = invalid-name, line-too-long, use-dict-literal, consider-using-f-string, too-many-nested-blocks, self-assigning-variable, broad-exception-raised, possibly-used-before-assignment
"""TMaRCo detoxification."""
import os
import math
Expand Down
3 changes: 2 additions & 1 deletion src/trustyai/metrics/distance.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""""Distance metrics"""
""" "Distance metrics"""

# pylint: disable = import-error
from dataclasses import dataclass
from typing import List, Optional, Union, Callable
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/metrics/fairness/group.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Group fairness metrics"""

# pylint: disable = import-error
from typing import List, Optional, Any, Union

Expand Down
3 changes: 2 additions & 1 deletion src/trustyai/metrics/language.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""""Language metrics"""
""" "Language metrics"""

# pylint: disable = import-error
from dataclasses import dataclass

Expand Down
3 changes: 2 additions & 1 deletion src/trustyai/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ def __init__(self, predict_fun):

def predict(self, inbound_bytearray):
"""The function called internally by :func:`predictAsync` when communicating
between Java and Python. This function should never need to be called manually."""
between Java and Python. This function should never need to be called manually.
"""
with pa.ipc.open_file(inbound_bytearray) as reader:
batch = reader.get_batch(0)
arr = batch.to_pandas()
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/utils/_visualisation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Visualiser utilies for explainer results"""

# pylint: disable = consider-using-f-string


Expand Down
4 changes: 2 additions & 2 deletions src/trustyai/utils/data_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ def numpy_to_prediction_object(


def prediction_object_to_numpy(
objects: Union[List[PredictionInput], List[PredictionOutput]]
objects: Union[List[PredictionInput], List[PredictionOutput]],
) -> np.array:
"""
Convert a list of TrustyAI
Expand Down Expand Up @@ -410,7 +410,7 @@ def prediction_object_to_numpy(


def prediction_object_to_pandas(
objects: Union[List[PredictionInput], List[PredictionOutput]]
objects: Union[List[PredictionInput], List[PredictionOutput]],
) -> pd.DataFrame:
"""
Convert a list of TrustyAI
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/utils/extras/models.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
"""AIX360 model wrappers"""

from aix360.algorithms.tsutils.model_wrappers import * # pylint: disable=wildcard-import,unused-wildcard-import
1 change: 1 addition & 0 deletions src/trustyai/utils/extras/timeseries.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Extra time series utilities."""

from aix360.algorithms.tsutils.tsframe import tsFrame # pylint: disable=unused-import
from aix360.algorithms.tsutils.tsperturbers import * # pylint: disable=wildcard-import,unused-wildcard-import
1 change: 1 addition & 0 deletions src/trustyai/utils/text.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Utility methods for text data handling"""

from typing import List, Callable

from jpype import _jclass
Expand Down
3 changes: 2 additions & 1 deletion src/trustyai/utils/tokenizers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
""""Default tokenizers for TrustyAI."""
""" "Default tokenizers for TrustyAI."""

# pylint: disable = import-error

from org.apache.commons.text import StringTokenizer as _StringTokenizer
Expand Down
3 changes: 2 additions & 1 deletion src/trustyai/utils/tyrus.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Tyrus module"""

# pylint: disable = too-few-public-methods, wrong-import-order, protected-access, cell-var-from-loop
# pylint: disable = too-many-instance-attributes, import-error. too-many-locals
# pylint: disable = consider-using-f-string
Expand Down Expand Up @@ -98,7 +99,7 @@ def __init__(
inputs: OneInputUnionType,
outputs: OneOutputUnionType,
background: ManyInputsUnionType,
**kwargs
**kwargs,
):
r"""Initialize the :class:`Tyrus` TrustyAI assistant and dashboard.

Expand Down
1 change: 1 addition & 0 deletions src/trustyai/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
"""TrustyAI version"""

__version__ = "0.6.1"
1 change: 1 addition & 0 deletions src/trustyai/visualizations/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Generates visualization according to explanation type"""

# pylint: disable=import-error, wrong-import-order, protected-access, missing-final-newline
from typing import Union, Optional

Expand Down
3 changes: 2 additions & 1 deletion src/trustyai/visualizations/distance.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Visualizations.distance module"""

# pylint: disable = import-error, too-few-public-methods, line-too-long, missing-final-newline
import numpy as np
import matplotlib.pyplot as plt
Expand All @@ -9,7 +10,7 @@ class DistanceViz:

def plot(self, explanations):
"""Plot the Levenshtein distance matrix"""
cmap = plt.cm.viridis
cmap = plt.cm.viridis # pylint: disable=no-member

_, axes = plt.subplots()
cax = axes.imshow(explanations.matrix, cmap=cmap, interpolation="nearest")
Expand Down
25 changes: 16 additions & 9 deletions src/trustyai/visualizations/lime.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Visualizations.lime module"""

# pylint: disable = import-error, too-few-public-methods, consider-using-f-string, missing-final-newline
import matplotlib.pyplot as plt
import matplotlib as mpl
Expand Down Expand Up @@ -34,9 +35,11 @@ def _matplotlib_plot(
] = feature_importance.getScore()

colours = [
ds["negative_primary_colour"]
if i < 0
else ds["positive_primary_colour"]
(
ds["negative_primary_colour"]
if i < 0
else ds["positive_primary_colour"]
)
for i in dictionary.values()
]
plt.title(f"LIME: Feature Importances to {output_name}")
Expand Down Expand Up @@ -65,18 +68,22 @@ def _get_bokeh_plot(self, explanations, output_name):
]
)
lime_data_source["color"] = lime_data_source["saliency"].apply(
lambda x: ds["positive_primary_colour"]
if x >= 0
else ds["negative_primary_colour"]
lambda x: (
ds["positive_primary_colour"]
if x >= 0
else ds["negative_primary_colour"]
)
)
lime_data_source["saliency_colored"] = lime_data_source["saliency"].apply(
lambda x: (bold_green_html if x >= 0 else bold_red_html)("{:.2f}".format(x))
)

lime_data_source["color_faded"] = lime_data_source["saliency"].apply(
lambda x: ds["positive_primary_colour_faded"]
if x >= 0
else ds["negative_primary_colour_faded"]
lambda x: (
ds["positive_primary_colour_faded"]
if x >= 0
else ds["negative_primary_colour_faded"]
)
)
source = ColumnDataSource(lime_data_source)
htool = HoverTool(
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/visualizations/pdp.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Visualizations.pdp module"""

# pylint: disable = import-error, wrong-import-order, too-few-public-methods, missing-final-newline
# pylint: disable = protected-access
import matplotlib.pyplot as plt
Expand Down
17 changes: 11 additions & 6 deletions src/trustyai/visualizations/shap.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Visualizations.shap module"""

# pylint: disable = import-error, consider-using-f-string, too-few-public-methods, missing-final-newline
import matplotlib.pyplot as plt
import matplotlib as mpl
Expand Down Expand Up @@ -100,14 +101,18 @@ def _get_bokeh_plot(self, explanations, output_name):
prediction = fnull + data_source["saliency"].sum()

data_source["color"] = data_source["saliency"].apply(
lambda x: ds["positive_primary_colour"]
if x >= 0
else ds["negative_primary_colour"]
lambda x: (
ds["positive_primary_colour"]
if x >= 0
else ds["negative_primary_colour"]
)
)
data_source["color_faded"] = data_source["saliency"].apply(
lambda x: ds["positive_primary_colour_faded"]
if x >= 0
else ds["negative_primary_colour_faded"]
lambda x: (
ds["positive_primary_colour_faded"]
if x >= 0
else ds["negative_primary_colour_faded"]
)
)
data_source["index"] = data_source.index
data_source["saliency_text"] = data_source["saliency"].apply(
Expand Down
1 change: 1 addition & 0 deletions src/trustyai/visualizations/visualization_results.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Generic class for Visualization results"""

# pylint: disable = import-error, too-few-public-methods, line-too-long, missing-final-newline
from abc import ABC, abstractmethod
from typing import Dict
Expand Down
Loading
Loading