src.tests.transf_octorf_test

Classes

TransfOctoRFTest()

class src.tests.transf_octorf_test.TransfOctoRFTest
Author:

Alberto M. Esmoris Pena

Test that the TransfOctoRF three-stage pipeline (RF + NN) learns linearly separable classification problems. The test generates synthetic data where each class occupies a well-separated region in feature space, trains the full pipeline (C++ Random Forest followed by Transformer or SharedMLP neural network), and verifies that the final predictions achieve near-perfect accuracy and F1.

Twenty-eight configurations are tested:

Config

Classes

NN variant

Feature setup

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AC

2 4 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4

SharedMLP SharedMLP Transformer Transformer Transformer Transformer Transformer Transformer Transformer Transformer SharedMLP Transformer GVA GVA (alias) Transformer SharedMLP Transformer Transformer Transformer Transformer GVA Transformer Transformer Transformer GVA GVA GVA GVA

raw synthetic, depth=1 raw synthetic, depth=1 raw synthetic, depth=1 raw synthetic, depth=1 mined geom, same for both mined geom, NN subset mined geom + RF proba/amb proba + ambiguity, depth=3 proba + amb + mined, d=3 class_names + serializ. LR scheduler (dict) store_features validation raw synthetic, depth=1 operator name alias point-wise labels point-wise labels class weights (standard) class weights + point-wise full augmentation combo depth=2 + per-depth n_h depth=2 + per-depth n_h point-wise + predictive FPS point-wise + predictive MD CW focal loss + point-wise gva_mix=’mlp’ (interv. A) output_mix=’mlp’ (interv.B) both mixers enabled both mixers, depth=2

RF and NN receive different data splits to verify that both stages learn independently on their respective inputs.

Pass criteria (per configuration):

  • Training loss \(< 0.05\)

  • Overall accuracy (OA) \(> 0.95\)

  • Macro F1 \(> 0.95\)

  • Per-class F1 \(> 0.95\) for every class

Variables:
  • loss_thr (float) – Maximum acceptable training loss.

  • metric_thr (float) – Minimum acceptable OA and F1.

__init__()

Initialize the TransfOctoRF separable-problem test.

run()

Run all nine configurations.

Returns:

True if every configuration passes, False otherwise.

Return type:

bool

check_config(name, n_classes, operator, n_rf=300, n_nn=200, n_f=6, K=8, separation=8.0, seed=42, nn_fnames=None, hidden_depth=1, gradient_centralization=False, learning_rate=0.005, nn_point_wise_labels=False, class_weight=None, augmentation_config=None, n_h=32, predictive_input_strategy=None, loss_function=None, focusing_parameter=2, gva_mix_strategy='add', output_mix_strategy='none')

Run one test configuration with raw synthetic features.

Parameters:
  • name (str) – Configuration label.

  • n_classes (int) – Number of classes.

  • operator (str) – Operator type (‘transformer’, ‘sharedmlp’, ‘gva’).

  • n_rf (int) – Samples per class for the RF dataset.

  • n_nn (int) – Samples per class for the NN dataset.

  • n_f (int) – Number of features.

  • K (int) – Number of KNN neighbors.

  • separation (float) – Distance between class centers.

  • seed (int) – Random seed.

  • nn_fnames (list or None) – NN feature names (None = all).

  • hidden_depth (int) – Number of stacked NN blocks.

Returns:

True if all thresholds are met.

Return type:

bool

check_mined_config(name, n_classes, operator, nn_fnames=None, n_pts_rf=3000, n_pts_nn=2500, K=8, separation=8.0, seed=42, hidden_depth=1, gradient_centralization=True)

Run one test configuration with C++ mined features.

Generates raw 3D point clouds (coordinates + labels) and passes them directly to the model. The model builds octree centroids and mines features internally via mining_config.

