{"id":24805342,"url":"https://github.com/viadee/xai_examples","last_synced_at":"2025-10-25T22:08:56.541Z","repository":{"id":45156439,"uuid":"173718694","full_name":"viadee/xai_examples","owner":"viadee","description":"Things that call for explanations...","archived":false,"fork":false,"pushed_at":"2022-01-04T17:56:54.000Z","size":46973,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-01-30T07:18:04.813Z","etag":null,"topics":["explainable-ai","machine-learning"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/viadee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-04T09:55:38.000Z","updated_at":"2024-03-21T23:09:23.000Z","dependencies_parsed_at":"2022-09-22T18:00:29.020Z","dependency_job_id":null,"html_url":"https://github.com/viadee/xai_examples","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viadee%2Fxai_examples","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viadee%2Fxai_examples/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viadee%2Fxai_examples/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viadee%2Fxai_examples/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/viadee","download_url":"https://codeload.github.com/viadee/xai_examples/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245423185,"owners_count":20612747,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["explainable-ai","machine-learning"],"created_at":"2025-01-30T07:18:06.362Z","updated_at":"2025-10-25T22:08:56.475Z","avatar_url":"https://github.com/viadee.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)\n\n# XAI Examples\n\nThis repository contains tutorials and readily compilable projects/source code concerning Explainable Artificial Intelligence (XAI).\n\nThe following algorithms and specific implementations are being used:\n+ Anchors. [Implementation](https://github.com/viadee/javaAnchorExplainer) and its optional [Adapters](https://github.com/viadee/javaAnchorAdapters)\n\n## Anchors Titanic Examples\n\nOne of the Anchors implementation's main feature consists in facilitating the usage of tabular explanations by providing default \nsolutions to common scenarios in conjunction with the anchorj library.\nThe following use-case exemplifies its usage by creating both local and global explanations of the \n[Titanic tabular dataset](https://www.kaggle.com/c/titanic/data).\n\n### 1. Referencing Dependencies\nUsing Apache Maven, the required anchorj dependencies are easily referenced and added as follows:\n\n    \u003c!-- AnchorJ --\u003e\n    \u003cdependency\u003e\n         \u003cgroupId\u003ede.viadee.xai.anchor\u003c/groupId\u003e\n         \u003cartifactId\u003ealgorithm\u003c/artifactId\u003e\n         \u003cversion\u003e1.0.2\u003c/version\u003e\n    \u003c/dependency\u003e\n    \n    \u003c!-- AnchorJ Default Solutions Extension containing AnchorTabular --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ede.viadee.xai.anchor\u003c/groupId\u003e\n        \u003cartifactId\u003eDefaultConfigsAdapter\u003c/artifactId\u003e\n        \u003cversion\u003e1.0.3\u003c/version\u003e\n    \u003c/dependency\u003e\n    \n    \u003c!-- AnchorJ Default Machine Learning Models --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ede.viadee.xai.anchor\u003c/groupId\u003e\n        \u003cartifactId\u003eDefaultMLMethods\u003c/artifactId\u003e\n        \u003cversion\u003e1.0.3\u003c/version\u003e\n    \u003c/dependency\u003e\n    \n    \u003c!-- Loading data from CSV --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.apache.commons\u003c/groupId\u003e\n        \u003cartifactId\u003ecommons-csv\u003c/artifactId\u003e\n        \u003cversion\u003e1.6\u003c/version\u003e\n    \u003c/dependency\u003e\n\n    \u003c!-- Logging --\u003e \n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.apache.logging.log4j\u003c/groupId\u003e\n        \u003cartifactId\u003elog4j-slf4j-impl\u003c/artifactId\u003e\n        \u003cversion\u003e2.8.1\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.apache.logging.log4j\u003c/groupId\u003e\n        \u003cartifactId\u003elog4j-core\u003c/artifactId\u003e\n        \u003cversion\u003e2.8.1\u003c/version\u003e\n    \u003c/dependency\u003e\n\n### 1.5 Optional: Logging settings\n\nIf you want to see the logging output create a file named 'log4j2.xml' in the resources folder\nand add the following lines:\n\n    \u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n    \u003cConfiguration monitorinterval=\"30\" status=\"info\" strict=\"true\"\u003e\n        \u003cProperties\u003e\n            \u003cproperty name=\"pattern\"\u003e%-5p [%d{yyyy-MM-dd HH:mm:ss.SSS}][%t][%c] %m%n\u003c/property\u003e\n        \u003c/Properties\u003e\n        \u003cAppenders\u003e\n            \u003cConsole name=\"stdout\" target=\"SYSTEM_OUT\"\u003e\n                \u003cLayout type=\"PatternLayout\" pattern=\"${pattern}\"/\u003e\n            \u003c/Console\u003e\n        \u003c/Appenders\u003e\n    \n        \u003cLoggers\u003e\n            \u003cRoot level=\"debug\"\u003e\n                \u003cAppenderRef ref=\"stdout\" level=\"info\"/\u003e\n            \u003c/Root\u003e\n        \u003c/Loggers\u003e\n    \u003c/Configuration\u003e\n\n### 2. Loading and Describing the Dataset\n\n\u003ccode\u003eAnchorTabular\u003c/code\u003e is henceforth used to easily set up the Anchors algorithm to handle tabular data. \nTherefore, it possesses a builder that enables registering arbitrary columns that describe the dataset. \nA column contains a name for identification, a number of transformations and a discretization.\nWhereas transformations are meant to clean data, discretization may be used to achieve better results with Anchors by \ngrouping various feature values.\n\nThe Titanic dataset gets loaded and configured as follows. \n\n    AnchorTabular anchorTabular = new AnchorTabularBuilderSequential()\n     .setDoBalance(false)\n     .addIgnoredColumn(\"PassengerId\")\n     .addTargetColumn(IntegerColumn.fromStringInput(\"Survived\"))\n     .addColumn(IntegerColumn.fromStringInput(\"Pclass\"))\n     .addColumn(new StringColumn(\"Name\"))\n     .addColumn(new StringColumn(\"Sex\"))\n     .addColumn(DoubleColumn.fromStringInput(\"Age\", -1, 5))\n     .addColumn(IntegerColumn.fromStringInput(\"SibSp\"))\n     .addColumn(IntegerColumn.fromStringInput(\"Parch\"))\n     .addColumn(IntegerColumn.fromStringInput(\"Ticket\", -1,\n             Collections.singletonList(new TicketNumberTransformer()), null))\n     .addColumn(DoubleColumn.fromStringInput(\"Fare\", -1, 6))\n     .addColumn(new StringColumn(\"Cabin\", Arrays.asList(\n             new ReplaceNonEmptyTransformer(true),\n             new ReplaceEmptyTransformer(false)),\n             null))\n     .addColumn(new StringColumn(\"Embarked\"))\n     .build(ClassLoader.getSystemResourceAsStream(\"titanic/train.csv\", true, false);\n\nUsing the sequential tabular builder, definitions for columns are stated in ascending order - just as they appear in the data.\nPlease note that attributes are described in greater depth in the code. \n\nAll of the configured attributes, such as columns, transformations and discretizations can be implemented and \nextended as required.\n\nIt even is possibly to refrain from using this extension altogether and implement a custom solution based directly on \nthe base library.\n\nThe anchorAdapters will conclude this phase by logging all discretization changes it made to the dataset. This helps monitoring the discretization, finding mistakes and looks like follows in this example's case:\n\n    DEBUG [2019-07-26 15:48:28.112][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [Pclass] is configured as follows:\n        [1] --\u003e 2\n        [2] --\u003e 1\n        [3] --\u003e 0\n    DEBUG [2019-07-26 15:48:28.113][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [Name] is configured as follows:\n        [Ware, Mrs. John James (Florence Louise Long)] --\u003e 362\n        [Cotterill, Mr. Henry Harry\"\"] --\u003e 377\n        [Olsson, Mr. Oscar Wilhelm] --\u003e 300\n        [Buckley, Mr. Daniel] --\u003e 106\n        [Buckley, Miss. Katherine] --\u003e 113\n        [Riordan, Miss. Johanna Hannah\"\"] --\u003e 408\n        [Pallas y Castello, Mr. Emilio] --\u003e 369\n        [Karnes, Mrs. J Frank (Claire Bennett)] --\u003e 246\n        [Payne, Mr. Vivian Ponsonby] --\u003e 390\n        [Palsson, Master. Paul Folke] --\u003e 389\n        [Denbury, Mr. Herbert] --\u003e 338\n        [Makinen, Mr. Kalle Edvard] --\u003e 97\n        [Davies, Mr. John Samuel] --\u003e 9\n        [Chronopoulos, Mr. Demetrios] --\u003e 115\n        [Dodge, Mrs. Washington (Ruth Vidaver)] --\u003e 374\n        ... (and 403 more elements)\n    DEBUG [2019-07-26 15:48:28.114][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [Sex] is configured as follows:\n        [female] --\u003e 1\n        [male] --\u003e 0\n    DEBUG [2019-07-26 15:48:28.116][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [Age] is configured as follows:\n        ]-1, -1) --\u003e -1\n        [0.17, 21) --\u003e 17\n        [22, 27) --\u003e 24\n        [28, 39) --\u003e 32\n        [40, 76[ --\u003e 48\n    DEBUG [2019-07-26 15:48:28.116][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [SibSp] is configured as follows:\n        [0] --\u003e 0\n        [1] --\u003e 1\n        [2] --\u003e 2\n        [3] --\u003e 3\n        [4] --\u003e 4\n        [5] --\u003e 5\n        [8] --\u003e 6\n    DEBUG [2019-07-26 15:48:28.116][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [Parch] is configured as follows:\n        [0] --\u003e 0\n        [1] --\u003e 1\n        [2] --\u003e 3\n        [3] --\u003e 2\n        [4] --\u003e 4\n        [5] --\u003e 6\n        [6] --\u003e 5\n        [9] --\u003e 7\n    DEBUG [2019-07-26 15:48:28.118][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [Ticket] is configured as follows:\n        [24065] --\u003e 13\n        [11778] --\u003e 96\n        [2] --\u003e 173\n        [23101284] --\u003e 230\n        [233478] --\u003e 168\n        [23101291] --\u003e 45\n        [3085] --\u003e 30\n        [9232] --\u003e 193\n        [349202] --\u003e 267\n        [349211] --\u003e 68\n        [14879] --\u003e 198\n        [2079] --\u003e 320\n        [349220] --\u003e 10\n        [11813] --\u003e 48\n        [4133] --\u003e 126\n        ... (and 347 more elements)\n    DEBUG [2019-07-26 15:48:28.120][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [Fare] is configured as follows:\n        ]-1, 7.75) --\u003e 7.27\n        [7.78, 8.67) --\u003e 7.9\n        [8.72, 14.46) --\u003e 12.55\n        [14.46, 26) --\u003e 21\n        [26.55, 56.5) --\u003e 31.5\n        [57.75, 512.33[ --\u003e 83.16\n    DEBUG [2019-07-26 15:48:28.120][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [Cabin] is configured as follows:\n        [false] --\u003e 0\n        [true] --\u003e 1\n    DEBUG [2019-07-26 15:48:28.121][main][de.viadee.xai.anchor.adapter.tabular.builder.TabularPreprocessor] Discretization for column [Embarked] is configured as follows:\n        [Q] --\u003e 0\n        [S] --\u003e 1\n        [C] --\u003e 2\n\n### 3. Obtaining the Model\nAnchors is a \u003cspan style=\"background-color: #FFFF00\"\u003eModel-Agnostic\u003c/span\u003e explanation algorithm and can describe \n\u003cb\u003eany\u003c/b\u003e classification model. Hence, its presence is implicitly assumed when creating explanations. \n\nHowever, for this example a default solution, i.e. a random forest model is used to remove the need for requirements.\n\n    TabularRandomForestClassifier randomForestModel = new TabularRandomForestClassifier(100, true);\n    randomForestModel.fit(anchorTabular.getTabularInstances());\n                    \nNonetheless, an arbitrary and custom model can easily be included by implementing the \n\u003ccode\u003eClassificationFunction\u003c/code\u003e interface and its predict method.\nMore options are further provided by the \u003ccode\u003eModelImportExtension\u003c/code\u003e project. This enables, among others, exported \nH2O models to be effortlessly explained.\n                    \n### 4. Obtaining the Explanation\nSince both a classifier and perturbation function are now provided, an \u003ccode\u003eAnchorConstructionBuilder\u003c/code\u003e can be \nobtained. \n(The perturbation function is created by AnchorTabular. Implementing a custom solution is - of course - possible)\n\nThe \u003ccode\u003eAnchorConstructionBuilder\u003c/code\u003e offers configuring various parameters of the algorithm and\ncan be received by the previously configured \u003ccode\u003eAnchorTabular\u003c/code\u003e as follows:\n\n    AnchorConstructionBuilder\u003cTabularInstance\u003e defaultBuilder = anchorTabular\n                    .createDefaultBuilder(classifier, anchorTabular.getTabularInstances()[0]);\n                    \nThis builder instance can henceforth be used to create explanations (in this case for the first instance contained \nby the \u003ccode\u003eanchorTabular\u003c/code\u003e instance):\n\n    AnchorResult\u003cTabularInstance\u003e anchor = defaultBuilder.build().constructAnchor();        \n    \n\u003ccode\u003eanchor\u003c/code\u003e now provides information about why the model predicted the instance the way it did. \nIn order to make the explanation human readable, the \u003ccode\u003eTabularInstanceVisualizer\u003c/code\u003e provided by the \n\u003ccode\u003eanchorTabular\u003c/code\u003e can be used as follows:\n\n    System.out.println(\"====Explained instance====\" + System.lineSeparator() +\n            anchorTabular.getVisualizer().visualizeInstance(anchor.getInstance()));\n            \n    System.out.println(\"====Result====\" + System.lineSeparator() +\n            anchorTabular.getVisualizer().visualizeResult(anchor));\n            \n### 5. Global Explanations\nThe main project contains various algorithms that are able to aggregate multiple single explanations. \nThereof, \u003ccode\u003eCoveragePick\u003c/code\u003e is expected to work best. It can be used as follows:\n\n    List\u003cAnchorResult\u003cTabularInstance\u003e\u003e globalExplanations = new CoveragePick\u003c\u003e(defaultBuilder, 10,\n                                                                                Executors.newCachedThreadPool(),\n                                                                                null)\n                    .run(anchorTabular.shuffleSplitInstances(1, 0)[0], 20);          \n\nSimilarly, its results may be visualized\n    \n    System.out.println(anchorTabular.getVisualizer().visualizeGlobalResults(globalExplanations));\n       \n    \n### 6. Exemplary Outputs\nThe above stated examples produce output similar to the following samples.\n\n    ====Explained instance====\n        Pclass='3'\n        Name='Gilnagh, Miss. Katherine 'Katie''\n        Sex='female'\n        Age='16'\n        SibSp='0'\n        Parch='0'\n        Ticket='35851'\n        Fare='7'\n        Embarked='Q'\n        WITH LABEL Survived='1'\n    ====Result====\n        IF Sex='female' {0.85,-0.58} AND \n        Embarked='Q' {0.11,-0.37} AND \n        SibSp='0' {0.04,-0} AND \n        Parch='0' {0.02,-0}\n        THEN PREDICT 1\n        WITH PRECISION 1.0 AND COVERAGE 0.033\n\n    \n    ===Global Result #1===\n        IF Fare IN RANGE [0,8] {0.63,-0.64} AND \n        Sex='male' {0.37,-0.07} AND \n        Parch='0' {0.01,-0}\n        THEN PREDICT 0\n        WITH PRECISION 1.0 AND COVERAGE 0.283\n    ===Global Result #2===\n        IF Fare IN RANGE [53,512] {0.68,-0.8} AND \n        Sex='female' {0.29,-0.07} AND \n        Pclass='1' {0.04,-0}\n        THEN PREDICT 1\n        WITH PRECISION 1.0 AND COVERAGE 0.117\n    ===Global Result #3===\n        IF SibSp='8' {0.64,-0.99} AND \n        Pclass='3' {0.06,0} AND \n        Ticket='CA. 2343' {0.19,0} AND \n        Embarked='S' {0.09,0} AND \n        Age IN RANGE [-1,0] {0.04,0}\n        THEN PREDICT 0\n        WITH PRECISION 1.0 AND COVERAGE 0.007\n    ===Global Result #4===\n        IF Fare IN RANGE [27,52] {0.61,-0.87} AND \n        Name='Barkworth, Mr. Algernon Henry Wilson' {0.24,-0.12} AND \n        Ticket='27042' {0.16,0}\n        THEN PREDICT 1\n        WITH PRECISION 1.0 AND COVERAGE 0.002\n    ===Global Result #5===\n        IF Fare IN RANGE [15,26] {0.55,-0.81} AND \n        Parch='2' {0.19,-0.16} AND \n        SibSp='1' {0.12,-0.02} AND \n        Name='Dean, Master. Bertram Vere' {0.16,0}\n        THEN PREDICT 1\n        WITH PRECISION 1.0 AND COVERAGE 0.002\n        \nNote that the bracketed values describe the added precision and coverage the inclusion of the respective feature \neffected. These values can be used to quickly infer a less precise anchor having a superior coverage.        \n\n### Optimizations \n\nThe required time to obtain explanations depends almost exclusively on the model and its latencies.\nDepending on the explained instances and set parameters, this runtime can range from a few seconds to multiple hours.\n\nThe above examples should terminate in a few seconds, due to the random forest's high performance.\n\nSo, it shall not go unnoticed that the previous examples can be sped up significantly by configuring Anchors to \nutilize different forms of parallelization:\n\n#### Threading\n\nEnabling threading is easily achieved by configuring the \n\u003ccode\u003eAnchorConstructionBuilder\u003c/code\u003e:\n\n    defaultBuilder.enableThreading(10 /*ThreadCount*/, Executors.newFixedThreadPool(10), null);\n    \nThis leads to single explanations being explained significantly fast (depending on your machine's performance and the \nmodel's latency).\n\n#### FastMPJ and Apache Spark\n\nFurthermore, multiple approaches are included in this project to load balance the creation of multiple explanations\namong a cluster of computers.\nThis is especially useful for global explanations.\n\n* A message passing interface (MPI) implementation is included in the \u003ccode\u003eFastMPJExtension\u003c/code\u003e package.\n* An Apache Spark adapter can be found in the \u003ccode\u003eSparkExtension\u003c/code\u003e.\n* A default Threading approach is included in anchorj core.\n\nThese methods provide implementations of the \u003ccode\u003eBatchExplainer\u003c/code\u003e interface which can be plugged in to the global\nexplainers as follows:\n\n    new CoveragePick\u003c\u003e(false, new SparkBatchExplainer(sparkContext), defaultBuilder);\n    \nHowever, these methods require advanced setups and configurations. \nFor further information, please refer to respective project documentations.\n\n# Collaboration\n\nThe project is operated and further developed by the viadee Consulting AG in Münster, Westphalia. Results from theses at the WWU Münster and the FH Münster have been incorporated.\n* Further theses are planned: Contact person is Dr. Frank Köhne from viadee.\n    Community contributions to the project are welcome: Please open Github-Issues with suggestions (or PR), which we can then edit in the team. For general discussions please refer to the [main repository](https://github.com/viadee/javaAnchorExplainer).\n*   We are looking for further partners who have interesting process data to refine our tooling as well as partners that are simply interested in a discussion about AI in the context of business process automation and explainability.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviadee%2Fxai_examples","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviadee%2Fxai_examples","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviadee%2Fxai_examples/lists"}