dro 0.2.0__py3-none-any.whl

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.
doc/__init__.py ADDED
File without changes
docs-code/__init__.py ADDED
File without changes
docs-code/conf.py ADDED
@@ -0,0 +1,121 @@
1
+ # Configuration file for the Sphinx documentation builder.
2
+ #
3
+ # For the full list of built-in configuration values, see the documentation:
4
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html
5
+
6
+ import sys
7
+ import os
8
+ sys.path.insert(0, os.path.abspath('../dro/src'))
9
+ print(sys.path)
10
+
11
+ project = 'dro'
12
+ copyright = '2025, Jiashuo Liu, Tianyu Wang, Peng Cui, Hongseok Namkoong, Jose Blanchet'
13
+ author = 'Jiashuo Liu, Tianyu Wang, Peng Cui, Hongseok Namkoong, Jose Blanchet'
14
+ release = '0.1.1'
15
+
16
+ # html_static_path = ['../docs']
17
+ html_baseurl = 'https://namkoong-lab.github.io/dro/'
18
+
19
+
20
+ extensions = [
21
+ 'sphinx.ext.autodoc',
22
+ 'sphinx.ext.intersphinx',
23
+ 'sphinx_autodoc_typehints',
24
+ 'sphinx.ext.mathjax',
25
+ "myst_parser",
26
+ 'nbsphinx',
27
+ 'sphinx_copybutton'
28
+ ]
29
+
30
+ autodoc_type_aliases = {
31
+ 'NDArray': 'numpy.ndarray',
32
+ "Expression": "cvxpy.expressions.expression.Expression",
33
+ 'Tensor': 'torch.Tensor',
34
+ # 'Module': 'torch.nn.Module'
35
+ }
36
+
37
+ autodoc_default_options = {
38
+ "no-autoparams": True
39
+ }
40
+
41
+ intersphinx_mapping = {
42
+ 'numpy': ('https://numpy.org/doc/stable/', None),
43
+ 'torch': ('https://pytorch.org/docs/stable/', None),
44
+ 'python': ('https://docs.python.org/3', None)
45
+ }
46
+
47
+ source_suffix = {
48
+ ".rst": "restructuredtext",
49
+ ".md": "markdown",
50
+ }
51
+
52
+ autodoc_typehints = "description"
53
+
54
+ # html_theme = 'sphinx_rtd_theme'
55
+ # html_theme_options = {
56
+ # 'navigation_depth': 4,
57
+ # 'collapse_navigation': False
58
+ # }
59
+
60
+
61
+ html_theme = 'piccolo_theme'
62
+ html_theme_options = {
63
+ "source_url": 'https://github.com/namkoong-lab/dro',
64
+ "source_icon": "github",
65
+ "globaltoc_collapse": False,
66
+ "banner_text": 'A GIFT to the whole DRO community!',
67
+ "banner_hiding": "temporal",
68
+ # "canonical_url": "",
69
+ # "analytics_id": "",
70
+ }
71
+
72
+
73
+ autodoc_default_options = {
74
+ 'member-order': 'bysource',
75
+ 'undoc-members': True,
76
+ 'show-inheritance': True,
77
+ "private-members": False
78
+ }
79
+
80
+ myst_enable_extensions = [
81
+ "dollarmath",
82
+ "colon_fence",
83
+ "html_image",
84
+ "linkify",
85
+ ]
86
+
87
+ nbsphinx_execute = 'auto'
88
+ nbsphinx_kernel_name = 'python3'
89
+ nbsphinx_timeout = 600
90
+ nbsphinx_prompt_width = "0"
91
+ nbsphinx_include_pattern = []
92
+
93
+
94
+ autoclass_content = 'both'
95
+
96
+ # add_module_names = False
97
+
98
+ nitpicky = True
99
+ nitpick_ignore = [
100
+ ("py:class", "torch.device"),
101
+ ("py:class", "torch.nn.Module"),
102
+ ("py:class", "nn.Module"),
103
+ ("py:class", "Module"),
104
+ ("py:exc", "LinAlgError"),
105
+ ('py:exc', 'MOTDROError'),
106
+ ('py:exc', 'KLDROError'),
107
+ ('py:exc', 'Chi2DROError'),
108
+ ('py:exc', 'BayesianDROError'),
109
+ ('py:exc', 'MMDDROError'),
110
+ ('py:exc', 'KLDROError'),
111
+ ('py:exc', 'ConditionalCVaRDROError'),
112
+ ('py:exc', 'HRDROError'),
113
+ ('py:exc', 'MarginalCVaRDROError'),
114
+ ('py:exc', 'ORWDROError'),
115
+ ('py:exc', 'SinkhornDROError'),
116
+ ('py:exc', 'TVDROError'),
117
+ ('py:exc', 'WassersteinDROError'),
118
+ ('py:exc', 'DROError'),
119
+ ('py:exc', 'CVaRDROError'),
120
+ ('py:exc', 'LinearModel')
121
+ ]
dro/__init__.py ADDED
@@ -0,0 +1,6 @@
1
+ __version__ = "0.2.0"
2
+ __author__ = 'DRO developers.'
3
+ __credits__ = "Tsinghua University, Columbia University, and Stanford University"
4
+
5
+
6
+ from .src import *
dro/src/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .data import *
2
+ from .linear_model import *
3
+ from .neural_model import *
@@ -0,0 +1,2 @@
1
+ from .dataloader_classification import classification_basic, classification_DN21, classification_SNVD20, classification_LWLC
2
+ from .dataloader_regression import regression_basic, regression_DN20_1, regression_DN20_2, regression_DN20_3, regression_LWLC
@@ -0,0 +1,154 @@
1
+ import numpy as np
2
+ from dro.src.data.draw_utils import draw_classification
3
+
4
+ def classification_basic(d=2, k=2, num_samples=500, radius=5.0, seed=42, visualize=False, save_dir= None):
5
+ """
6
+ Basic classification setting.
7
+
8
+ Parameters:
9
+ - d (int): The dimension of covariates
10
+ - k (int): The number of classes
11
+ - num_samples (int): The number of samples
12
+ - radius (float): The radius of the ball to sample the class center
13
+ - seed (int): Random seed.
14
+ - visualize (bool): Whether to visualize the data
15
+ - save_dir (str): The save path of the visualization figure, if set None, we just visualize instead of storing it.
16
+
17
+ Returns:
18
+ - X (numpy.ndarray): A numpy array containing the generated covariate data
19
+ - y (numpy.ndarray): A numpy array containing the generated target data
20
+ """
21
+ np.random.seed(seed)
22
+ samples_per_class = num_samples // k
23
+ X, y = [], []
24
+
25
+ centers = np.random.randn(k, d)
26
+ centers /= np.linalg.norm(centers, axis=1, keepdims=True)
27
+ centers *= radius
28
+
29
+ for i, center in enumerate(centers):
30
+ class_points = np.random.randn(samples_per_class, d) + center
31
+ X.append(class_points)
32
+ y.append(np.full(samples_per_class, 2 * i - 1))
33
+
34
+ X = np.vstack(X)
35
+ y = np.hstack(y)
36
+
37
+ if visualize:
38
+ draw_classification(X, y, save_dir)
39
+
40
+ return X, y
41
+
42
+
43
+ def classification_DN21(d, flip_ratio=0.1, num_samples=100, seed=42, visualize=False, save_dir="./visualization.png"):
44
+ """
45
+ Following Section 3.1.1 of "Learning Models with Uniform Performance via Distributionally Robust Optimization"
46
+ link: https://arxiv.org/pdf/1810.08750
47
+
48
+ Parameters:
49
+ - d (int): The dimension of covariates
50
+ - flip_ratio (fload): The ratio of labels to be flipped
51
+ - num_samples (int): The number of samples
52
+ - seed (int): Random seed.
53
+ - visualize (bool): Whether to visualize the data
54
+ - save_dir (str): The save path of the visualization figure
55
+
56
+ Returns:
57
+ - X (numpy.ndarray): A numpy array containing the generated covariate data
58
+ - y_noisy (numpy.ndarray): A numpy array containing the generated target data
59
+ """
60
+
61
+ np.random.seed(seed)
62
+
63
+ X = np.random.randn(num_samples, d)
64
+
65
+ theta_star = np.random.randn(d)
66
+ theta_star /= np.linalg.norm(theta_star)
67
+
68
+ y_clean = np.sign(X @ theta_star)
69
+
70
+ flip_mask = np.random.rand(num_samples) < flip_ratio
71
+ y_noisy = np.where(flip_mask, -y_clean, y_clean)
72
+
73
+ if visualize:
74
+ draw_classification(X, y_noisy, save_dir)
75
+
76
+ return X, y_noisy
77
+
78
+
79
+ def classification_SNVD20(num_samples=500, seed=42, visualize=False, save_dir="./visualization.png"):
80
+ """
81
+ Following Section 5.1 of "Certifying Some Distributional Robustness with Principled Adversarial Training"
82
+ link: https://arxiv.org/pdf/1710.10571
83
+
84
+ Parameters:
85
+ - num_samples (int): The number of samples
86
+ - seed (int): Random seed.
87
+ - visualize (bool): Whether to visualize the data
88
+ - save_dir (str): The save path of the visualization figure
89
+
90
+ Returns:
91
+ - X_filtered (numpy.ndarray): A numpy array containing the generated covariate data
92
+ - y_filtered (numpy.ndarray): A numpy array containing the generated target data
93
+ """
94
+
95
+ np.random.seed(seed)
96
+ X = np.random.randn(num_samples, 2)
97
+ norms = np.linalg.norm(X, axis=1)
98
+ y = np.sign(norms-np.sqrt(2))
99
+ lower_bound = np.sqrt(2) / 1.3
100
+ upper_bound = 1.3 * np.sqrt(2)
101
+ mask = (norms < lower_bound) | (norms > upper_bound)
102
+
103
+ X_filtered = X[mask]
104
+ y_filtered = y[mask]
105
+
106
+ if visualize:
107
+ draw_classification(X_filtered, y_filtered, save_dir)
108
+
109
+ return X_filtered, y_filtered
110
+
111
+
112
+ def classification_LWLC(num_samples=10000, d=5, bias=0.5, scramble=True, sigma_s=3.0, sigma_v=0.3, high_dimension=300, seed=42, visualize=False, save_dir="./visualization.png"):
113
+ """
114
+ Following Section 4.1 (Classification) of "Distributionally Robust Optimization with Data Geometry"
115
+ link: https://proceedings.neurips.cc/paper_files/paper/2022/file/da535999561b932f56efdd559498282e-Paper-Conference.pdf
116
+
117
+ Parameters:
118
+ - num_samples (int): The number of samples
119
+ - d (int): The dimension of feature S and V
120
+ - bias (float): The bias ratio in (0,1)
121
+ - scramble (bool): Whether to mix the features S and V
122
+ - sigma_s (float): The variance of the Guassian distribution to sample the feature S
123
+ - sigma_v (float): The variance of the Guassian distribution to sample the feature V
124
+ - high_dimension (int): The final dimension of X
125
+ - seed (int): Random seed.
126
+ - visualize (bool): Whether to visualize the data
127
+ - save_dir (str): The save path of the visualization figure
128
+
129
+ Returns:
130
+ - X (numpy.ndarray): A numpy array containing the generated (high-dimensional) covariate data
131
+ - y (numpy.ndarray): A numpy array containing the generated target data
132
+ """
133
+ from scipy.stats import ortho_group
134
+ S = np.float32(ortho_group.rvs(size=1, dim=high_dimension, random_state=1))
135
+
136
+ np.random.seed(seed)
137
+ y = np.random.choice([1, -1], size=(num_samples, 1))
138
+ X = np.random.randn(num_samples, d * 2)
139
+
140
+ X[:, :d] *= sigma_s
141
+ X[:, d:] *= sigma_v
142
+ flip = np.random.choice([1, -1], size=(num_samples, 1), p=[bias, 1. - bias]) * y
143
+ X[:, :d] += y
144
+ X[:, d:] += flip
145
+ if scramble:
146
+ X = np.tile(X,(1,high_dimension//(2*d)))
147
+ X = np.matmul(X, S)
148
+
149
+ if visualize:
150
+ draw_classification(X, y, save_dir)
151
+
152
+ return X, y
153
+
154
+
@@ -0,0 +1,177 @@
1
+ import numpy as np
2
+ from sklearn.datasets import make_regression
3
+ from ucimlrepo import fetch_ucirepo
4
+ import pandas as pd
5
+
6
+ def regression_basic(num_samples=100, d=1, noise=0.1, seed=42):
7
+ """
8
+ Basic regression setting.
9
+
10
+ Parameters:
11
+ - num_samples (int): The number of samples
12
+ - d (int): The dimension of covariates
13
+ - noise (float): The variance of the noise term
14
+ - seed (int): Random seed.
15
+
16
+ Returns:
17
+ - X (numpy.ndarray): A numpy array containing the generated covariate data
18
+ - y (numpy.ndarray): A numpy array containing the generated target data
19
+ """
20
+
21
+ X, y = make_regression(n_samples=num_samples, n_features=d, noise=noise, random_state=seed)
22
+ return X, y
23
+
24
+
25
+ def regression_DN20_1(num_samples, d=5, noise=0.01, seed=42):
26
+ """
27
+ Following Section 3.1.2 of "Learning Models with Uniform Performance via Distributionally Robust Optimization"
28
+ link: https://arxiv.org/pdf/1810.08750
29
+
30
+ Parameters:
31
+ - num_samples (int): The number of samples
32
+ - d (int): The dimension of covariates
33
+ - noise (float): The variance of the noise term
34
+ - seed (int): Random seed.
35
+
36
+ Returns:
37
+ - X (numpy.ndarray): A numpy array containing the generated covariate data
38
+ - y (numpy.ndarray): A numpy array containing the generated target data
39
+ """
40
+ np.random.seed(seed)
41
+
42
+ X = np.random.randn(num_samples, d)
43
+ eps = np.random.randn(num_samples)*noise
44
+ theta_star = np.random.randn(d)
45
+ theta_star /= np.linalg.norm(theta_star)
46
+
47
+ y = X @ theta_star+eps
48
+ y_noisy = np.where(X[:,0]>1.645, y+X[:,0], y)
49
+
50
+ return X, y_noisy
51
+
52
+
53
+ def regression_DN20_2(num_samples, prob=0.1, noise=0.01, seed=42):
54
+ """
55
+ Following Section 3.1.3 of "Learning Models with Uniform Performance via Distributionally Robust Optimization"
56
+ link: https://arxiv.org/pdf/1810.08750
57
+
58
+ Parameters:
59
+ - num_samples (int): The number of samples
60
+ - prob (float): the minority group ratio in (0,1)
61
+ - noise (float): The variance of the noise term
62
+ - seed (int): Random seed.
63
+
64
+ Returns:
65
+ - X (numpy.ndarray): A numpy array containing the generated covariate data
66
+ - y (numpy.ndarray): A numpy array containing the generated target data
67
+ """
68
+
69
+ np.random.seed(seed)
70
+ X = np.random.randn(num_samples, 2)
71
+ theta_star1 = np.array([1.0, 0.1]).T
72
+ theta_star2 = np.array([1.0, 1.0]).T
73
+
74
+ eps = np.random.randn(num_samples)*noise
75
+ G = np.random.uniform(low=0, high=1, size=num_samples)
76
+ y = np.where(G<prob, X@theta_star1+eps, X@theta_star2+eps)
77
+
78
+ return X, y
79
+
80
+ def regression_DN20_3(save_dir="./data/", download=True):
81
+ """
82
+ Following Section 3.3 of "Learning Models with Uniform Performance via Distributionally Robust Optimization"
83
+ link: https://arxiv.org/pdf/1810.08750
84
+
85
+ Data is from UCI repository: https://archive.ics.uci.edu/dataset/183/communities+and+crime
86
+
87
+ Parameters:
88
+ - save_dir (str): The path to save the data
89
+ - download (bool): Whether to download the data. If not, will load the data according to the save_dir
90
+
91
+ Returns:
92
+ - X (numpy.ndarray): A numpy array containing the generated covariate data
93
+ - y (numpy.ndarray): A numpy array containing the generated target data
94
+ """
95
+ if download:
96
+ communities_and_crime = fetch_ucirepo(id=183)
97
+ X = communities_and_crime.data.features
98
+ y = communities_and_crime.data.targets
99
+ X = X.drop(columns=['communityname'])
100
+ X_values = X.apply(pd.to_numeric, errors='coerce')
101
+ X_filled = X_values.apply(lambda col: col.fillna(col.mean()) if col.dtype in ['float64', 'int64'] else col, axis=0)
102
+ X_values = X_filled.to_numpy()
103
+ y = y.to_numpy()
104
+ np.savez(f'{save_dir}crime.npz', X=X_values, y=y)
105
+ else:
106
+ try:
107
+ data = np.load(f'{save_dir}crime.npz')
108
+ X = data["X"]
109
+ y = data["y"]
110
+ except Exception as e :
111
+ print(e)
112
+ print("Please set download=True and retry!")
113
+ return X, y
114
+
115
+ def regression_LWLC(n1=100000, n2=1000, ps=5, pvb=1, pv=4, r=1.7, scramble=False):
116
+ """
117
+ Following Section 4.1 (Regression) of "Distributionally Robust Optimization with Data Geometry"
118
+ link: https://proceedings.neurips.cc/paper_files/paper/2022/file/da535999561b932f56efdd559498282e-Paper-Conference.pdf
119
+
120
+ n1: total number of samples in the pool
121
+ n2: number of samples required
122
+ r: controls the spurious correlation between pvb and y
123
+ scramble: whether to mix S and V
124
+
125
+ Parameters:
126
+ - n1 (int): The total number of samples in the pool
127
+ - n2 (int): The number of samples required
128
+ - ps (int): The dimension of feature S
129
+ - pvb (int): The dimension of feature Vb
130
+ - pv (int): The dimension of other features in V (except for Vb)
131
+ - r (float): The adjustment parameter to control the spurious correlation with |r|>1. Higher |r| denotes stronger spurious correlation, and sign(r) controls the direction of spurious correlation
132
+ - scramble (bool): Whether to mix the features S and V.
133
+
134
+ Returns:
135
+ - X (numpy.ndarray): A numpy array containing the generated covariate data
136
+ - y (numpy.ndarray): A numpy array containing the generated target data
137
+ """
138
+
139
+ S = np.random.normal(0, 2, [n1, ps])
140
+
141
+ Z = np.random.normal(0, 1, [n1, ps + 1])
142
+ for i in range(ps):
143
+ S[:, i:i + 1] = 0.8 * Z[:, i:i + 1] + 0.2 * Z[:, i + 1:i + 2]
144
+
145
+ beta = np.zeros((ps, 1))
146
+ for i in range(ps):
147
+ beta[i] = (-1) ** i * (i % 3 + 1) * 1.0
148
+
149
+ noise = np.random.normal(0, 0.5, [n1, 1])
150
+
151
+ Y = np.dot(S, beta) + noise + 0.1 * S[:, 0:1] * S[:, 1:2] * S[:, 2:3]
152
+ V = np.random.normal(Y, 2, [n1, pvb + pv])
153
+ V[:, :pv] = np.random.normal(0, 2, [n1, pv])
154
+ index_pre = np.ones([n1, 1], dtype=bool)
155
+ for i in range(pvb):
156
+ D = np.abs(V[:, pv + i:pv + i + 1] * np.sign(r) - Y)
157
+ pro = np.power(np.abs(r), -D * 5)
158
+ selection_bias = np.random.random([n1, 1])
159
+ index_pre = index_pre & (
160
+ selection_bias < pro)
161
+ index = np.where(index_pre == True)
162
+ S_re = S[index[0], :]
163
+ V_re = V[index[0], :]
164
+ Y_re = Y[index[0]]
165
+ n, _ = S_re.shape
166
+ index_s = np.random.permutation(n)
167
+
168
+ X_re = np.hstack((S_re, V_re))
169
+
170
+ X = X_re[index_s[0:n2], :]
171
+ y = Y_re[index_s[0:n2], :]
172
+
173
+ from scipy.stats import ortho_group
174
+ S = np.float32(ortho_group.rvs(size=1, dim=X.shape[1], random_state=1))
175
+ if scramble:
176
+ X = np.matmul(X, S)
177
+ return X, y
@@ -0,0 +1,40 @@
1
+ import matplotlib.pyplot as plt
2
+ from sklearn.decomposition import PCA
3
+ import numpy as np
4
+
5
+ class VisualizationError(Exception):
6
+ """Base exception class for errors in the visualization.
7
+ """
8
+ pass
9
+
10
+ def draw_classification(X, y, save_dir = None, title = None, weight = None, scale = 20):
11
+ """
12
+ two dimensional projection of classification data (X, y)
13
+ """
14
+ if weight is None:
15
+ weight = np.ones(X.shape[0])
16
+ else:
17
+ weight = weight * X.shape[0]
18
+
19
+ if X.shape[1]>2:
20
+ pca = PCA(n_components=2)
21
+ X_2D = pca.fit_transform(X)
22
+ else:
23
+ X_2D = X
24
+ if X.shape[1] == 1:
25
+ raise VisualizationError()
26
+
27
+ plt.figure(figsize=(8, 6))
28
+ plt.scatter(X_2D[:, 0], X_2D[:, 1], s = weight * scale, c = y, cmap=plt.cm.jet, edgecolors="k", alpha=0.7)
29
+ plt.xlabel("Principal Component 1")
30
+ plt.ylabel("Principal Component 2")
31
+ if title is None:
32
+ plt.title("Data Visualization")
33
+ else:
34
+ plt.title(title)
35
+
36
+ plt.colorbar(label="Class Label")
37
+ if save_dir is None:
38
+ plt.show()
39
+ else:
40
+ plt.savefig(save_dir)
dro/src/data/info.py ADDED
@@ -0,0 +1,126 @@
1
+ def list_functions():
2
+ functions_metadata = [
3
+ {
4
+ 'name': 'classification_basic',
5
+ 'description': 'Generate basic classification data where each class is sampled from a different center, with the data points spread radially from the center.',
6
+ 'parameters': [
7
+ ('d', 'int', 'Dimension of the covariates (default: 2)'),
8
+ ('k', 'int', 'Number of classes (default: 2)'),
9
+ ('num_samples', 'int', 'Total number of samples (default: 500)'),
10
+ ('radius', 'float', 'Radius of the ball to sample the class center (default: 5.0)'),
11
+ ('seed', 'int', 'Random seed (default: 42)'),
12
+ ('visualize', 'bool', 'Whether to visualize the data (default: False)'),
13
+ ('save_dir', 'str', 'The save path of the visualization figure (default: "./visualization.png")')
14
+ ],
15
+ 'returns': 'X and y as numpy arrays, where X is the covariate data and y is the target data'
16
+ },
17
+ {
18
+ 'name': 'classification_DN21',
19
+ 'description': 'Generate classification data using a linear decision boundary with label flipping as per the DN21 setting from the paper "Learning Models with Uniform Performance via Distributionally Robust Optimization".',
20
+ 'parameters': [
21
+ ('d', 'int', 'Dimension of the covariates'),
22
+ ('flip_ratio', 'float', 'The ratio of labels to be flipped (default: 0.1)'),
23
+ ('num_samples', 'int', 'Total number of samples (default: 100)'),
24
+ ('seed', 'int', 'Random seed (default: 42)'),
25
+ ('visualize', 'bool', 'Whether to visualize the data (default: False)'),
26
+ ('save_dir', 'str', 'The save path of the visualization figure (default: "./visualization.png")')
27
+ ],
28
+ 'returns': 'X (covariate data) and y_noisy (target data with noise from flipped labels) as numpy arrays'
29
+ },
30
+ {
31
+ 'name': 'classification_SNVD20',
32
+ 'description': 'Generate classification data by applying a filter based on the Euclidean norm of points sampled from a 2D normal distribution, with additional filtering as per the SNVD20 setting from the paper "Certifying Some Distributional Robustness with Principled Adversarial Training".',
33
+ 'parameters': [
34
+ ('num_samples', 'int', 'Total number of samples (default: 500)'),
35
+ ('seed', 'int', 'Random seed (default: 42)'),
36
+ ('visualize', 'bool', 'Whether to visualize the data (default: False)'),
37
+ ('save_dir', 'str', 'The save path of the visualization figure (default: "./visualization.png")')
38
+ ],
39
+ 'returns': 'X_filtered (filtered covariate data) and y_filtered (filtered target data) as numpy arrays'
40
+ },
41
+ {
42
+ 'name': 'classification_LWLC',
43
+ 'description': 'Generate high-dimensional classification data with features scrambled and a Gaussian distribution applied to the feature set, based on the LWLC model from the paper "Distributionally Robust Optimization with Data Geometry".',
44
+ 'parameters': [
45
+ ('num_samples', 'int', 'Total number of samples (default: 10000)'),
46
+ ('d', 'int', 'Dimension of feature sets S and V (default: 5)'),
47
+ ('bias', 'float', 'Bias ratio for class labels (default: 0.5)'),
48
+ ('scramble', 'bool', 'Whether to scramble features (default: True)'),
49
+ ('sigma_s', 'float', 'Variance of the Gaussian distribution for feature S (default: 3.0)'),
50
+ ('sigma_v', 'float', 'Variance of the Gaussian distribution for feature V (default: 0.3)'),
51
+ ('high_dimension', 'int', 'The final dimension of X (default: 300)'),
52
+ ('seed', 'int', 'Random seed (default: 42)'),
53
+ ('visualize', 'bool', 'Whether to visualize the data (default: False)'),
54
+ ('save_dir', 'str', 'The save path of the visualization figure (default: "./visualization.png")')
55
+ ],
56
+ 'returns': 'X (high-dimensional covariate data) and y (target data) as numpy arrays'
57
+ },
58
+ {
59
+ 'name': 'regression_basic',
60
+ 'description': 'Generates a basic regression dataset with a specified number of samples and dimensions, with Gaussian noise added to the target variable.',
61
+ 'parameters': [
62
+ ('num_samples', 'int', 'The number of samples'),
63
+ ('d', 'int', 'The dimension of covariates'),
64
+ ('noise', 'float', 'The variance of the noise term'),
65
+ ('seed', 'int', 'Random seed')
66
+ ],
67
+ 'returns': 'X (numpy.ndarray), y (numpy.ndarray): The generated covariate and target data'
68
+ },
69
+ {
70
+ 'name': 'regression_DN20_1',
71
+ 'description': 'Generates a regression dataset following Section 3.1.2 of "Learning Models with Uniform Performance via Distributionally Robust Optimization", where the target variable has Gaussian noise and a noisy label is added based on the value of the first covariate.',
72
+ 'parameters': [
73
+ ('num_samples', 'int', 'The number of samples'),
74
+ ('d', 'int', 'The dimension of covariates'),
75
+ ('noise', 'float', 'The variance of the noise term'),
76
+ ('seed', 'int', 'Random seed')
77
+ ],
78
+ 'returns': 'X (numpy.ndarray), y_noisy (numpy.ndarray): The generated covariate and noisy target data'
79
+ },
80
+ {
81
+ 'name': 'regression_DN20_2',
82
+ 'description': 'Generates a regression dataset following Section 3.1.3 of "Learning Models with Uniform Performance via Distributionally Robust Optimization", with two different linear models based on a minority group ratio and Gaussian noise.',
83
+ 'parameters': [
84
+ ('num_samples', 'int', 'The number of samples'),
85
+ ('prob', 'float', 'The minority group ratio'),
86
+ ('noise', 'float', 'The variance of the noise term'),
87
+ ('seed', 'int', 'Random seed')
88
+ ],
89
+ 'returns': 'X (numpy.ndarray), y (numpy.ndarray): The generated covariate and target data'
90
+ },
91
+ {
92
+ 'name': 'regression_DN20_3',
93
+ 'description': 'Generates a regression dataset based on the UCI Communities and Crime dataset, as described in Section 3.3 of "Learning Models with Uniform Performance via Distributionally Robust Optimization", with options to download or load the data.',
94
+ 'parameters': [
95
+ ('save_dir', 'str', 'The path to save the data'),
96
+ ('download', 'bool', 'Whether to download the data or load from the saved directory')
97
+ ],
98
+ 'returns': 'X (numpy.ndarray), y (numpy.ndarray): The generated covariate and target data'
99
+ },
100
+ {
101
+ 'name': 'regression_LWLC',
102
+ 'description': 'Generates a regression dataset with controlled spurious correlation, following Section 4.1 of "Distributionally Robust Optimization with Data Geometry", with options to scramble features and control spurious correlations.',
103
+ 'parameters': [
104
+ ('n1', 'int', 'The total number of samples in the pool'),
105
+ ('n2', 'int', 'The number of samples required'),
106
+ ('ps', 'int', 'The dimension of feature S'),
107
+ ('pvb', 'int', 'The dimension of feature Vb'),
108
+ ('pv', 'int', 'The dimension of other features in V (except for Vb)'),
109
+ ('r', 'float', 'The adjustment parameter controlling spurious correlation'),
110
+ ('scramble', 'bool', 'Whether to mix S and V')
111
+ ],
112
+ 'returns': 'X (numpy.ndarray), y (numpy.ndarray): The generated covariate and target data'
113
+ }
114
+ ]
115
+
116
+ for idx, func in enumerate(functions_metadata):
117
+ print(f"Data Generation Mechanism {idx+1}: {func['name']}")
118
+ print(f" Description: {func['description']}")
119
+ print(f" Parameters:")
120
+ for param in func['parameters']:
121
+ print(f" - {param[0]} ({param[1]}): {param[2]}")
122
+ print(f" Returns: {func['returns']}\n")
123
+
124
+
125
+ if __name__ == "__main__":
126
+ list_functions()