oikan 0.0.3.7__py3-none-any.whl → 0.0.3.8__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/model.py +30 -13
- {oikan-0.0.3.7.dist-info → oikan-0.0.3.8.dist-info}/METADATA +1 -1
- oikan-0.0.3.8.dist-info/RECORD +10 -0
- oikan-0.0.3.7.dist-info/RECORD +0 -10
- {oikan-0.0.3.7.dist-info → oikan-0.0.3.8.dist-info}/WHEEL +0 -0
- {oikan-0.0.3.7.dist-info → oikan-0.0.3.8.dist-info}/licenses/LICENSE +0 -0
- {oikan-0.0.3.7.dist-info → oikan-0.0.3.8.dist-info}/top_level.txt +0 -0
oikan/model.py
CHANGED
@@ -12,6 +12,7 @@ from sklearn.model_selection import train_test_split
|
|
12
12
|
from sklearn.metrics import r2_score, accuracy_score
|
13
13
|
from .exceptions import *
|
14
14
|
import sys
|
15
|
+
from tqdm import tqdm
|
15
16
|
|
16
17
|
class OIKAN(ABC):
|
17
18
|
"""
|
@@ -353,14 +354,23 @@ class OIKAN(ABC):
|
|
353
354
|
if np.any(np.isinf(X)) or np.any(np.isinf(y)):
|
354
355
|
raise NumericalInstabilityError("Input data contains infinite values")
|
355
356
|
|
356
|
-
|
357
|
+
if self.verbose:
|
358
|
+
print("\nStage 1: Coarse Model Fitting")
|
359
|
+
|
357
360
|
coarse_degree = 2 # Fixed low degree for coarse model
|
358
361
|
poly_coarse = PolynomialFeatures(degree=coarse_degree, include_bias=True)
|
362
|
+
|
363
|
+
if self.verbose:
|
364
|
+
print("Generating polynomial features...")
|
359
365
|
X_poly_coarse = poly_coarse.fit_transform(X)
|
366
|
+
|
367
|
+
if self.verbose:
|
368
|
+
print("Fitting coarse elastic net model...")
|
360
369
|
model_coarse = ElasticNet(alpha=self.alpha, fit_intercept=False)
|
361
370
|
model_coarse.fit(X_poly_coarse, y)
|
362
371
|
|
363
|
-
|
372
|
+
if self.verbose:
|
373
|
+
print("Computing feature importances...")
|
364
374
|
basis_functions_coarse = poly_coarse.get_feature_names_out()
|
365
375
|
if len(y.shape) == 1 or y.shape[1] == 1:
|
366
376
|
coef_coarse = model_coarse.coef_.flatten()
|
@@ -368,7 +378,7 @@ class OIKAN(ABC):
|
|
368
378
|
coef_coarse = np.sum(np.abs(model_coarse.coef_), axis=0)
|
369
379
|
|
370
380
|
importances = np.zeros(X.shape[1])
|
371
|
-
for i, func in enumerate(basis_functions_coarse):
|
381
|
+
for i, func in enumerate(tqdm(basis_functions_coarse, disable=not self.verbose, desc="Analyzing features")):
|
372
382
|
features_involved = get_features_involved(func)
|
373
383
|
for idx in features_involved:
|
374
384
|
importances[idx] += np.abs(coef_coarse[i])
|
@@ -379,11 +389,13 @@ class OIKAN(ABC):
|
|
379
389
|
# Select top K features
|
380
390
|
top_k_indices = np.argsort(importances)[::-1][:self.top_k]
|
381
391
|
|
382
|
-
|
383
|
-
|
392
|
+
if self.verbose:
|
393
|
+
print(f"\nStage 2: Refined Model with top {self.top_k} features")
|
394
|
+
print("Generating additional non-linear features...")
|
395
|
+
|
384
396
|
additional_features = []
|
385
397
|
additional_names = []
|
386
|
-
for i in top_k_indices:
|
398
|
+
for i in tqdm(top_k_indices, disable=not self.verbose, desc="Generating features"):
|
387
399
|
# Higher-degree polynomial
|
388
400
|
additional_features.append(X[:, i]**3)
|
389
401
|
additional_names.append(f'x{i}^3')
|
@@ -395,15 +407,18 @@ class OIKAN(ABC):
|
|
395
407
|
additional_features.append(np.sin(X[:, i]))
|
396
408
|
additional_names.append(f'sin_x{i}')
|
397
409
|
|
398
|
-
|
410
|
+
if self.verbose:
|
411
|
+
print("Combining features and fitting final model...")
|
399
412
|
X_additional = np.column_stack(additional_features)
|
400
413
|
X_refined = np.hstack([X_poly_coarse, X_additional])
|
401
414
|
basis_functions_refined = list(basis_functions_coarse) + additional_names
|
402
415
|
|
403
|
-
# Fit refined model
|
404
416
|
model_refined = ElasticNet(alpha=self.alpha, fit_intercept=False)
|
405
417
|
model_refined.fit(X_refined, y)
|
406
418
|
|
419
|
+
if self.verbose:
|
420
|
+
print("Building final symbolic model...")
|
421
|
+
|
407
422
|
# Store symbolic model
|
408
423
|
if len(y.shape) == 1 or y.shape[1] == 1:
|
409
424
|
# Regression
|
@@ -418,7 +433,7 @@ class OIKAN(ABC):
|
|
418
433
|
# Classification
|
419
434
|
coefficients_list = []
|
420
435
|
selected_indices = set()
|
421
|
-
for c in range(y.shape[1]):
|
436
|
+
for c in tqdm(range(y.shape[1]), disable=not self.verbose, desc="Processing classes"):
|
422
437
|
coef = model_refined.coef_[c]
|
423
438
|
indices = np.where(np.abs(coef) > 1e-6)[0]
|
424
439
|
selected_indices.update(indices)
|
@@ -454,7 +469,7 @@ class OIKANRegressor(OIKAN):
|
|
454
469
|
self._train_neural_net(X, y, output_size=1, loss_fn=nn.MSELoss())
|
455
470
|
|
456
471
|
if self.verbose:
|
457
|
-
print(f"Original data: features shape: {X.shape} | target shape: {y.shape}")
|
472
|
+
print(f"Original data: features shape: {X.shape} | target shape: {y.shape} | size: {X.nbytes / (1024 * 1024):.2f} MB")
|
458
473
|
|
459
474
|
X_aug = self._generate_augmented_data(X)
|
460
475
|
|
@@ -463,13 +478,14 @@ class OIKANRegressor(OIKAN):
|
|
463
478
|
y_aug = self.neural_net(torch.tensor(X_aug, dtype=torch.float32)).detach().numpy()
|
464
479
|
|
465
480
|
if self.verbose:
|
466
|
-
print(f"Augmented data: features shape: {X_aug.shape} | target shape: {y_aug.shape}")
|
481
|
+
print(f"Augmented data: features shape: {X_aug.shape} | target shape: {y_aug.shape} | size: {X_aug.nbytes / (1024 * 1024):.2f} MB")
|
467
482
|
|
468
483
|
X_combined = np.vstack([X, X_aug])
|
469
484
|
y_combined = np.vstack([y, y_aug])
|
470
485
|
else:
|
471
486
|
if self.verbose:
|
472
487
|
print("Skipping neural network training (augmentation_factor=1)")
|
488
|
+
print(f"Data: features shape: {X.shape} | target shape: {y.shape} | size: {X.nbytes / (1024 * 1024):.2f} MB")
|
473
489
|
X_combined = X
|
474
490
|
y_combined = y
|
475
491
|
|
@@ -523,7 +539,7 @@ class OIKANClassifier(OIKAN):
|
|
523
539
|
self._train_neural_net(X, y_onehot, output_size=n_classes, loss_fn=nn.CrossEntropyLoss())
|
524
540
|
|
525
541
|
if self.verbose:
|
526
|
-
print(f"Original data: features shape: {X.shape} | target shape: {y.shape}")
|
542
|
+
print(f"Original data: features shape: {X.shape} | target shape: {y.shape} | size: {X.nbytes / (1024 * 1024):.2f} MB")
|
527
543
|
|
528
544
|
X_aug = self._generate_augmented_data(X)
|
529
545
|
|
@@ -532,13 +548,14 @@ class OIKANClassifier(OIKAN):
|
|
532
548
|
logits_aug = self.neural_net(torch.tensor(X_aug, dtype=torch.float32)).detach().numpy()
|
533
549
|
|
534
550
|
if self.verbose:
|
535
|
-
print(f"Augmented data: features shape: {X_aug.shape} | target shape: {logits_aug.shape}")
|
551
|
+
print(f"Augmented data: features shape: {X_aug.shape} | target shape: {logits_aug.shape} | size: {X_aug.nbytes / (1024 * 1024):.2f} MB")
|
536
552
|
|
537
553
|
X_combined = np.vstack([X, X_aug])
|
538
554
|
y_combined = np.vstack([y_onehot.numpy(), logits_aug])
|
539
555
|
else:
|
540
556
|
if self.verbose:
|
541
557
|
print("Skipping neural network training (augmentation_factor=1)")
|
558
|
+
print(f"Data: features shape: {X.shape} | target shape: {y.shape} | size: {X.nbytes / (1024 * 1024):.2f} MB")
|
542
559
|
X_combined = X
|
543
560
|
y_combined = y_onehot.numpy()
|
544
561
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
oikan/__init__.py,sha256=zEzhm1GYLT4vNaIQ4CgZcNpUk3uo8SWnoaHYtHW_XSQ,628
|
2
|
+
oikan/exceptions.py,sha256=GhHWqy2Q5LVBcteTy4ngnqxr7FOoLNyD8dNt1kfRXyw,901
|
3
|
+
oikan/model.py,sha256=K-cBAUvfw3B8wxWjNSUC1CadU1iVUb8erapUpD9KzKw,25822
|
4
|
+
oikan/neural.py,sha256=PZjaffSuABuCNxu-7PinU1GR6ji0Y6xRgSQ3n5HRDxI,1572
|
5
|
+
oikan/utils.py,sha256=7UCm9obO-8Q2zhetdAkukMDOZvGSBWUL_dSF04XqM7k,8808
|
6
|
+
oikan-0.0.3.8.dist-info/licenses/LICENSE,sha256=75ASVmU-XIpN-M4LbVmJ_ibgbzbvRLVti8FhnR0BTf8,1096
|
7
|
+
oikan-0.0.3.8.dist-info/METADATA,sha256=jmDvzPj-d_JH4yAZiBf45-mjItUVRepX1Xv2cMqqAkA,12749
|
8
|
+
oikan-0.0.3.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
9
|
+
oikan-0.0.3.8.dist-info/top_level.txt,sha256=XwnwKwTJddZwIvtrUsAz-l-58BJRj6HjAGWrfYi_3QY,6
|
10
|
+
oikan-0.0.3.8.dist-info/RECORD,,
|
oikan-0.0.3.7.dist-info/RECORD
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
oikan/__init__.py,sha256=zEzhm1GYLT4vNaIQ4CgZcNpUk3uo8SWnoaHYtHW_XSQ,628
|
2
|
-
oikan/exceptions.py,sha256=GhHWqy2Q5LVBcteTy4ngnqxr7FOoLNyD8dNt1kfRXyw,901
|
3
|
-
oikan/model.py,sha256=TC2-R00GOjFb7ePzKTqeYkOiVlqUK7KP0mXsnJhg9ik,24736
|
4
|
-
oikan/neural.py,sha256=PZjaffSuABuCNxu-7PinU1GR6ji0Y6xRgSQ3n5HRDxI,1572
|
5
|
-
oikan/utils.py,sha256=7UCm9obO-8Q2zhetdAkukMDOZvGSBWUL_dSF04XqM7k,8808
|
6
|
-
oikan-0.0.3.7.dist-info/licenses/LICENSE,sha256=75ASVmU-XIpN-M4LbVmJ_ibgbzbvRLVti8FhnR0BTf8,1096
|
7
|
-
oikan-0.0.3.7.dist-info/METADATA,sha256=nrel6O7TXdbtJHSNCzvqPq_IELeQWx0azfrU4Jq6sps,12749
|
8
|
-
oikan-0.0.3.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
9
|
-
oikan-0.0.3.7.dist-info/top_level.txt,sha256=XwnwKwTJddZwIvtrUsAz-l-58BJRj6HjAGWrfYi_3QY,6
|
10
|
-
oikan-0.0.3.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|