gpe-framework 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gpe_framework-1.0.0/LICENSE +22 -0
- gpe_framework-1.0.0/PKG-INFO +259 -0
- gpe_framework-1.0.0/README.md +225 -0
- gpe_framework-1.0.0/baselines/__init__.py +18 -0
- gpe_framework-1.0.0/baselines/anchors_wrapper.py +257 -0
- gpe_framework-1.0.0/baselines/lime_wrapper.py +266 -0
- gpe_framework-1.0.0/baselines/shap_wrapper.py +261 -0
- gpe_framework-1.0.0/gpe/__init__.py +144 -0
- gpe_framework-1.0.0/gpe/core.py +455 -0
- gpe_framework-1.0.0/gpe/explanation.py +366 -0
- gpe_framework-1.0.0/gpe/metrics.py +380 -0
- gpe_framework-1.0.0/gpe/novel_methods.py +866 -0
- gpe_framework-1.0.0/gpe/tree_utils.py +428 -0
- gpe_framework-1.0.0/gpe/variants.py +523 -0
- gpe_framework-1.0.0/gpe/visualization.py +535 -0
- gpe_framework-1.0.0/gpe_framework.egg-info/PKG-INFO +259 -0
- gpe_framework-1.0.0/gpe_framework.egg-info/SOURCES.txt +23 -0
- gpe_framework-1.0.0/gpe_framework.egg-info/dependency_links.txt +1 -0
- gpe_framework-1.0.0/gpe_framework.egg-info/requires.txt +13 -0
- gpe_framework-1.0.0/gpe_framework.egg-info/top_level.txt +2 -0
- gpe_framework-1.0.0/setup.cfg +4 -0
- gpe_framework-1.0.0/setup.py +48 -0
- gpe_framework-1.0.0/tests/test_core.py +372 -0
- gpe_framework-1.0.0/tests/test_metrics.py +263 -0
- gpe_framework-1.0.0/tests/test_variants.py +251 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vladyslav Dehtiarov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: gpe-framework
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Greedy-Prune-Explain: Minimal local explanations for decision tree predictions
|
|
5
|
+
Home-page: https://github.com/vladdehtiarov/gpe-framework
|
|
6
|
+
Author: Vladyslav Dehtiarov
|
|
7
|
+
Author-email: vvdehtiarov@gmail.com
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Science/Research
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: numpy<2.0.0,>=1.20.0
|
|
24
|
+
Requires-Dist: pandas>=1.3.0
|
|
25
|
+
Requires-Dist: scikit-learn>=1.0.0
|
|
26
|
+
Requires-Dist: scipy>=1.7.0
|
|
27
|
+
Requires-Dist: matplotlib>=3.4.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
31
|
+
Provides-Extra: baselines
|
|
32
|
+
Requires-Dist: lime>=0.2.0; extra == "baselines"
|
|
33
|
+
Requires-Dist: anchor-exp>=0.0.2; extra == "baselines"
|
|
34
|
+
|
|
35
|
+
# GPE Framework - Greedy-Prune-Explain
|
|
36
|
+
|
|
37
|
+
[](https://www.python.org/downloads/)
|
|
38
|
+
[](https://opensource.org/licenses/MIT)
|
|
39
|
+
[](https://badge.fury.io/py/gpe-framework)
|
|
40
|
+
|
|
41
|
+
**GPE (Greedy-Prune-Explain)** is a novel method for generating minimal, interpretable local explanations for decision tree predictions. Unlike existing methods like LIME, SHAP, or Anchors, GPE leverages the inherent structure of decision trees to produce explanations that are:
|
|
42
|
+
|
|
43
|
+
- ✅ **Minimal** — Contains only essential conditions (1-2 instead of 5)
|
|
44
|
+
- ✅ **Precise** — 99.4% precision on real-world financial data
|
|
45
|
+
- ✅ **Fast** — 48x faster than LIME, 19x faster than Anchors
|
|
46
|
+
- ✅ **Actionable** — Simple IF-THEN rules like "income < 50000 AND debt_ratio > 0.4"
|
|
47
|
+
|
|
48
|
+
## 📊 Benchmark Results
|
|
49
|
+
|
|
50
|
+
Tested on 3 financial datasets (632K records total):
|
|
51
|
+
|
|
52
|
+
| Method | Time (ms) | Complexity | Precision | Speedup |
|
|
53
|
+
|--------|-----------|------------|-----------|---------|
|
|
54
|
+
| **GPE-Core** | **4.4** | **1.4** | **99.4%** | **48x** |
|
|
55
|
+
| GPE-IT | 3.0 | 1.4 | 97.9% | 71x |
|
|
56
|
+
| LIME | 213 | 5.0 | — | 1x |
|
|
57
|
+
| Anchors | 82 | 0.7 | 99.2% | 3x |
|
|
58
|
+
|
|
59
|
+
*All results are statistically significant (p < 0.001)*
|
|
60
|
+
|
|
61
|
+
## 🚀 Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install gpe-framework
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Or install from source:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git clone https://github.com/vdehtiarov/gpe-framework.git
|
|
71
|
+
cd gpe-framework
|
|
72
|
+
pip install -e .
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## 📖 Quick Start
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from sklearn.tree import DecisionTreeClassifier
|
|
79
|
+
from sklearn.datasets import load_iris
|
|
80
|
+
from gpe import GPEExplainer
|
|
81
|
+
|
|
82
|
+
# Load data and train model
|
|
83
|
+
iris = load_iris()
|
|
84
|
+
X, y = iris.data, iris.target
|
|
85
|
+
model = DecisionTreeClassifier(max_depth=5)
|
|
86
|
+
model.fit(X, y)
|
|
87
|
+
|
|
88
|
+
# Create explainer
|
|
89
|
+
explainer = GPEExplainer(
|
|
90
|
+
model=model,
|
|
91
|
+
feature_names=iris.feature_names,
|
|
92
|
+
X_train=X,
|
|
93
|
+
min_precision=0.95
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Explain a prediction
|
|
97
|
+
explanation = explainer.explain(X[0])
|
|
98
|
+
print(explanation)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Output:**
|
|
102
|
+
```
|
|
103
|
+
============================================================
|
|
104
|
+
GPE Explanation (method: GPE)
|
|
105
|
+
============================================================
|
|
106
|
+
Prediction: 0
|
|
107
|
+
Rule: petal length (cm) <= 2.45
|
|
108
|
+
------------------------------------------------------------
|
|
109
|
+
Precision: 100.00%
|
|
110
|
+
Coverage: 33.33%
|
|
111
|
+
Complexity: 1 conditions
|
|
112
|
+
Reduction: 75.0% (4 → 1 conditions)
|
|
113
|
+
============================================================
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Natural Language Output
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
print(explanation.to_natural_language())
|
|
120
|
+
```
|
|
121
|
+
```
|
|
122
|
+
The model predicts 'setosa' because petal length is at most 2.45.
|
|
123
|
+
This explanation covers 33.3% of similar cases with 100.0% accuracy.
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 🔧 GPE Variants
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from gpe import (
|
|
130
|
+
GPEExplainer, # Standard (fast, greedy)
|
|
131
|
+
GPEInformationTheoretic, # Uses mutual information for pruning
|
|
132
|
+
GPECounterfactual, # Adds counterfactual explanations
|
|
133
|
+
GPEOptimal, # Exhaustive search for minimal rule
|
|
134
|
+
GPEEnsemble # For Random Forest, XGBoost
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# GPE-IT: Uses mutual information I(condition; prediction)
|
|
138
|
+
gpe_it = GPEInformationTheoretic(model, feature_names=features, X_train=X)
|
|
139
|
+
explanation = gpe_it.explain(x)
|
|
140
|
+
|
|
141
|
+
# GPE-CF: Includes counterfactual explanation
|
|
142
|
+
gpe_cf = GPECounterfactual(model, feature_names=features, X_train=X)
|
|
143
|
+
cf_explanation = gpe_cf.explain_with_counterfactual(x)
|
|
144
|
+
print(f"To change the decision: {cf_explanation.changes}")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## 📖 How It Works
|
|
148
|
+
|
|
149
|
+
GPE operates in three phases:
|
|
150
|
+
|
|
151
|
+
### 1. GREEDY Phase
|
|
152
|
+
Extract the full decision path from root to leaf:
|
|
153
|
+
```
|
|
154
|
+
Root → income <= 50000 → debt_ratio > 0.4 → ... → Leaf (denied)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 2. PRUNE Phase
|
|
158
|
+
Iteratively remove conditions that don't affect precision:
|
|
159
|
+
```python
|
|
160
|
+
while conditions > 1:
|
|
161
|
+
for condition in rule:
|
|
162
|
+
precision_without = calculate_precision(rule - condition)
|
|
163
|
+
if precision_without >= threshold:
|
|
164
|
+
remove(condition)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 3. EXPLAIN Phase
|
|
168
|
+
Return the minimal rule with metrics:
|
|
169
|
+
- **Precision** — Accuracy for instances satisfying the rule
|
|
170
|
+
- **Coverage** — Proportion of dataset satisfying the rule
|
|
171
|
+
- **Complexity** — Number of conditions
|
|
172
|
+
|
|
173
|
+
## 📊 Metrics
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from gpe import (
|
|
177
|
+
precision_score,
|
|
178
|
+
coverage_score,
|
|
179
|
+
complexity_score,
|
|
180
|
+
fidelity_score,
|
|
181
|
+
stability_score
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Evaluate explanation quality
|
|
185
|
+
precision = precision_score(explanation, model, X)
|
|
186
|
+
coverage = coverage_score(explanation, X)
|
|
187
|
+
complexity = complexity_score(explanation)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## 🔬 Scientific Novelty
|
|
191
|
+
|
|
192
|
+
1. **GPE-Core** — First local explanation method specifically designed for decision trees
|
|
193
|
+
2. **GPE-IT** — Novel use of mutual information I(condition; prediction) for condition selection
|
|
194
|
+
3. **Theoretical guarantees** — Proven precision bounds and O(n·d) complexity
|
|
195
|
+
4. **Practical efficiency** — 48x faster than LIME on real data
|
|
196
|
+
|
|
197
|
+
## 📁 Project Structure
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
gpe-framework/
|
|
201
|
+
├── gpe/
|
|
202
|
+
│ ├── __init__.py # Public API
|
|
203
|
+
│ ├── core.py # GPEExplainer
|
|
204
|
+
│ ├── novel_methods.py # GPE-IT, GPE-CF (scientific contribution)
|
|
205
|
+
│ ├── variants.py # GPEOptimal, GPEWeighted
|
|
206
|
+
│ ├── explanation.py # Data structures
|
|
207
|
+
│ ├── metrics.py # Evaluation metrics
|
|
208
|
+
│ ├── tree_utils.py # Tree utilities
|
|
209
|
+
│ └── visualization.py # Plotting functions
|
|
210
|
+
├── tests/ # Unit tests
|
|
211
|
+
├── experiments/ # Benchmark scripts
|
|
212
|
+
└── docs/ # Documentation
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## 🤝 Contributing
|
|
216
|
+
|
|
217
|
+
Contributions are welcome! Please read our contributing guidelines and submit pull requests.
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
# Install development dependencies
|
|
221
|
+
pip install -e ".[dev]"
|
|
222
|
+
|
|
223
|
+
# Run tests
|
|
224
|
+
pytest tests/ -v
|
|
225
|
+
|
|
226
|
+
# Format code
|
|
227
|
+
black gpe/
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## 📜 License
|
|
231
|
+
|
|
232
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
233
|
+
|
|
234
|
+
## 👤 Author
|
|
235
|
+
|
|
236
|
+
**Vladyslav Dehtiarov**
|
|
237
|
+
- Email: vvdehtiarov@gmail.com
|
|
238
|
+
- ORCID: [0000-0002-1578-8588](https://orcid.org/0000-0002-1578-8588)
|
|
239
|
+
- Affiliation: Sumy State University, Ukraine
|
|
240
|
+
|
|
241
|
+
## 📚 Citation
|
|
242
|
+
|
|
243
|
+
If you use GPE in your research, please cite:
|
|
244
|
+
|
|
245
|
+
```bibtex
|
|
246
|
+
@article{dehtiarov2025gpe,
|
|
247
|
+
title={Greedy-Prune-Explain: Minimal Local Explanations for Decision Tree Predictions},
|
|
248
|
+
author={Dehtiarov, Vladyslav and Borovyk, Valentyna},
|
|
249
|
+
journal={International Journal of Artificial Intelligence Research},
|
|
250
|
+
year={2025}
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## 🔗 Links
|
|
255
|
+
|
|
256
|
+
- [GitHub Repository](https://github.com/vdehtiarov/gpe-framework)
|
|
257
|
+
- [PyPI Package](https://pypi.org/project/gpe-framework/)
|
|
258
|
+
- [Documentation](https://github.com/vdehtiarov/gpe-framework#readme)
|
|
259
|
+
- [Issue Tracker](https://github.com/vdehtiarov/gpe-framework/issues)
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# GPE Framework - Greedy-Prune-Explain
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://badge.fury.io/py/gpe-framework)
|
|
6
|
+
|
|
7
|
+
**GPE (Greedy-Prune-Explain)** is a novel method for generating minimal, interpretable local explanations for decision tree predictions. Unlike existing methods like LIME, SHAP, or Anchors, GPE leverages the inherent structure of decision trees to produce explanations that are:
|
|
8
|
+
|
|
9
|
+
- ✅ **Minimal** — Contains only essential conditions (1-2 instead of 5)
|
|
10
|
+
- ✅ **Precise** — 99.4% precision on real-world financial data
|
|
11
|
+
- ✅ **Fast** — 48x faster than LIME, 19x faster than Anchors
|
|
12
|
+
- ✅ **Actionable** — Simple IF-THEN rules like "income < 50000 AND debt_ratio > 0.4"
|
|
13
|
+
|
|
14
|
+
## 📊 Benchmark Results
|
|
15
|
+
|
|
16
|
+
Tested on 3 financial datasets (632K records total):
|
|
17
|
+
|
|
18
|
+
| Method | Time (ms) | Complexity | Precision | Speedup |
|
|
19
|
+
|--------|-----------|------------|-----------|---------|
|
|
20
|
+
| **GPE-Core** | **4.4** | **1.4** | **99.4%** | **48x** |
|
|
21
|
+
| GPE-IT | 3.0 | 1.4 | 97.9% | 71x |
|
|
22
|
+
| LIME | 213 | 5.0 | — | 1x |
|
|
23
|
+
| Anchors | 82 | 0.7 | 99.2% | 3x |
|
|
24
|
+
|
|
25
|
+
*All results are statistically significant (p < 0.001)*
|
|
26
|
+
|
|
27
|
+
## 🚀 Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install gpe-framework
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or install from source:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git clone https://github.com/vdehtiarov/gpe-framework.git
|
|
37
|
+
cd gpe-framework
|
|
38
|
+
pip install -e .
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 📖 Quick Start
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from sklearn.tree import DecisionTreeClassifier
|
|
45
|
+
from sklearn.datasets import load_iris
|
|
46
|
+
from gpe import GPEExplainer
|
|
47
|
+
|
|
48
|
+
# Load data and train model
|
|
49
|
+
iris = load_iris()
|
|
50
|
+
X, y = iris.data, iris.target
|
|
51
|
+
model = DecisionTreeClassifier(max_depth=5)
|
|
52
|
+
model.fit(X, y)
|
|
53
|
+
|
|
54
|
+
# Create explainer
|
|
55
|
+
explainer = GPEExplainer(
|
|
56
|
+
model=model,
|
|
57
|
+
feature_names=iris.feature_names,
|
|
58
|
+
X_train=X,
|
|
59
|
+
min_precision=0.95
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Explain a prediction
|
|
63
|
+
explanation = explainer.explain(X[0])
|
|
64
|
+
print(explanation)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Output:**
|
|
68
|
+
```
|
|
69
|
+
============================================================
|
|
70
|
+
GPE Explanation (method: GPE)
|
|
71
|
+
============================================================
|
|
72
|
+
Prediction: 0
|
|
73
|
+
Rule: petal length (cm) <= 2.45
|
|
74
|
+
------------------------------------------------------------
|
|
75
|
+
Precision: 100.00%
|
|
76
|
+
Coverage: 33.33%
|
|
77
|
+
Complexity: 1 conditions
|
|
78
|
+
Reduction: 75.0% (4 → 1 conditions)
|
|
79
|
+
============================================================
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Natural Language Output
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
print(explanation.to_natural_language())
|
|
86
|
+
```
|
|
87
|
+
```
|
|
88
|
+
The model predicts 'setosa' because petal length is at most 2.45.
|
|
89
|
+
This explanation covers 33.3% of similar cases with 100.0% accuracy.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 🔧 GPE Variants
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from gpe import (
|
|
96
|
+
GPEExplainer, # Standard (fast, greedy)
|
|
97
|
+
GPEInformationTheoretic, # Uses mutual information for pruning
|
|
98
|
+
GPECounterfactual, # Adds counterfactual explanations
|
|
99
|
+
GPEOptimal, # Exhaustive search for minimal rule
|
|
100
|
+
GPEEnsemble # For Random Forest, XGBoost
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# GPE-IT: Uses mutual information I(condition; prediction)
|
|
104
|
+
gpe_it = GPEInformationTheoretic(model, feature_names=features, X_train=X)
|
|
105
|
+
explanation = gpe_it.explain(x)
|
|
106
|
+
|
|
107
|
+
# GPE-CF: Includes counterfactual explanation
|
|
108
|
+
gpe_cf = GPECounterfactual(model, feature_names=features, X_train=X)
|
|
109
|
+
cf_explanation = gpe_cf.explain_with_counterfactual(x)
|
|
110
|
+
print(f"To change the decision: {cf_explanation.changes}")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 📖 How It Works
|
|
114
|
+
|
|
115
|
+
GPE operates in three phases:
|
|
116
|
+
|
|
117
|
+
### 1. GREEDY Phase
|
|
118
|
+
Extract the full decision path from root to leaf:
|
|
119
|
+
```
|
|
120
|
+
Root → income <= 50000 → debt_ratio > 0.4 → ... → Leaf (denied)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 2. PRUNE Phase
|
|
124
|
+
Iteratively remove conditions that don't affect precision:
|
|
125
|
+
```python
|
|
126
|
+
while conditions > 1:
|
|
127
|
+
for condition in rule:
|
|
128
|
+
precision_without = calculate_precision(rule - condition)
|
|
129
|
+
if precision_without >= threshold:
|
|
130
|
+
remove(condition)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 3. EXPLAIN Phase
|
|
134
|
+
Return the minimal rule with metrics:
|
|
135
|
+
- **Precision** — Accuracy for instances satisfying the rule
|
|
136
|
+
- **Coverage** — Proportion of dataset satisfying the rule
|
|
137
|
+
- **Complexity** — Number of conditions
|
|
138
|
+
|
|
139
|
+
## 📊 Metrics
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from gpe import (
|
|
143
|
+
precision_score,
|
|
144
|
+
coverage_score,
|
|
145
|
+
complexity_score,
|
|
146
|
+
fidelity_score,
|
|
147
|
+
stability_score
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# Evaluate explanation quality
|
|
151
|
+
precision = precision_score(explanation, model, X)
|
|
152
|
+
coverage = coverage_score(explanation, X)
|
|
153
|
+
complexity = complexity_score(explanation)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## 🔬 Scientific Novelty
|
|
157
|
+
|
|
158
|
+
1. **GPE-Core** — First local explanation method specifically designed for decision trees
|
|
159
|
+
2. **GPE-IT** — Novel use of mutual information I(condition; prediction) for condition selection
|
|
160
|
+
3. **Theoretical guarantees** — Proven precision bounds and O(n·d) complexity
|
|
161
|
+
4. **Practical efficiency** — 48x faster than LIME on real data
|
|
162
|
+
|
|
163
|
+
## 📁 Project Structure
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
gpe-framework/
|
|
167
|
+
├── gpe/
|
|
168
|
+
│ ├── __init__.py # Public API
|
|
169
|
+
│ ├── core.py # GPEExplainer
|
|
170
|
+
│ ├── novel_methods.py # GPE-IT, GPE-CF (scientific contribution)
|
|
171
|
+
│ ├── variants.py # GPEOptimal, GPEWeighted
|
|
172
|
+
│ ├── explanation.py # Data structures
|
|
173
|
+
│ ├── metrics.py # Evaluation metrics
|
|
174
|
+
│ ├── tree_utils.py # Tree utilities
|
|
175
|
+
│ └── visualization.py # Plotting functions
|
|
176
|
+
├── tests/ # Unit tests
|
|
177
|
+
├── experiments/ # Benchmark scripts
|
|
178
|
+
└── docs/ # Documentation
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## 🤝 Contributing
|
|
182
|
+
|
|
183
|
+
Contributions are welcome! Please read our contributing guidelines and submit pull requests.
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# Install development dependencies
|
|
187
|
+
pip install -e ".[dev]"
|
|
188
|
+
|
|
189
|
+
# Run tests
|
|
190
|
+
pytest tests/ -v
|
|
191
|
+
|
|
192
|
+
# Format code
|
|
193
|
+
black gpe/
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## 📜 License
|
|
197
|
+
|
|
198
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
199
|
+
|
|
200
|
+
## 👤 Author
|
|
201
|
+
|
|
202
|
+
**Vladyslav Dehtiarov**
|
|
203
|
+
- Email: vvdehtiarov@gmail.com
|
|
204
|
+
- ORCID: [0000-0002-1578-8588](https://orcid.org/0000-0002-1578-8588)
|
|
205
|
+
- Affiliation: Sumy State University, Ukraine
|
|
206
|
+
|
|
207
|
+
## 📚 Citation
|
|
208
|
+
|
|
209
|
+
If you use GPE in your research, please cite:
|
|
210
|
+
|
|
211
|
+
```bibtex
|
|
212
|
+
@article{dehtiarov2025gpe,
|
|
213
|
+
title={Greedy-Prune-Explain: Minimal Local Explanations for Decision Tree Predictions},
|
|
214
|
+
author={Dehtiarov, Vladyslav and Borovyk, Valentyna},
|
|
215
|
+
journal={International Journal of Artificial Intelligence Research},
|
|
216
|
+
year={2025}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## 🔗 Links
|
|
221
|
+
|
|
222
|
+
- [GitHub Repository](https://github.com/vdehtiarov/gpe-framework)
|
|
223
|
+
- [PyPI Package](https://pypi.org/project/gpe-framework/)
|
|
224
|
+
- [Documentation](https://github.com/vdehtiarov/gpe-framework#readme)
|
|
225
|
+
- [Issue Tracker](https://github.com/vdehtiarov/gpe-framework/issues)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Baseline Explainer Wrappers.
|
|
3
|
+
|
|
4
|
+
This module provides unified wrappers for comparing GPE with other
|
|
5
|
+
explanation methods:
|
|
6
|
+
- LIME (Local Interpretable Model-agnostic Explanations)
|
|
7
|
+
- SHAP (SHapley Additive exPlanations)
|
|
8
|
+
- Anchors
|
|
9
|
+
|
|
10
|
+
Author: Vladyslav Dehtiarov
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from .lime_wrapper import LIMEWrapper
|
|
14
|
+
from .shap_wrapper import SHAPWrapper
|
|
15
|
+
from .anchors_wrapper import AnchorsWrapper
|
|
16
|
+
|
|
17
|
+
__all__ = ['LIMEWrapper', 'SHAPWrapper', 'AnchorsWrapper']
|
|
18
|
+
|