oikan 0.0.3.2__py3-none-any.whl → 0.0.3.3__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.
- oikan/exceptions.py +25 -1
- oikan/model.py +156 -50
- oikan/utils.py +33 -14
- {oikan-0.0.3.2.dist-info → oikan-0.0.3.3.dist-info}/METADATA +16 -8
- oikan-0.0.3.3.dist-info/RECORD +10 -0
- {oikan-0.0.3.2.dist-info → oikan-0.0.3.3.dist-info}/WHEEL +1 -1
- oikan-0.0.3.2.dist-info/RECORD +0 -10
- {oikan-0.0.3.2.dist-info → oikan-0.0.3.3.dist-info}/licenses/LICENSE +0 -0
- {oikan-0.0.3.2.dist-info → oikan-0.0.3.3.dist-info}/top_level.txt +0 -0
oikan/exceptions.py
CHANGED
@@ -4,4 +4,28 @@ class OIKANError(Exception):
|
|
4
4
|
|
5
5
|
class ModelNotFittedError(OIKANError):
|
6
6
|
"""Raised when a method requires a fitted model."""
|
7
|
-
pass
|
7
|
+
pass
|
8
|
+
|
9
|
+
class InvalidParameterError(OIKANError):
|
10
|
+
"""Raised when an invalid parameter value is provided."""
|
11
|
+
pass
|
12
|
+
|
13
|
+
class DataDimensionError(OIKANError):
|
14
|
+
"""Raised when input data has incorrect dimensions."""
|
15
|
+
pass
|
16
|
+
|
17
|
+
class NumericalInstabilityError(OIKANError):
|
18
|
+
"""Raised when numerical computations become unstable."""
|
19
|
+
pass
|
20
|
+
|
21
|
+
class FeatureExtractionError(OIKANError):
|
22
|
+
"""Raised when feature extraction or transformation fails."""
|
23
|
+
pass
|
24
|
+
|
25
|
+
class ModelSerializationError(OIKANError):
|
26
|
+
"""Raised when model saving/loading operations fail."""
|
27
|
+
pass
|
28
|
+
|
29
|
+
class ConvergenceError(OIKANError):
|
30
|
+
"""Raised when the model fails to converge during training."""
|
31
|
+
pass
|
oikan/model.py
CHANGED
@@ -3,13 +3,14 @@ import torch
|
|
3
3
|
import torch.nn as nn
|
4
4
|
import torch.optim as optim
|
5
5
|
from sklearn.preprocessing import PolynomialFeatures
|
6
|
-
from sklearn.linear_model import
|
6
|
+
from sklearn.linear_model import ElasticNet
|
7
7
|
from abc import ABC, abstractmethod
|
8
8
|
import json
|
9
9
|
from .neural import TabularNet
|
10
10
|
from .utils import evaluate_basis_functions, get_features_involved
|
11
11
|
from sklearn.model_selection import train_test_split
|
12
12
|
from sklearn.metrics import r2_score, accuracy_score
|
13
|
+
from .exceptions import *
|
13
14
|
import sys
|
14
15
|
|
15
16
|
class OIKAN(ABC):
|
@@ -30,6 +31,8 @@ class OIKAN(ABC):
|
|
30
31
|
L1 regularization strength for Lasso in symbolic regression.
|
31
32
|
sigma : float, optional (default=0.1)
|
32
33
|
Standard deviation of Gaussian noise for data augmentation.
|
34
|
+
top_k : int, optional (default=5)
|
35
|
+
Number of top features to select in hierarchical symbolic regression.
|
33
36
|
epochs : int, optional (default=100)
|
34
37
|
Number of epochs for neural network training.
|
35
38
|
lr : float, optional (default=0.001)
|
@@ -43,7 +46,28 @@ class OIKAN(ABC):
|
|
43
46
|
"""
|
44
47
|
def __init__(self, hidden_sizes=[64, 64], activation='relu', augmentation_factor=10,
|
45
48
|
polynomial_degree=2, alpha=0.1, sigma=0.1, epochs=100, lr=0.001, batch_size=32,
|
46
|
-
verbose=False, evaluate_nn=False):
|
49
|
+
verbose=False, evaluate_nn=False, top_k=5):
|
50
|
+
if not isinstance(hidden_sizes, list) or not all(isinstance(x, int) and x > 0 for x in hidden_sizes):
|
51
|
+
raise InvalidParameterError("hidden_sizes must be a list of positive integers")
|
52
|
+
if activation not in ['relu', 'tanh', 'leaky_relu', 'elu', 'swish', 'gelu']:
|
53
|
+
raise InvalidParameterError(f"Unsupported activation function: {activation}")
|
54
|
+
if not isinstance(augmentation_factor, int) or augmentation_factor < 1:
|
55
|
+
raise InvalidParameterError("augmentation_factor must be a positive integer")
|
56
|
+
if not isinstance(polynomial_degree, int) or polynomial_degree < 1:
|
57
|
+
raise InvalidParameterError("polynomial_degree must be a positive integer")
|
58
|
+
if not isinstance(top_k, int) or top_k < 1:
|
59
|
+
raise InvalidParameterError("top_k must be a positive integer")
|
60
|
+
if not 0 < lr < 1:
|
61
|
+
raise InvalidParameterError("Learning rate must be between 0 and 1")
|
62
|
+
if not isinstance(batch_size, int) or batch_size < 1:
|
63
|
+
raise InvalidParameterError("batch_size must be a positive integer")
|
64
|
+
if not isinstance(epochs, int) or epochs < 1:
|
65
|
+
raise InvalidParameterError("epochs must be a positive integer")
|
66
|
+
if not 0 <= alpha <= 1:
|
67
|
+
raise InvalidParameterError("alpha must be between 0 and 1")
|
68
|
+
if sigma <= 0:
|
69
|
+
raise InvalidParameterError("sigma must be positive")
|
70
|
+
|
47
71
|
self.hidden_sizes = hidden_sizes
|
48
72
|
self.activation = activation
|
49
73
|
self.augmentation_factor = augmentation_factor
|
@@ -55,6 +79,7 @@ class OIKAN(ABC):
|
|
55
79
|
self.batch_size = batch_size
|
56
80
|
self.verbose = verbose
|
57
81
|
self.evaluate_nn = evaluate_nn
|
82
|
+
self.top_k = top_k
|
58
83
|
self.neural_net = None
|
59
84
|
self.symbolic_model = None
|
60
85
|
self.evaluation_done = False
|
@@ -74,13 +99,13 @@ class OIKAN(ABC):
|
|
74
99
|
basis_functions = self.symbolic_model['basis_functions']
|
75
100
|
if 'coefficients' in self.symbolic_model:
|
76
101
|
coefficients = self.symbolic_model['coefficients']
|
77
|
-
formula = " + ".join([f"{coefficients[i]:.
|
102
|
+
formula = " + ".join([f"{coefficients[i]:.5f}*{basis_functions[i]}"
|
78
103
|
for i in range(len(coefficients)) if coefficients[i] != 0])
|
79
104
|
return formula if formula else "0"
|
80
105
|
else:
|
81
106
|
formulas = []
|
82
107
|
for c, coef in enumerate(self.symbolic_model['coefficients_list']):
|
83
|
-
formula = " + ".join([f"{coef[i]:.
|
108
|
+
formula = " + ".join([f"{coef[i]:.5f}*{basis_functions[i]}"
|
84
109
|
for i in range(len(coef)) if coef[i] != 0])
|
85
110
|
formulas.append(f"Class {self.classes_[c]}: {formula if formula else '0'}")
|
86
111
|
return formulas
|
@@ -129,27 +154,33 @@ class OIKAN(ABC):
|
|
129
154
|
File path to save the model. Should end with .json
|
130
155
|
"""
|
131
156
|
if self.symbolic_model is None:
|
132
|
-
raise
|
133
|
-
|
157
|
+
raise ModelNotFittedError("Model must be fitted before saving")
|
158
|
+
|
134
159
|
if not path.endswith('.json'):
|
135
160
|
path = path + '.json'
|
136
|
-
|
137
|
-
# Convert numpy arrays and other non-serializable types to lists
|
138
|
-
model_data = {
|
139
|
-
'n_features': self.symbolic_model['n_features'],
|
140
|
-
'degree': self.symbolic_model['degree'],
|
141
|
-
'basis_functions': self.symbolic_model['basis_functions']
|
142
|
-
}
|
143
161
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
162
|
+
try:
|
163
|
+
# Convert numpy arrays and other non-serializable types to lists
|
164
|
+
model_data = {
|
165
|
+
'n_features': self.symbolic_model['n_features'],
|
166
|
+
'degree': self.symbolic_model['degree'],
|
167
|
+
'basis_functions': self.symbolic_model['basis_functions']
|
168
|
+
}
|
169
|
+
|
170
|
+
if 'coefficients' in self.symbolic_model:
|
171
|
+
model_data['coefficients'] = self.symbolic_model['coefficients']
|
172
|
+
else:
|
173
|
+
model_data['coefficients_list'] = [coef for coef in self.symbolic_model['coefficients_list']]
|
174
|
+
if hasattr(self, 'classes_'):
|
175
|
+
model_data['classes'] = self.classes_.tolist()
|
176
|
+
|
177
|
+
with open(path, 'w') as f:
|
178
|
+
json.dump(model_data, f, indent=2)
|
179
|
+
except Exception as e:
|
180
|
+
raise ModelSerializationError(f"Failed to save model: {str(e)}")
|
150
181
|
|
151
|
-
|
152
|
-
|
182
|
+
if self.verbose:
|
183
|
+
print(f"Model saved to {path}")
|
153
184
|
|
154
185
|
def load(self, path):
|
155
186
|
"""
|
@@ -162,22 +193,28 @@ class OIKAN(ABC):
|
|
162
193
|
"""
|
163
194
|
if not path.endswith('.json'):
|
164
195
|
path = path + '.json'
|
196
|
+
|
197
|
+
try:
|
198
|
+
with open(path, 'r') as f:
|
199
|
+
model_data = json.load(f)
|
200
|
+
|
201
|
+
self.symbolic_model = {
|
202
|
+
'n_features': model_data['n_features'],
|
203
|
+
'degree': model_data['degree'],
|
204
|
+
'basis_functions': model_data['basis_functions']
|
205
|
+
}
|
165
206
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
207
|
+
if 'coefficients' in model_data:
|
208
|
+
self.symbolic_model['coefficients'] = model_data['coefficients']
|
209
|
+
else:
|
210
|
+
self.symbolic_model['coefficients_list'] = model_data['coefficients_list']
|
211
|
+
if 'classes' in model_data:
|
212
|
+
self.classes_ = np.array(model_data['classes'])
|
213
|
+
except Exception as e:
|
214
|
+
raise ModelSerializationError(f"Failed to load model: {str(e)}")
|
174
215
|
|
175
|
-
if
|
176
|
-
|
177
|
-
else:
|
178
|
-
self.symbolic_model['coefficients_list'] = model_data['coefficients_list']
|
179
|
-
if 'classes' in model_data:
|
180
|
-
self.classes_ = np.array(model_data['classes'])
|
216
|
+
if self.verbose:
|
217
|
+
print(f"Model loaded from {path}")
|
181
218
|
|
182
219
|
def _evaluate_neural_net(self, X, y, output_size, loss_fn):
|
183
220
|
"""Evaluates neural network performance on train-test split."""
|
@@ -253,7 +290,6 @@ class OIKAN(ABC):
|
|
253
290
|
|
254
291
|
def _generate_augmented_data(self, X):
|
255
292
|
"""Generates augmented data by adding Gaussian noise."""
|
256
|
-
n_samples = X.shape[0]
|
257
293
|
X_aug = []
|
258
294
|
for _ in range(self.augmentation_factor):
|
259
295
|
noise = np.random.normal(0, self.sigma, X.shape)
|
@@ -262,32 +298,102 @@ class OIKAN(ABC):
|
|
262
298
|
return np.vstack(X_aug)
|
263
299
|
|
264
300
|
def _perform_symbolic_regression(self, X, y):
|
265
|
-
"""
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
301
|
+
"""
|
302
|
+
Performs hierarchical symbolic regression using a two-stage approach.
|
303
|
+
|
304
|
+
Parameters:
|
305
|
+
-----------
|
306
|
+
X : array-like of shape (n_samples, n_features)
|
307
|
+
Input data.
|
308
|
+
y : array-like of shape (n_samples,) or (n_samples, n_classes)
|
309
|
+
Target values or logits.
|
310
|
+
"""
|
311
|
+
n_features = X.shape[1]
|
312
|
+
self.top_k = min(self.top_k, n_features)
|
313
|
+
|
314
|
+
if self.top_k < 1:
|
315
|
+
raise InvalidParameterError("top_k must be at least 1")
|
316
|
+
|
317
|
+
if np.any(np.isnan(X)) or np.any(np.isnan(y)):
|
318
|
+
raise NumericalInstabilityError("Input data contains NaN values")
|
319
|
+
|
320
|
+
if np.any(np.isinf(X)) or np.any(np.isinf(y)):
|
321
|
+
raise NumericalInstabilityError("Input data contains infinite values")
|
322
|
+
|
323
|
+
# Stage 1: Coarse Model
|
324
|
+
coarse_degree = 2 # Fixed low degree for coarse model
|
325
|
+
poly_coarse = PolynomialFeatures(degree=coarse_degree, include_bias=True)
|
326
|
+
X_poly_coarse = poly_coarse.fit_transform(X)
|
327
|
+
model_coarse = ElasticNet(alpha=self.alpha, fit_intercept=False)
|
328
|
+
model_coarse.fit(X_poly_coarse, y)
|
329
|
+
|
330
|
+
# Compute feature importances for original features
|
331
|
+
basis_functions_coarse = poly_coarse.get_feature_names_out()
|
270
332
|
if len(y.shape) == 1 or y.shape[1] == 1:
|
271
|
-
|
272
|
-
|
333
|
+
coef_coarse = model_coarse.coef_.flatten()
|
334
|
+
else:
|
335
|
+
coef_coarse = np.sum(np.abs(model_coarse.coef_), axis=0)
|
336
|
+
|
337
|
+
importances = np.zeros(X.shape[1])
|
338
|
+
for i, func in enumerate(basis_functions_coarse):
|
339
|
+
features_involved = get_features_involved(func)
|
340
|
+
for idx in features_involved:
|
341
|
+
importances[idx] += np.abs(coef_coarse[i])
|
342
|
+
|
343
|
+
if np.all(importances == 0):
|
344
|
+
raise FeatureExtractionError("Failed to compute feature importances - all values are zero")
|
345
|
+
|
346
|
+
# Select top K features
|
347
|
+
top_k_indices = np.argsort(importances)[::-1][:self.top_k]
|
348
|
+
|
349
|
+
# Stage 2: Refined Model
|
350
|
+
# ~ generate additional non-linear features for top K features
|
351
|
+
additional_features = []
|
352
|
+
additional_names = []
|
353
|
+
for i in top_k_indices:
|
354
|
+
# Higher-degree polynomial
|
355
|
+
additional_features.append(X[:, i]**3)
|
356
|
+
additional_names.append(f'x{i}^3')
|
357
|
+
# Non-linear transformations
|
358
|
+
additional_features.append(np.log1p(np.abs(X[:, i])))
|
359
|
+
additional_names.append(f'log1p_x{i}')
|
360
|
+
additional_features.append(np.exp(np.clip(X[:, i], -10, 10)))
|
361
|
+
additional_names.append(f'exp_x{i}')
|
362
|
+
additional_features.append(np.sin(X[:, i]))
|
363
|
+
additional_names.append(f'sin_x{i}')
|
364
|
+
|
365
|
+
# Combine features
|
366
|
+
X_additional = np.column_stack(additional_features)
|
367
|
+
X_refined = np.hstack([X_poly_coarse, X_additional])
|
368
|
+
basis_functions_refined = list(basis_functions_coarse) + additional_names
|
369
|
+
|
370
|
+
# Fit refined model
|
371
|
+
model_refined = ElasticNet(alpha=self.alpha, fit_intercept=False)
|
372
|
+
model_refined.fit(X_refined, y)
|
373
|
+
|
374
|
+
# Store symbolic model
|
375
|
+
if len(y.shape) == 1 or y.shape[1] == 1:
|
376
|
+
# Regression
|
377
|
+
coef_refined = model_refined.coef_.flatten()
|
378
|
+
selected_indices = np.where(np.abs(coef_refined) > 1e-6)[0]
|
273
379
|
self.symbolic_model = {
|
274
380
|
'n_features': X.shape[1],
|
275
|
-
'degree': self.polynomial_degree,
|
276
|
-
'basis_functions':
|
277
|
-
'coefficients':
|
381
|
+
'degree': self.polynomial_degree,
|
382
|
+
'basis_functions': [basis_functions_refined[i] for i in selected_indices],
|
383
|
+
'coefficients': coef_refined[selected_indices].tolist()
|
278
384
|
}
|
279
385
|
else:
|
386
|
+
# Classification
|
280
387
|
coefficients_list = []
|
281
|
-
# Note: Using the same basis functions across classes for simplicity
|
282
388
|
selected_indices = set()
|
283
389
|
for c in range(y.shape[1]):
|
284
|
-
coef =
|
390
|
+
coef = model_refined.coef_[c]
|
285
391
|
indices = np.where(np.abs(coef) > 1e-6)[0]
|
286
392
|
selected_indices.update(indices)
|
287
393
|
selected_indices = list(selected_indices)
|
288
|
-
basis_functions =
|
394
|
+
basis_functions = [basis_functions_refined[i] for i in selected_indices]
|
289
395
|
for c in range(y.shape[1]):
|
290
|
-
coef =
|
396
|
+
coef = model_refined.coef_[c]
|
291
397
|
coef_selected = coef[selected_indices].tolist()
|
292
398
|
coefficients_list.append(coef_selected)
|
293
399
|
self.symbolic_model = {
|
oikan/utils.py
CHANGED
@@ -9,7 +9,7 @@ def evaluate_basis_functions(X, basis_functions, n_features):
|
|
9
9
|
X : array-like of shape (n_samples, n_features)
|
10
10
|
Input data.
|
11
11
|
basis_functions : list
|
12
|
-
List of basis function strings (e.g., '1', 'x0', 'x0^2', 'x0 x1').
|
12
|
+
List of basis function strings (e.g., '1', 'x0', 'x0^2', 'x0 x1', 'log1p_x0').
|
13
13
|
n_features : int
|
14
14
|
Number of input features.
|
15
15
|
|
@@ -22,15 +22,26 @@ def evaluate_basis_functions(X, basis_functions, n_features):
|
|
22
22
|
for i, func in enumerate(basis_functions):
|
23
23
|
if func == '1':
|
24
24
|
X_transformed[:, i] = 1
|
25
|
+
elif func.startswith('log1p_x'):
|
26
|
+
idx = int(func.split('_')[1][1:])
|
27
|
+
X_transformed[:, i] = np.log1p(np.abs(X[:, idx]))
|
28
|
+
elif func.startswith('exp_x'):
|
29
|
+
idx = int(func.split('_')[1][1:])
|
30
|
+
X_transformed[:, i] = np.exp(np.clip(X[:, idx], -10, 10))
|
31
|
+
elif func.startswith('sin_x'):
|
32
|
+
idx = int(func.split('_')[1][1:])
|
33
|
+
X_transformed[:, i] = np.sin(X[:, idx])
|
25
34
|
elif '^' in func:
|
26
35
|
var, power = func.split('^')
|
27
36
|
idx = int(var[1:])
|
28
37
|
X_transformed[:, i] = X[:, idx] ** int(power)
|
29
38
|
elif ' ' in func:
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
39
|
+
vars = func.split(' ')
|
40
|
+
result = np.ones(X.shape[0])
|
41
|
+
for var in vars:
|
42
|
+
idx = int(var[1:])
|
43
|
+
result *= X[:, idx]
|
44
|
+
X_transformed[:, i] = result
|
34
45
|
else:
|
35
46
|
idx = int(func[1:])
|
36
47
|
X_transformed[:, i] = X[:, idx]
|
@@ -43,21 +54,29 @@ def get_features_involved(basis_function):
|
|
43
54
|
Parameters:
|
44
55
|
-----------
|
45
56
|
basis_function : str
|
46
|
-
String representation of the basis function, e.g., 'x0', 'x0^2', 'x0 x1'.
|
57
|
+
String representation of the basis function, e.g., 'x0', 'x0^2', 'x0 x1', 'log1p_x0'.
|
47
58
|
|
48
59
|
Returns:
|
49
60
|
--------
|
50
61
|
set : Set of feature indices involved.
|
51
62
|
"""
|
52
|
-
if basis_function == '1':
|
63
|
+
if basis_function == '1':
|
53
64
|
return set()
|
54
65
|
features = set()
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
else:
|
60
|
-
var = part # Take 'x0' as is
|
61
|
-
idx = int(var[1:]) # Extract index, e.g., 0
|
66
|
+
if '_' in basis_function: # Handle non-linear functions like 'log1p_x0'
|
67
|
+
parts = basis_function.split('_')
|
68
|
+
if len(parts) == 2 and parts[1].startswith('x'):
|
69
|
+
idx = int(parts[1][1:])
|
62
70
|
features.add(idx)
|
71
|
+
elif '^' in basis_function: # Handle powers, e.g., 'x0^2'
|
72
|
+
var = basis_function.split('^')[0]
|
73
|
+
idx = int(var[1:])
|
74
|
+
features.add(idx)
|
75
|
+
elif ' ' in basis_function: # Handle interactions, e.g., 'x0 x1'
|
76
|
+
for part in basis_function.split():
|
77
|
+
idx = int(part[1:])
|
78
|
+
features.add(idx)
|
79
|
+
elif basis_function.startswith('x'):
|
80
|
+
idx = int(basis_function[1:])
|
81
|
+
features.add(idx)
|
63
82
|
return features
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: oikan
|
3
|
-
Version: 0.0.3.
|
3
|
+
Version: 0.0.3.3
|
4
4
|
Summary: OIKAN: Neuro-Symbolic ML for Scientific Discovery
|
5
5
|
Author: Arman Zhalgasbayev
|
6
6
|
License: MIT
|
@@ -57,7 +57,7 @@ OIKAN implements a modern interpretation of the Kolmogorov-Arnold Representation
|
|
57
57
|
|
58
58
|
2. **Neural Implementation**: OIKAN uses a specialized architecture combining:
|
59
59
|
- Feature transformation layers with interpretable basis functions
|
60
|
-
- Symbolic regression for formula extraction
|
60
|
+
- Symbolic regression for formula extraction (ElasticNet-based)
|
61
61
|
- Automatic pruning of insignificant terms
|
62
62
|
|
63
63
|
```python
|
@@ -76,15 +76,19 @@ OIKAN implements a modern interpretation of the Kolmogorov-Arnold Representation
|
|
76
76
|
SYMBOLIC_FUNCTIONS = {
|
77
77
|
'linear': 'x', # Direct relationships
|
78
78
|
'quadratic': 'x^2', # Non-linear patterns
|
79
|
+
'cubic': 'x^3', # Higher-order relationships
|
79
80
|
'interaction': 'x_i x_j', # Feature interactions
|
80
|
-
'higher_order': 'x^n' # Polynomial terms
|
81
|
+
'higher_order': 'x^n', # Polynomial terms
|
82
|
+
'trigonometric': 'sin(x)', # Trigonometric functions
|
83
|
+
'exponential': 'exp(x)', # Exponential growth
|
84
|
+
'logarithmic': 'log(x)' # Logarithmic relationships
|
81
85
|
}
|
82
86
|
```
|
83
87
|
|
84
88
|
4. **Formula Extraction Process**:
|
85
89
|
- Train neural network on raw data
|
86
90
|
- Generate augmented samples for better coverage
|
87
|
-
- Perform L1-regularized symbolic regression
|
91
|
+
- Perform L1-regularized symbolic regression (alpha)
|
88
92
|
- Prune terms with coefficients below threshold
|
89
93
|
- Export human-readable mathematical expressions
|
90
94
|
|
@@ -115,12 +119,14 @@ model = OIKANRegressor(
|
|
115
119
|
activation='relu', # Activation function (other options: 'tanh', 'leaky_relu', 'elu', 'swish', 'gelu')
|
116
120
|
augmentation_factor=5, # Augmentation factor for data generation
|
117
121
|
polynomial_degree=2, # Degree of polynomial basis functions
|
118
|
-
alpha=0.1, # L1 regularization strength
|
122
|
+
alpha=0.1, # L1 regularization strength (Symbolic regression)
|
119
123
|
sigma=0.1, # Standard deviation of Gaussian noise for data augmentation
|
124
|
+
top_k=5, # Number of top features to select (Symbolic regression)
|
120
125
|
epochs=100, # Number of training epochs
|
121
126
|
lr=0.001, # Learning rate
|
122
127
|
batch_size=32, # Batch size for training
|
123
|
-
verbose=True # Verbose output during training
|
128
|
+
verbose=True, # Verbose output during training
|
129
|
+
evaluate_nn=True # Validate neural network performance before full process
|
124
130
|
)
|
125
131
|
|
126
132
|
# Fit the model
|
@@ -163,12 +169,14 @@ model = OIKANClassifier(
|
|
163
169
|
activation='relu', # Activation function (other options: 'tanh', 'leaky_relu', 'elu', 'swish', 'gelu')
|
164
170
|
augmentation_factor=10, # Augmentation factor for data generation
|
165
171
|
polynomial_degree=2, # Degree of polynomial basis functions
|
166
|
-
alpha=0.1, # L1 regularization strength
|
172
|
+
alpha=0.1, # L1 regularization strength (Symbolic regression)
|
167
173
|
sigma=0.1, # Standard deviation of Gaussian noise for data augmentation
|
174
|
+
top_k=5, # Number of top features to select (Symbolic regression)
|
168
175
|
epochs=100, # # Number of training epochs
|
169
176
|
lr=0.001, # Learning rate
|
170
177
|
batch_size=32, # Batch size for training
|
171
|
-
verbose=True # Verbose output during training
|
178
|
+
verbose=True, # Verbose output during training
|
179
|
+
evaluate_nn=True # Validate neural network performance before full process
|
172
180
|
)
|
173
181
|
|
174
182
|
# Fit the model
|
@@ -0,0 +1,10 @@
|
|
1
|
+
oikan/__init__.py,sha256=zEzhm1GYLT4vNaIQ4CgZcNpUk3uo8SWnoaHYtHW_XSQ,628
|
2
|
+
oikan/exceptions.py,sha256=GhHWqy2Q5LVBcteTy4ngnqxr7FOoLNyD8dNt1kfRXyw,901
|
3
|
+
oikan/model.py,sha256=wvF_g1RcpYcQin_wOUiWEUeKJcQ8HyPtEm_5YrCeXFs,21946
|
4
|
+
oikan/neural.py,sha256=wxmGgzmtpwJ3lvH6u6D4i4BiAzg018czrIdw49phSCY,1558
|
5
|
+
oikan/utils.py,sha256=_FNhB_sIQfY-KsKRqvuKKVXNVZaAdpI5w8zPY_j_xJU,2898
|
6
|
+
oikan-0.0.3.3.dist-info/licenses/LICENSE,sha256=75ASVmU-XIpN-M4LbVmJ_ibgbzbvRLVti8FhnR0BTf8,1096
|
7
|
+
oikan-0.0.3.3.dist-info/METADATA,sha256=moaO5H0kXU-Gf_sV7tpt4VUgmTEys6dINlzr0yfDSUc,9055
|
8
|
+
oikan-0.0.3.3.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
9
|
+
oikan-0.0.3.3.dist-info/top_level.txt,sha256=XwnwKwTJddZwIvtrUsAz-l-58BJRj6HjAGWrfYi_3QY,6
|
10
|
+
oikan-0.0.3.3.dist-info/RECORD,,
|
oikan-0.0.3.2.dist-info/RECORD
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
oikan/__init__.py,sha256=zEzhm1GYLT4vNaIQ4CgZcNpUk3uo8SWnoaHYtHW_XSQ,628
|
2
|
-
oikan/exceptions.py,sha256=Is0jG4apxO8QJQREIiJQYMjANYWibWeS-103q9KWbfg,192
|
3
|
-
oikan/model.py,sha256=oZtx5uFxMj4q89ODKDBeTJ0whbqiMIR2tKwgmYVXHUY,16887
|
4
|
-
oikan/neural.py,sha256=wxmGgzmtpwJ3lvH6u6D4i4BiAzg018czrIdw49phSCY,1558
|
5
|
-
oikan/utils.py,sha256=xMGRa1qhn8BWn9UxpVeJIuGb-UvQmbjiFSsvAdF0bMU,2095
|
6
|
-
oikan-0.0.3.2.dist-info/licenses/LICENSE,sha256=75ASVmU-XIpN-M4LbVmJ_ibgbzbvRLVti8FhnR0BTf8,1096
|
7
|
-
oikan-0.0.3.2.dist-info/METADATA,sha256=PPsMSll3Ds6E9J3ZnXxo8Yno0ZsHrSb55kZ-035jJZE,8441
|
8
|
-
oikan-0.0.3.2.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
9
|
-
oikan-0.0.3.2.dist-info/top_level.txt,sha256=XwnwKwTJddZwIvtrUsAz-l-58BJRj6HjAGWrfYi_3QY,6
|
10
|
-
oikan-0.0.3.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|