trexselector 0.5.9__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.
Potentially problematic release.
This version of trexselector might be problematic. Click here for more details.
- trexselector-0.5.9/PKG-INFO +166 -0
- trexselector-0.5.9/README.md +137 -0
- trexselector-0.5.9/setup.cfg +4 -0
- trexselector-0.5.9/setup.py +31 -0
- trexselector-0.5.9/tests/__init__.py +0 -0
- trexselector-0.5.9/tests/conftest.py +46 -0
- trexselector-0.5.9/tests/test_trexselector/__init__.py +3 -0
- trexselector-0.5.9/tests/test_trexselector/test_add_dummies.py +60 -0
- trexselector-0.5.9/tests/test_trexselector/test_fdp.py +81 -0
- trexselector-0.5.9/tests/test_trexselector/test_tpp.py +81 -0
- trexselector-0.5.9/tests/test_trexselector/test_trex.py +103 -0
- trexselector-0.5.9/trexselector/__init__.py +19 -0
- trexselector-0.5.9/trexselector/add_dummies.py +142 -0
- trexselector-0.5.9/trexselector/fdp.py +145 -0
- trexselector-0.5.9/trexselector/gauss_data.py +49 -0
- trexselector-0.5.9/trexselector/lm_dummy.py +149 -0
- trexselector-0.5.9/trexselector/phi_prime_fun.py +58 -0
- trexselector-0.5.9/trexselector/random_experiments.py +229 -0
- trexselector-0.5.9/trexselector/screen_trex.py +228 -0
- trexselector-0.5.9/trexselector/select_var_fun.py +69 -0
- trexselector-0.5.9/trexselector/select_var_fun_DA_BT.py +77 -0
- trexselector-0.5.9/trexselector/trex.py +611 -0
- trexselector-0.5.9/trexselector.egg-info/PKG-INFO +166 -0
- trexselector-0.5.9/trexselector.egg-info/SOURCES.txt +25 -0
- trexselector-0.5.9/trexselector.egg-info/dependency_links.txt +1 -0
- trexselector-0.5.9/trexselector.egg-info/requires.txt +7 -0
- trexselector-0.5.9/trexselector.egg-info/top_level.txt +2 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: trexselector
|
|
3
|
+
Version: 0.5.9
|
|
4
|
+
Summary: T-Rex Selector: High-Dimensional Variable Selection & FDR Control
|
|
5
|
+
Home-page: https://github.com/ArnauVilella/trexselector-python
|
|
6
|
+
Author: Python port by Arnau Vilella
|
|
7
|
+
Author-email: avp@connect.ust.hk
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: numpy
|
|
14
|
+
Requires-Dist: scipy
|
|
15
|
+
Requires-Dist: scikit-learn
|
|
16
|
+
Requires-Dist: tlars
|
|
17
|
+
Requires-Dist: joblib
|
|
18
|
+
Requires-Dist: matplotlib
|
|
19
|
+
Requires-Dist: pandas
|
|
20
|
+
Dynamic: author
|
|
21
|
+
Dynamic: author-email
|
|
22
|
+
Dynamic: classifier
|
|
23
|
+
Dynamic: description
|
|
24
|
+
Dynamic: description-content-type
|
|
25
|
+
Dynamic: home-page
|
|
26
|
+
Dynamic: requires-dist
|
|
27
|
+
Dynamic: requires-python
|
|
28
|
+
Dynamic: summary
|
|
29
|
+
|
|
30
|
+
# TRexSelector-Python (trexselector)
|
|
31
|
+
|
|
32
|
+
A Python port of the [TRexSelector](https://github.com/jasinmachkour/TRexSelector) R package for high-dimensional variable selection with false discovery rate (FDR) control.
|
|
33
|
+
|
|
34
|
+
## Overview
|
|
35
|
+
|
|
36
|
+
TRexSelector performs fast variable selection in high-dimensional settings while controlling the false discovery rate (FDR) at a user-defined target level. The package is based on the paper [Machkour, Muma, and Palomar (2022)](https://arxiv.org/abs/2110.06048).
|
|
37
|
+
|
|
38
|
+
This Python package provides a port of the original R implementation, maintaining the same functionality while providing a more Pythonic interface. The Python port was created by Arnau Vilella (avp@connect.ust.hk).
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install trexselector==0.5.9
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import numpy as np
|
|
50
|
+
from trexselector import trex, generate_gaussian_data
|
|
51
|
+
|
|
52
|
+
# Generate some example data
|
|
53
|
+
X, y, beta = generate_gaussian_data(n=100, p=20, seed=1234)
|
|
54
|
+
|
|
55
|
+
# Run the T-Rex selector
|
|
56
|
+
res = trex(X=X, y=y)
|
|
57
|
+
|
|
58
|
+
# Get the selected variables
|
|
59
|
+
selected_var = res["selected_var"]
|
|
60
|
+
print(f"Selected variables: {selected_var}")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Library Reference
|
|
64
|
+
|
|
65
|
+
### Main Functions
|
|
66
|
+
|
|
67
|
+
#### trex(X, y, tFDR=0.2, K=20, max_num_dummies=10, max_T_stop=True, method="trex", ...)
|
|
68
|
+
|
|
69
|
+
The main function for high-dimensional variable selection with FDR control.
|
|
70
|
+
|
|
71
|
+
- **X**: ndarray - Predictor matrix of shape (n, p).
|
|
72
|
+
- **y**: ndarray - Response vector of shape (n,).
|
|
73
|
+
- **tFDR**: float - Target FDR level (between 0 and 1).
|
|
74
|
+
- **K**: int - Number of random experiments.
|
|
75
|
+
- **max_num_dummies**: int - Factor determining maximum number of dummies.
|
|
76
|
+
- **max_T_stop**: bool - If True, maximum number of included dummies is set to ceiling(n/2).
|
|
77
|
+
- **method**: str - Method to use ('trex', 'trex+GVS', 'trex+DA+AR1', 'trex+DA+equi', 'trex+DA+BT', 'trex+DA+NN').
|
|
78
|
+
- **Returns**: dict - Contains selected variables and additional information.
|
|
79
|
+
|
|
80
|
+
#### screen_trex(X, y, tFDR=0.2, K=20, max_num_dummies=10, ...)
|
|
81
|
+
|
|
82
|
+
Screening variant of T-Rex for ultra-high dimensional datasets.
|
|
83
|
+
|
|
84
|
+
- **X**, **y**, **tFDR**, **K**: Same as trex().
|
|
85
|
+
- **q**: int - Number of variables to select in each split.
|
|
86
|
+
- **num_splits**: int - Number of splits of the original problem.
|
|
87
|
+
- **Returns**: dict - Contains selected variables and screening information.
|
|
88
|
+
|
|
89
|
+
#### random_experiments(X, y, K=20, T_stop=1, num_dummies=None, ...)
|
|
90
|
+
|
|
91
|
+
Run K random experiments with the T-Rex selector.
|
|
92
|
+
|
|
93
|
+
- **X**, **y**, **K**: Same as trex().
|
|
94
|
+
- **T_stop**: int - Number of included dummies before stopping.
|
|
95
|
+
- **num_dummies**: int - Number of dummies to append.
|
|
96
|
+
- **parallel_process**: bool - If True, experiments run in parallel.
|
|
97
|
+
- **Returns**: dict - Contains experiment results and statistics.
|
|
98
|
+
|
|
99
|
+
### Helper Functions
|
|
100
|
+
|
|
101
|
+
#### add_dummies(X, num_dummies)
|
|
102
|
+
|
|
103
|
+
Add random dummy variables to the predictor matrix.
|
|
104
|
+
|
|
105
|
+
- **X**: ndarray - Predictor matrix.
|
|
106
|
+
- **num_dummies**: int - Number of dummies to append.
|
|
107
|
+
- **Returns**: ndarray - Matrix with appended dummies.
|
|
108
|
+
|
|
109
|
+
#### add_dummies_GVS(X, num_dummies, corr_max=0.5)
|
|
110
|
+
|
|
111
|
+
Add dummy variables with correlation constraints for group variable selection.
|
|
112
|
+
|
|
113
|
+
- **X**: ndarray - Predictor matrix.
|
|
114
|
+
- **num_dummies**: int - Number of dummies to append.
|
|
115
|
+
- **corr_max**: float - Maximum allowed correlation between predictors.
|
|
116
|
+
- **Returns**: dict - Contains matrix with dummies and group information.
|
|
117
|
+
|
|
118
|
+
#### FDP(beta_hat, beta)
|
|
119
|
+
|
|
120
|
+
Compute the false discovery proportion.
|
|
121
|
+
|
|
122
|
+
- **beta_hat**: ndarray - Estimated coefficient vector.
|
|
123
|
+
- **beta**: ndarray - True coefficient vector.
|
|
124
|
+
- **Returns**: float - False discovery proportion.
|
|
125
|
+
|
|
126
|
+
#### TPP(beta_hat, beta)
|
|
127
|
+
|
|
128
|
+
Compute the true positive proportion.
|
|
129
|
+
|
|
130
|
+
- **beta_hat**: ndarray - Estimated coefficient vector.
|
|
131
|
+
- **beta**: ndarray - True coefficient vector.
|
|
132
|
+
- **Returns**: float - True positive proportion.
|
|
133
|
+
|
|
134
|
+
#### generate_gaussian_data(n=50, p=100, seed=789)
|
|
135
|
+
|
|
136
|
+
Generate synthetic Gaussian data for testing.
|
|
137
|
+
|
|
138
|
+
- **n**: int - Number of observations.
|
|
139
|
+
- **p**: int - Number of variables.
|
|
140
|
+
- **seed**: int - Random seed.
|
|
141
|
+
- **Returns**: tuple - (X, y, beta) containing predictor matrix, response, and true coefficients.
|
|
142
|
+
|
|
143
|
+
### Advanced Features
|
|
144
|
+
|
|
145
|
+
The package supports several variants of the T-Rex selector:
|
|
146
|
+
|
|
147
|
+
- **Basic T-Rex**: Standard variable selection with FDR control
|
|
148
|
+
- **T-Rex+GVS**: Group variable selection using correlation structure
|
|
149
|
+
- **T-Rex+DA variants**: Dependency-aware variants
|
|
150
|
+
- AR1: Using AR(1) correlation structure
|
|
151
|
+
- Equi: Using equicorrelation structure
|
|
152
|
+
- BT: Using binary tree structure
|
|
153
|
+
- NN: Using nearest neighbor structure
|
|
154
|
+
|
|
155
|
+
## References
|
|
156
|
+
|
|
157
|
+
- Machkour, J., Muma, M., & Palomar, D. P. (2022). Model-Free Variable Selection with Directed Controls for the False Discovery Rate via Coefficient of Intrinsic Dependence. arXiv preprint arXiv:2110.06048.
|
|
158
|
+
- Machkour, J., Muma, M., & Palomar, D. P. (2022). High-dimensional variable selection for classification via binary random sketching. 2022 30th European Signal Processing Conference (EUSIPCO), 2202-2206.
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
This package is licensed under the GNU General Public License v3.0 (GPL-3.0).
|
|
163
|
+
|
|
164
|
+
## Acknowledgments
|
|
165
|
+
|
|
166
|
+
The original R package [TRexSelector](https://github.com/jasinmachkour/TRexSelector) was created by Jasin Machkour, Simon Tien, Daniel P. Palomar, and Michael Muma. This Python port was developed by Arnau Vilella (avp@connect.ust.hk).
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# TRexSelector-Python (trexselector)
|
|
2
|
+
|
|
3
|
+
A Python port of the [TRexSelector](https://github.com/jasinmachkour/TRexSelector) R package for high-dimensional variable selection with false discovery rate (FDR) control.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
TRexSelector performs fast variable selection in high-dimensional settings while controlling the false discovery rate (FDR) at a user-defined target level. The package is based on the paper [Machkour, Muma, and Palomar (2022)](https://arxiv.org/abs/2110.06048).
|
|
8
|
+
|
|
9
|
+
This Python package provides a port of the original R implementation, maintaining the same functionality while providing a more Pythonic interface. The Python port was created by Arnau Vilella (avp@connect.ust.hk).
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install trexselector==0.5.9
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
import numpy as np
|
|
21
|
+
from trexselector import trex, generate_gaussian_data
|
|
22
|
+
|
|
23
|
+
# Generate some example data
|
|
24
|
+
X, y, beta = generate_gaussian_data(n=100, p=20, seed=1234)
|
|
25
|
+
|
|
26
|
+
# Run the T-Rex selector
|
|
27
|
+
res = trex(X=X, y=y)
|
|
28
|
+
|
|
29
|
+
# Get the selected variables
|
|
30
|
+
selected_var = res["selected_var"]
|
|
31
|
+
print(f"Selected variables: {selected_var}")
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Library Reference
|
|
35
|
+
|
|
36
|
+
### Main Functions
|
|
37
|
+
|
|
38
|
+
#### trex(X, y, tFDR=0.2, K=20, max_num_dummies=10, max_T_stop=True, method="trex", ...)
|
|
39
|
+
|
|
40
|
+
The main function for high-dimensional variable selection with FDR control.
|
|
41
|
+
|
|
42
|
+
- **X**: ndarray - Predictor matrix of shape (n, p).
|
|
43
|
+
- **y**: ndarray - Response vector of shape (n,).
|
|
44
|
+
- **tFDR**: float - Target FDR level (between 0 and 1).
|
|
45
|
+
- **K**: int - Number of random experiments.
|
|
46
|
+
- **max_num_dummies**: int - Factor determining maximum number of dummies.
|
|
47
|
+
- **max_T_stop**: bool - If True, maximum number of included dummies is set to ceiling(n/2).
|
|
48
|
+
- **method**: str - Method to use ('trex', 'trex+GVS', 'trex+DA+AR1', 'trex+DA+equi', 'trex+DA+BT', 'trex+DA+NN').
|
|
49
|
+
- **Returns**: dict - Contains selected variables and additional information.
|
|
50
|
+
|
|
51
|
+
#### screen_trex(X, y, tFDR=0.2, K=20, max_num_dummies=10, ...)
|
|
52
|
+
|
|
53
|
+
Screening variant of T-Rex for ultra-high dimensional datasets.
|
|
54
|
+
|
|
55
|
+
- **X**, **y**, **tFDR**, **K**: Same as trex().
|
|
56
|
+
- **q**: int - Number of variables to select in each split.
|
|
57
|
+
- **num_splits**: int - Number of splits of the original problem.
|
|
58
|
+
- **Returns**: dict - Contains selected variables and screening information.
|
|
59
|
+
|
|
60
|
+
#### random_experiments(X, y, K=20, T_stop=1, num_dummies=None, ...)
|
|
61
|
+
|
|
62
|
+
Run K random experiments with the T-Rex selector.
|
|
63
|
+
|
|
64
|
+
- **X**, **y**, **K**: Same as trex().
|
|
65
|
+
- **T_stop**: int - Number of included dummies before stopping.
|
|
66
|
+
- **num_dummies**: int - Number of dummies to append.
|
|
67
|
+
- **parallel_process**: bool - If True, experiments run in parallel.
|
|
68
|
+
- **Returns**: dict - Contains experiment results and statistics.
|
|
69
|
+
|
|
70
|
+
### Helper Functions
|
|
71
|
+
|
|
72
|
+
#### add_dummies(X, num_dummies)
|
|
73
|
+
|
|
74
|
+
Add random dummy variables to the predictor matrix.
|
|
75
|
+
|
|
76
|
+
- **X**: ndarray - Predictor matrix.
|
|
77
|
+
- **num_dummies**: int - Number of dummies to append.
|
|
78
|
+
- **Returns**: ndarray - Matrix with appended dummies.
|
|
79
|
+
|
|
80
|
+
#### add_dummies_GVS(X, num_dummies, corr_max=0.5)
|
|
81
|
+
|
|
82
|
+
Add dummy variables with correlation constraints for group variable selection.
|
|
83
|
+
|
|
84
|
+
- **X**: ndarray - Predictor matrix.
|
|
85
|
+
- **num_dummies**: int - Number of dummies to append.
|
|
86
|
+
- **corr_max**: float - Maximum allowed correlation between predictors.
|
|
87
|
+
- **Returns**: dict - Contains matrix with dummies and group information.
|
|
88
|
+
|
|
89
|
+
#### FDP(beta_hat, beta)
|
|
90
|
+
|
|
91
|
+
Compute the false discovery proportion.
|
|
92
|
+
|
|
93
|
+
- **beta_hat**: ndarray - Estimated coefficient vector.
|
|
94
|
+
- **beta**: ndarray - True coefficient vector.
|
|
95
|
+
- **Returns**: float - False discovery proportion.
|
|
96
|
+
|
|
97
|
+
#### TPP(beta_hat, beta)
|
|
98
|
+
|
|
99
|
+
Compute the true positive proportion.
|
|
100
|
+
|
|
101
|
+
- **beta_hat**: ndarray - Estimated coefficient vector.
|
|
102
|
+
- **beta**: ndarray - True coefficient vector.
|
|
103
|
+
- **Returns**: float - True positive proportion.
|
|
104
|
+
|
|
105
|
+
#### generate_gaussian_data(n=50, p=100, seed=789)
|
|
106
|
+
|
|
107
|
+
Generate synthetic Gaussian data for testing.
|
|
108
|
+
|
|
109
|
+
- **n**: int - Number of observations.
|
|
110
|
+
- **p**: int - Number of variables.
|
|
111
|
+
- **seed**: int - Random seed.
|
|
112
|
+
- **Returns**: tuple - (X, y, beta) containing predictor matrix, response, and true coefficients.
|
|
113
|
+
|
|
114
|
+
### Advanced Features
|
|
115
|
+
|
|
116
|
+
The package supports several variants of the T-Rex selector:
|
|
117
|
+
|
|
118
|
+
- **Basic T-Rex**: Standard variable selection with FDR control
|
|
119
|
+
- **T-Rex+GVS**: Group variable selection using correlation structure
|
|
120
|
+
- **T-Rex+DA variants**: Dependency-aware variants
|
|
121
|
+
- AR1: Using AR(1) correlation structure
|
|
122
|
+
- Equi: Using equicorrelation structure
|
|
123
|
+
- BT: Using binary tree structure
|
|
124
|
+
- NN: Using nearest neighbor structure
|
|
125
|
+
|
|
126
|
+
## References
|
|
127
|
+
|
|
128
|
+
- Machkour, J., Muma, M., & Palomar, D. P. (2022). Model-Free Variable Selection with Directed Controls for the False Discovery Rate via Coefficient of Intrinsic Dependence. arXiv preprint arXiv:2110.06048.
|
|
129
|
+
- Machkour, J., Muma, M., & Palomar, D. P. (2022). High-dimensional variable selection for classification via binary random sketching. 2022 30th European Signal Processing Conference (EUSIPCO), 2202-2206.
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
This package is licensed under the GNU General Public License v3.0 (GPL-3.0).
|
|
134
|
+
|
|
135
|
+
## Acknowledgments
|
|
136
|
+
|
|
137
|
+
The original R package [TRexSelector](https://github.com/jasinmachkour/TRexSelector) was created by Jasin Machkour, Simon Tien, Daniel P. Palomar, and Michael Muma. This Python port was developed by Arnau Vilella (avp@connect.ust.hk).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r", encoding="utf-8") as fh:
|
|
4
|
+
long_description = fh.read()
|
|
5
|
+
|
|
6
|
+
setup(
|
|
7
|
+
name="trexselector",
|
|
8
|
+
version="0.5.9",
|
|
9
|
+
author="Python port by Arnau Vilella",
|
|
10
|
+
author_email="avp@connect.ust.hk",
|
|
11
|
+
description="T-Rex Selector: High-Dimensional Variable Selection & FDR Control",
|
|
12
|
+
long_description=long_description,
|
|
13
|
+
long_description_content_type="text/markdown",
|
|
14
|
+
url="https://github.com/ArnauVilella/trexselector-python",
|
|
15
|
+
packages=find_packages(),
|
|
16
|
+
classifiers=[
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
],
|
|
21
|
+
python_requires=">=3.8",
|
|
22
|
+
install_requires=[
|
|
23
|
+
"numpy",
|
|
24
|
+
"scipy",
|
|
25
|
+
"scikit-learn",
|
|
26
|
+
"tlars",
|
|
27
|
+
"joblib",
|
|
28
|
+
"matplotlib",
|
|
29
|
+
"pandas"
|
|
30
|
+
],
|
|
31
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pytest configuration file.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import pytest
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
# Add the package root to the Python path
|
|
11
|
+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
|
12
|
+
|
|
13
|
+
@pytest.fixture
|
|
14
|
+
def gaussian_data():
|
|
15
|
+
"""
|
|
16
|
+
Fixture providing Gaussian test data similar to the R package's Gauss_data.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
tuple: X, y, beta where:
|
|
20
|
+
X is the predictor matrix (n x p)
|
|
21
|
+
y is the response vector (n)
|
|
22
|
+
beta is the true coefficient vector (p)
|
|
23
|
+
"""
|
|
24
|
+
# Set seed for reproducibility
|
|
25
|
+
np.random.seed(789)
|
|
26
|
+
|
|
27
|
+
n, p = 50, 100
|
|
28
|
+
|
|
29
|
+
# Generate predictor matrix
|
|
30
|
+
X = np.random.normal(0, 1, size=(n, p))
|
|
31
|
+
|
|
32
|
+
# Scale X
|
|
33
|
+
X = (X - X.mean(axis=0)) / X.std(axis=0, ddof=1)
|
|
34
|
+
|
|
35
|
+
# Generate true coefficient vector (3 non-zero coefficients)
|
|
36
|
+
beta = np.zeros(p)
|
|
37
|
+
beta[:3] = 3.0
|
|
38
|
+
|
|
39
|
+
# Generate response vector
|
|
40
|
+
eps = np.random.normal(0, 1, size=n)
|
|
41
|
+
y = X @ beta + eps
|
|
42
|
+
|
|
43
|
+
# Center y
|
|
44
|
+
y = y - y.mean()
|
|
45
|
+
|
|
46
|
+
return X, y, beta
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for the add_dummies function.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
import numpy as np
|
|
7
|
+
from trexselector import add_dummies
|
|
8
|
+
|
|
9
|
+
def test_add_dummies_input_validation(gaussian_data):
|
|
10
|
+
"""Test error control for inputs X and num_dummies."""
|
|
11
|
+
X, y, _ = gaussian_data
|
|
12
|
+
|
|
13
|
+
# Tests for X
|
|
14
|
+
# Test X must be a 2D array
|
|
15
|
+
with pytest.raises(ValueError, match="'X' must be a 2D numpy array"):
|
|
16
|
+
add_dummies(X=X[:, 0], num_dummies=10)
|
|
17
|
+
|
|
18
|
+
# Create X with NaNs
|
|
19
|
+
X_with_nan = X.copy()
|
|
20
|
+
X_with_nan[0, 0] = np.nan
|
|
21
|
+
|
|
22
|
+
with pytest.raises(ValueError, match="'X' contains NaNs"):
|
|
23
|
+
add_dummies(X=X_with_nan, num_dummies=10)
|
|
24
|
+
|
|
25
|
+
# Tests for num_dummies
|
|
26
|
+
# Test num_dummies must be an integer
|
|
27
|
+
with pytest.raises(ValueError, match="'num_dummies' must be an integer larger or equal to 1"):
|
|
28
|
+
add_dummies(X=X, num_dummies=0.5)
|
|
29
|
+
|
|
30
|
+
# Test num_dummies must be >= 1
|
|
31
|
+
with pytest.raises(ValueError, match="'num_dummies' must be an integer larger or equal to 1"):
|
|
32
|
+
add_dummies(X=X, num_dummies=0)
|
|
33
|
+
|
|
34
|
+
# Test num_dummies must not be negative
|
|
35
|
+
with pytest.raises(ValueError, match="'num_dummies' must be an integer larger or equal to 1"):
|
|
36
|
+
add_dummies(X=X, num_dummies=-10)
|
|
37
|
+
|
|
38
|
+
def test_add_dummies_output_shape(gaussian_data):
|
|
39
|
+
"""Test that the output shape of add_dummies is correct."""
|
|
40
|
+
X, _, _ = gaussian_data
|
|
41
|
+
|
|
42
|
+
# Create a smaller test matrix
|
|
43
|
+
n, p = 20, 5
|
|
44
|
+
np.random.seed(42)
|
|
45
|
+
X_small = np.random.randn(n, p)
|
|
46
|
+
|
|
47
|
+
# Test with different numbers of dummies
|
|
48
|
+
for num_dummies in [1, 2, 3]:
|
|
49
|
+
X_Dummy = add_dummies(X=X_small, num_dummies=num_dummies)
|
|
50
|
+
|
|
51
|
+
# Check shape
|
|
52
|
+
assert X_Dummy.shape == (n, p + num_dummies), f"Expected shape {(n, p + num_dummies)}, got {X_Dummy.shape}"
|
|
53
|
+
|
|
54
|
+
# Check that the first p columns are identical to X
|
|
55
|
+
np.testing.assert_allclose(X_Dummy[:, :p], X_small)
|
|
56
|
+
|
|
57
|
+
# Check that the dummy variables are standardized with more tolerance
|
|
58
|
+
for j in range(p, p + num_dummies):
|
|
59
|
+
assert abs(X_Dummy[:, j].mean()) < 1e-10, f"Dummy column {j} is not centered"
|
|
60
|
+
assert abs(X_Dummy[:, j].std() - 1.0) < 1e-10, f"Dummy column {j} is not standardized"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for the FDP (False Discovery Proportion) function.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
import numpy as np
|
|
7
|
+
from trexselector import FDP, trex
|
|
8
|
+
|
|
9
|
+
def test_fdp_input_validation_beta_hat(gaussian_data):
|
|
10
|
+
"""Test error control for input beta_hat."""
|
|
11
|
+
X, y, beta = gaussian_data
|
|
12
|
+
|
|
13
|
+
# Run T-Rex to get beta_hat
|
|
14
|
+
np.random.seed(1234)
|
|
15
|
+
res = trex(X, y, verbose=False)
|
|
16
|
+
beta_hat = np.zeros(beta.shape[0])
|
|
17
|
+
beta_hat[res["selected_var"]] = 1
|
|
18
|
+
|
|
19
|
+
# Create beta_hat with NAs
|
|
20
|
+
beta_hat_with_nan = beta_hat.copy()
|
|
21
|
+
beta_hat_with_nan[np.random.choice(len(beta_hat), size=10)] = np.nan
|
|
22
|
+
|
|
23
|
+
# Tests
|
|
24
|
+
# Test beta_hat must be 1D array
|
|
25
|
+
with pytest.raises(ValueError, match="'beta_hat' must be a 1D numpy array"):
|
|
26
|
+
FDP(beta_hat=np.column_stack([beta_hat, beta_hat]), beta=beta)
|
|
27
|
+
|
|
28
|
+
# Test beta_hat must be numeric
|
|
29
|
+
with pytest.raises(ValueError, match="'beta_hat' must be a 1D numpy array"):
|
|
30
|
+
FDP(beta_hat=beta_hat.astype(str), beta=beta)
|
|
31
|
+
|
|
32
|
+
# Test beta_hat cannot contain NaNs
|
|
33
|
+
with pytest.raises(ValueError, match="'beta_hat' contains NaNs"):
|
|
34
|
+
FDP(beta_hat=beta_hat_with_nan, beta=beta)
|
|
35
|
+
|
|
36
|
+
def test_fdp_input_validation_beta(gaussian_data):
|
|
37
|
+
"""Test error control for input beta."""
|
|
38
|
+
X, y, beta = gaussian_data
|
|
39
|
+
|
|
40
|
+
# Run T-Rex to get beta_hat
|
|
41
|
+
np.random.seed(1234)
|
|
42
|
+
res = trex(X, y, verbose=False)
|
|
43
|
+
beta_hat = np.zeros(beta.shape[0])
|
|
44
|
+
beta_hat[res["selected_var"]] = 1
|
|
45
|
+
|
|
46
|
+
# Create beta with NAs
|
|
47
|
+
beta_with_nan = beta.copy()
|
|
48
|
+
beta_with_nan[np.random.choice(len(beta), size=10)] = np.nan
|
|
49
|
+
|
|
50
|
+
# Tests
|
|
51
|
+
# Test beta must be 1D array
|
|
52
|
+
with pytest.raises(ValueError, match="'beta' must be a 1D numpy array"):
|
|
53
|
+
FDP(beta_hat=beta_hat, beta=np.column_stack([beta, beta]))
|
|
54
|
+
|
|
55
|
+
# Test beta must be numeric
|
|
56
|
+
with pytest.raises(ValueError, match="'beta' must be a 1D numpy array"):
|
|
57
|
+
FDP(beta_hat=beta_hat, beta=beta.astype(str))
|
|
58
|
+
|
|
59
|
+
# Test beta cannot contain NaNs
|
|
60
|
+
with pytest.raises(ValueError, match="'beta' contains NaNs"):
|
|
61
|
+
FDP(beta_hat=beta_hat, beta=beta_with_nan)
|
|
62
|
+
|
|
63
|
+
# Test length of beta_hat must match length of beta
|
|
64
|
+
with pytest.raises(ValueError, match="Shapes of 'beta_hat' and 'beta' must match"):
|
|
65
|
+
FDP(beta_hat=np.concatenate([beta_hat, beta_hat]), beta=beta)
|
|
66
|
+
|
|
67
|
+
def test_fdp_value_range(gaussian_data):
|
|
68
|
+
"""Test that the value of FDP is in the interval [0, 1]."""
|
|
69
|
+
X, y, beta = gaussian_data
|
|
70
|
+
|
|
71
|
+
# Run T-Rex to get beta_hat
|
|
72
|
+
np.random.seed(1234)
|
|
73
|
+
res = trex(X, y, verbose=False)
|
|
74
|
+
beta_hat = np.zeros(beta.shape[0])
|
|
75
|
+
beta_hat[res["selected_var"]] = 1
|
|
76
|
+
|
|
77
|
+
# Compute FDP
|
|
78
|
+
fdp = FDP(beta_hat=beta_hat, beta=beta)
|
|
79
|
+
|
|
80
|
+
# Test FDP is in [0, 1]
|
|
81
|
+
assert 0 <= fdp <= 1, f"FDP value {fdp} is outside the expected range [0, 1]"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for the TPP (True Positive Proportion) function.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
import numpy as np
|
|
7
|
+
from trexselector import TPP, trex
|
|
8
|
+
|
|
9
|
+
def test_tpp_input_validation_beta_hat(gaussian_data):
|
|
10
|
+
"""Test error control for input beta_hat."""
|
|
11
|
+
X, y, beta = gaussian_data
|
|
12
|
+
|
|
13
|
+
# Run T-Rex to get beta_hat
|
|
14
|
+
np.random.seed(1234)
|
|
15
|
+
res = trex(X, y, verbose=False)
|
|
16
|
+
beta_hat = np.zeros(beta.shape[0])
|
|
17
|
+
beta_hat[res["selected_var"]] = 1
|
|
18
|
+
|
|
19
|
+
# Create beta_hat with NAs
|
|
20
|
+
beta_hat_with_nan = beta_hat.copy()
|
|
21
|
+
beta_hat_with_nan[np.random.choice(len(beta_hat), size=10)] = np.nan
|
|
22
|
+
|
|
23
|
+
# Tests
|
|
24
|
+
# Test beta_hat must be 1D array
|
|
25
|
+
with pytest.raises(ValueError, match="'beta_hat' must be a 1D numpy array"):
|
|
26
|
+
TPP(beta_hat=np.column_stack([beta_hat, beta_hat]), beta=beta)
|
|
27
|
+
|
|
28
|
+
# Test beta_hat must be numeric
|
|
29
|
+
with pytest.raises(ValueError, match="'beta_hat' must be a 1D numpy array"):
|
|
30
|
+
TPP(beta_hat=beta_hat.astype(str), beta=beta)
|
|
31
|
+
|
|
32
|
+
# Test beta_hat cannot contain NaNs
|
|
33
|
+
with pytest.raises(ValueError, match="'beta_hat' contains NaNs"):
|
|
34
|
+
TPP(beta_hat=beta_hat_with_nan, beta=beta)
|
|
35
|
+
|
|
36
|
+
def test_tpp_input_validation_beta(gaussian_data):
|
|
37
|
+
"""Test error control for input beta."""
|
|
38
|
+
X, y, beta = gaussian_data
|
|
39
|
+
|
|
40
|
+
# Run T-Rex to get beta_hat
|
|
41
|
+
np.random.seed(1234)
|
|
42
|
+
res = trex(X, y, verbose=False)
|
|
43
|
+
beta_hat = np.zeros(beta.shape[0])
|
|
44
|
+
beta_hat[res["selected_var"]] = 1
|
|
45
|
+
|
|
46
|
+
# Create beta with NAs
|
|
47
|
+
beta_with_nan = beta.copy()
|
|
48
|
+
beta_with_nan[np.random.choice(len(beta), size=10)] = np.nan
|
|
49
|
+
|
|
50
|
+
# Tests
|
|
51
|
+
# Test beta must be 1D array
|
|
52
|
+
with pytest.raises(ValueError, match="'beta' must be a 1D numpy array"):
|
|
53
|
+
TPP(beta_hat=beta_hat, beta=np.column_stack([beta, beta]))
|
|
54
|
+
|
|
55
|
+
# Test beta must be numeric
|
|
56
|
+
with pytest.raises(ValueError, match="'beta' must be a 1D numpy array"):
|
|
57
|
+
TPP(beta_hat=beta_hat, beta=beta.astype(str))
|
|
58
|
+
|
|
59
|
+
# Test beta cannot contain NaNs
|
|
60
|
+
with pytest.raises(ValueError, match="'beta' contains NaNs"):
|
|
61
|
+
TPP(beta_hat=beta_hat, beta=beta_with_nan)
|
|
62
|
+
|
|
63
|
+
# Test length of beta_hat must match length of beta
|
|
64
|
+
with pytest.raises(ValueError, match="Shapes of 'beta_hat' and 'beta' must match"):
|
|
65
|
+
TPP(beta_hat=np.concatenate([beta_hat, beta_hat]), beta=beta)
|
|
66
|
+
|
|
67
|
+
def test_tpp_value_range(gaussian_data):
|
|
68
|
+
"""Test that the value of TPP is in the interval [0, 1]."""
|
|
69
|
+
X, y, beta = gaussian_data
|
|
70
|
+
|
|
71
|
+
# Run T-Rex to get beta_hat
|
|
72
|
+
np.random.seed(1234)
|
|
73
|
+
res = trex(X, y, verbose=False)
|
|
74
|
+
beta_hat = np.zeros(beta.shape[0])
|
|
75
|
+
beta_hat[res["selected_var"]] = 1
|
|
76
|
+
|
|
77
|
+
# Compute TPP
|
|
78
|
+
tpp = TPP(beta_hat=beta_hat, beta=beta)
|
|
79
|
+
|
|
80
|
+
# Test TPP is in [0, 1]
|
|
81
|
+
assert 0 <= tpp <= 1, f"TPP value {tpp} is outside the expected range [0, 1]"
|