Parameters:
  • name (str) – Configuration label.

  • n_classes (int) – Number of classes.

  • operator (str) – Operator type (‘transformer’, ‘sharedmlp’, ‘gva’).

  • nn_fnames (list or None) – NN feature names (None = all).

  • n_pts_rf (int) – Points per class for the RF cloud.

  • n_pts_nn (int) – Points per class for the NN cloud.

  • K (int) – Number of KNN neighbors.

  • separation (float) – Distance between class centers.

  • seed (int) – Random seed.

Returns:

True if all thresholds are met.

Return type:

bool

train_and_evaluate(name, X_rf, y_rf, X_nn, y_nn, fnames, nn_fnames, operator, K, epochs=50, n_h=32, hidden_depth=1, gradient_centralization=False, learning_rate=0.005, nn_point_wise_labels=False, class_weight=None, augmentation_config=None, predictive_input_strategy=None, loss_function=None, focusing_parameter=2, gva_mix_strategy='add', output_mix_strategy='none')

Build model, train RF + NN, predict, and validate.

Parameters:
  • name (str) – Configuration label.

  • X_rf (np.ndarray) – RF training features (S_rf, n_f).

  • y_rf (np.ndarray) – RF training labels (S_rf,).

  • X_nn (np.ndarray) – NN training features (S_nn, n_f).

  • y_nn (np.ndarray) – NN training labels (S_nn,).

  • fnames (list) – All feature names.

  • nn_fnames (list or None) – NN feature names (None = all).

  • operator (str) – Operator type (‘transformer’, ‘sharedmlp’, ‘gva’).

  • K (int) – Number of KNN neighbors.

  • epochs (int) – Training epochs for the NN.

  • n_h (int) – Hidden dimensionality for the NN.

  • hidden_depth (int) – Number of stacked NN blocks.

Returns:

True if all thresholds are met.

Return type:

bool

check_class_names_and_serialization(name, n_classes, operator, n_rf=300, n_nn=200, n_f=6, K=8, separation=8.0, seed=42)

Test that class_names sets num_classes_ and that the model survives a pickle round-trip (getstate/setstate).

Parameters:

name – Configuration label.

Returns:

True if all checks pass.

Return type:

bool

check_store_features(name, n_classes, operator, n_rf=300, n_nn=200, n_f=6, K=8, separation=8.0, seed=42)

Test that store_features and store_raw_features produce features with the expected statistical properties.

  • store_raw_features=True: features have natural scale.

  • store_raw_features=False: features are standardized (mean ≈ 0, std ≈ 1).

Parameters:

name – Configuration label.

Returns:

True if all checks pass.

Return type:

bool

static make_separable_features(n_per_class, n_classes, n_f, separation, seed)

Generate a linearly separable feature matrix.

Each class has its centroid offset by c * separation along feature axis 0. Small Gaussian noise is added to all features. The first 3 features also serve as spatial coordinates (x, y, z).

Parameters:
  • n_per_class (int) – Samples per class.

  • n_classes (int) – Number of classes.

  • n_f (int) – Number of features.

  • separation (float) – Distance between class centers.

  • seed (int) – Random seed for reproducibility.

Returns:

(X, y) feature matrix and labels.

Return type:

tuple[np.ndarray, np.ndarray]

static make_separable_pcloud(n_per_class, n_classes, separation, seed)

Generate a 3D point cloud whose classes have distinct local geometry so geometric descriptors (linearity, planarity, sphericity, …) can separate them.

  • Class 0: planar — thin disc in the xy-plane.

  • Class 1: linear — elongated along the x-axis.

  • Class 2: spherical — isotropic Gaussian blob.

  • Class 3: mixed — moderate spread in all axes with asymmetric scaling.

Each class is offset by c * separation along x so that height features also contribute to separability.

Parameters:
  • n_per_class (int) – Points per class.

  • n_classes (int) – Number of classes.

  • separation (float) – Distance between class centers.

  • seed (int) – Random seed.

Returns:

(X_coords, y_labels) with shapes (N, 3), (N,).

Return type:

tuple[np.ndarray, np.ndarray]