Compare models in a hybrid setup: Motion feedback- Force actuation¶
- numerical model: simulate the floater dynamics.
- physical turbine: measure forces and accelerations
- Ml model: multi-output regressor
In [1]:
Copied!
from fowt_ml.pipeline import Pipeline
from fowt_ml.pipeline import Pipeline
In [2]:
Copied!
example_config_file = "../../src/example_config.yml"
example_config_file = "../../src/example_config.yml"
In [3]:
Copied!
my_pipeline = Pipeline(example_config_file)
my_pipeline = Pipeline(example_config_file)
In [4]:
Copied!
# set correct path for mat file: add the correct path
my_pipeline.data_config["exp699"]["path_file"] = "/home/sarah/temp/hybridlabs/data_example/exp699.mat"
# set correct path for mat file: add the correct path
my_pipeline.data_config["exp699"]["path_file"] = "/home/sarah/temp/hybridlabs/data_example/exp699.mat"
In [5]:
Copied!
# check the targets and predictors that are provided in the comfig
print("targets are:", my_pipeline.target_labels)
# check the targets and predictors that are provided in the comfig
print("targets are:", my_pipeline.target_labels)
targets are: ['force_tt_meas6[0]', 'force_tt_meas6[1]', 'force_tt_meas6[2]', 'force_tt_meas6[3]', 'force_tt_meas6[4]', 'force_tt_meas6[5]']
In [6]:
Copied!
print("features are:", my_pipeline.predictors_labels)
print("features are:", my_pipeline.predictors_labels)
features are: ['pos_act6[0]', 'pos_act6[1]', 'pos_act6[2]', 'pos_act6[3]', 'pos_act6[4]', 'pos_act6[5]', 'spd_rot_act', 'wind_speed']
In [7]:
Copied!
# check the models and metrics that are provided by the config
print(my_pipeline.model_names)
# check the models and metrics that are provided by the config
print(my_pipeline.model_names)
{'ElasticNetRegression': {}, 'LeastAngleRegression': {}, 'LassoRegression': {}, 'LinearRegression': {}, 'SklearnGPRegressor': {'num_inducing': 100, 'num_latents': 3, 'num_epochs': 10}, 'RandomForest': {'n_estimators': 50, 'max_depth': 5, 'bootstrap': True, 'max_samples': 10000}, 'MultilayerPerceptron': {'hidden_layer_sizes': 10, 'max_iter': 50}, 'XGBoostRegression': {'n_estimators': 10, 'max_depth': 10, 'tree_method': 'hist'}, 'RNNRegressor': {'input_size': 14, 'hidden_size': 64, 'num_layers': 2, 'output_size': 6, 'max_epochs': 5}, 'LSTMRegressor': {'input_size': 14, 'hidden_size': 64, 'num_layers': 2, 'output_size': 6, 'max_epochs': 5}, 'GRURegressor': {'input_size': 14, 'hidden_size': 64, 'num_layers': 2, 'output_size': 6, 'max_epochs': 5}}
In [8]:
Copied!
print(my_pipeline.metric_names)
print(my_pipeline.metric_names)
['neg_mean_absolute_error', 'neg_root_mean_squared_error', 'r2', 'model_fit_time', 'model_predict_time']
In [9]:
Copied!
# setup the pipeline
my_pipeline.setup(data="exp699")
# setup the pipeline
my_pipeline.setup(data="exp699")
In [10]:
Copied!
# compare models on test data
models, scores = my_pipeline.compare_models(sort="model_fit_time")
# compare models on test data
models, scores = my_pipeline.compare_models(sort="model_fit_time")
2025/11/07 16:36:10 WARNING mlflow.utils.requirements_utils: The following packages were not found in the public PyPI package index as of 2025-04-15; if these packages are not present in the public PyPI index, you must install them manually before loading your model: {'fowt-ml'}
2025/11/07 16:36:23 WARNING mlflow.utils.requirements_utils: The following packages were not found in the public PyPI package index as of 2025-04-15; if these packages are not present in the public PyPI index, you must install them manually before loading your model: {'fowt-ml'}
2025/11/07 16:36:28 WARNING mlflow.utils.requirements_utils: The following packages were not found in the public PyPI package index as of 2025-04-15; if these packages are not present in the public PyPI index, you must install them manually before loading your model: {'fowt-ml'}
2025/11/07 16:36:32 WARNING mlflow.utils.requirements_utils: The following packages were not found in the public PyPI package index as of 2025-04-15; if these packages are not present in the public PyPI index, you must install them manually before loading your model: {'fowt-ml'}
INFO:fowt_ml.pipeline:Saving grid scores to grid_scores.csv
INFO:fowt_ml.pipeline:Saving best model to joblib format in best_model.joblib
In [11]:
Copied!
scores
scores
Out[11]:
| neg_mean_absolute_error | neg_root_mean_squared_error | r2 | model_fit_time | model_predict_time | |
|---|---|---|---|---|---|
| LassoRegression | -1.634784 | -2.166301 | -0.000028 | 0.180 | 0.000 |
| LinearRegression | -1.603058 | -2.130906 | 0.107320 | 0.197 | 0.000 |
| ElasticNetRegression | -1.633379 | -2.164612 | 0.010868 | 0.213 | 0.002 |
| LeastAngleRegression | -1.603058 | -2.130906 | 0.107320 | 0.214 | 0.000 |
| XGBoostRegression | -1.581626 | -2.086574 | 0.153210 | 3.239 | 0.001 |
| RandomForest | -1.600439 | -2.122963 | 0.106379 | 4.171 | 0.002 |
| MultilayerPerceptron | -1.597414 | -2.118111 | 0.120811 | 7.175 | 0.001 |
| LSTMRegressor | -1.625406 | -2.155499 | 0.033197 | 44.764 | 0.001 |
| SklearnGPRegressor | -1.597856 | -2.121320 | 0.124109 | 70.427 | 0.003 |
| RNNRegressor | -1.601624 | -2.128001 | 0.110522 | 171.203 | 0.001 |
| GRURegressor | -1.606470 | -2.133881 | 0.090896 | 473.594 | 0.001 |
In [12]:
Copied!
models
models
Out[12]:
{'ElasticNetRegression': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model', ElasticNet())]),
transformer=StandardScaler()),
'LeastAngleRegression': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model', Lars())]),
transformer=StandardScaler()),
'LassoRegression': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model', Lasso())]),
transformer=StandardScaler()),
'LinearRegression': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model',
LinearRegression())]),
transformer=StandardScaler()),
'SklearnGPRegressor': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model',
SklearnGPRegressor(num_inducing=100,
num_latents=3))]),
transformer=StandardScaler()),
'RandomForest': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model',
RandomForestRegressor(max_depth=5,
max_samples=10000,
n_estimators=50))]),
transformer=StandardScaler()),
'MultilayerPerceptron': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model',
MLPRegressor(hidden_layer_sizes=10,
max_iter=50))]),
transformer=StandardScaler()),
'XGBoostRegression': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model',
XGBRegressor(base_score=None,
booster=None,
callbacks=None,
colsample_bylevel=None,
colsample_bynode=None,
colsample_bytree=None,
device=None,
early_stopping_rounds=None,
enable_categorical=False,
eval_metric=None,
feature_types=None,
feature_weights=None,
gamma=None,
grow...None,
importance_type=None,
interaction_constraints=None,
learning_rate=None,
max_bin=None,
max_cat_threshold=None,
max_cat_to_onehot=None,
max_delta_step=None,
max_depth=10,
max_leaves=None,
min_child_weight=None,
missing=nan,
monotone_constraints=None,
multi_strategy=None,
n_estimators=10,
n_jobs=None,
num_parallel_tree=None, ...))]),
transformer=StandardScaler()),
'RNNRegressor': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model',
NeuralNetRegressor(_params_to_validate={'module__num_layers', 'module__hidden_size', 'module__rnn_model', 'module__input_size', 'module__output_size'}, batch_size=128, callbacks=None, compile=False, dataset=<class 'skorch.dataset.Dataset'>, device='cpu', iterator_train=<...4, module__input_size=14, module__num_layers=2, module__output_size=6, module__rnn_model=<class 'torch.nn.modules.rnn.RNN'>, optimizer=<class 'torch.optim.sgd.SGD'>, predict_nonlinearity='auto', torch_load_kwargs=None, train_split=<skorch.dataset.ValidSplit object at 0x7607b1ebc7d0>, use_caching='auto', verbose=0, warm_start=False))]),
transformer=StandardScaler()),
'LSTMRegressor': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model',
NeuralNetRegressor(_params_to_validate={'module__num_layers', 'module__hidden_size', 'module__rnn_model', 'module__input_size', 'module__output_size'}, batch_size=128, callbacks=None, compile=False, dataset=<class 'skorch.dataset.Dataset'>, device='cpu', iterator_train=<..., module__input_size=14, module__num_layers=2, module__output_size=6, module__rnn_model=<class 'torch.nn.modules.rnn.LSTM'>, optimizer=<class 'torch.optim.sgd.SGD'>, predict_nonlinearity='auto', torch_load_kwargs=None, train_split=<skorch.dataset.ValidSplit object at 0x7607b1ebc7d0>, use_caching='auto', verbose=0, warm_start=False))]),
transformer=StandardScaler()),
'GRURegressor': TransformedTargetRegressor(regressor=Pipeline(steps=[('scaler',
StandardScaler()),
('model',
NeuralNetRegressor(_params_to_validate={'module__num_layers', 'module__hidden_size', 'module__rnn_model', 'module__input_size', 'module__output_size'}, batch_size=128, callbacks=None, compile=False, dataset=<class 'skorch.dataset.Dataset'>, device='cpu', iterator_train=<...4, module__input_size=14, module__num_layers=2, module__output_size=6, module__rnn_model=<class 'torch.nn.modules.rnn.GRU'>, optimizer=<class 'torch.optim.sgd.SGD'>, predict_nonlinearity='auto', torch_load_kwargs=None, train_split=<skorch.dataset.ValidSplit object at 0x7607b1ebc7d0>, use_caching='auto', verbose=0, warm_start=False))]),
transformer=StandardScaler())}
In [13]:
Copied!
# compare models using cross_validation
models, scores = my_pipeline.compare_models(sort="model_predict_time", cross_validation=True)
# compare models using cross_validation
models, scores = my_pipeline.compare_models(sort="model_predict_time", cross_validation=True)
INFO:fowt_ml.pipeline:Logging experiment to MLflow with id 542351623230069078
2025/11/07 17:20:46 WARNING mlflow.utils.requirements_utils: The following packages were not found in the public PyPI package index as of 2025-04-15; if these packages are not present in the public PyPI index, you must install them manually before loading your model: {'fowt-ml'}
2025/11/07 17:20:59 WARNING mlflow.utils.requirements_utils: The following packages were not found in the public PyPI package index as of 2025-04-15; if these packages are not present in the public PyPI index, you must install them manually before loading your model: {'fowt-ml'}
2025/11/07 17:21:04 WARNING mlflow.utils.requirements_utils: The following packages were not found in the public PyPI package index as of 2025-04-15; if these packages are not present in the public PyPI index, you must install them manually before loading your model: {'fowt-ml'}
2025/11/07 17:21:08 WARNING mlflow.utils.requirements_utils: The following packages were not found in the public PyPI package index as of 2025-04-15; if these packages are not present in the public PyPI index, you must install them manually before loading your model: {'fowt-ml'}
INFO:fowt_ml.pipeline:Saving grid scores to grid_scores.csv
INFO:fowt_ml.pipeline:Saving best model to joblib format in best_model.joblib
In [14]:
Copied!
scores
scores
Out[14]:
| model_fit_time | neg_mean_absolute_error | neg_root_mean_squared_error | r2 | model_predict_time | |
|---|---|---|---|---|---|
| MultilayerPerceptron | 6.433333 | -1.601874 | -2.126851 | 0.120934 | 0.000667 |
| LeastAngleRegression | 0.190333 | -1.607107 | -2.138802 | 0.108088 | 0.001000 |
| XGBoostRegression | 2.320000 | -1.590403 | -2.102121 | 0.146356 | 0.001000 |
| LinearRegression | 0.214333 | -1.607107 | -2.138802 | 0.108088 | 0.001000 |
| LSTMRegressor | 30.154333 | -1.633139 | -2.168106 | 0.018256 | 0.001000 |
| GRURegressor | 358.188667 | -1.615096 | -2.147482 | 0.078020 | 0.001000 |
| RNNRegressor | 115.061000 | -1.606321 | -2.137074 | 0.110053 | 0.001000 |
| LassoRegression | 0.185000 | -1.638445 | -2.174113 | -0.000020 | 0.001333 |
| ElasticNetRegression | 0.168000 | -1.637037 | -2.172398 | 0.011023 | 0.001667 |
| RandomForest | 3.776667 | -1.604963 | -2.131216 | 0.107301 | 0.002000 |
| SklearnGPRegressor | 51.833667 | -1.602236 | -2.130439 | 0.122882 | 0.003000 |
In [ ]:
Copied!