HI Following the guide in the documentation: <Tra...
# mlforecast
a
HI Following the guide in the documentation: Transfer Learning with MLForecast, I encountered an issue with the ts object when performing transfer learning. While the local target scaler is correctly updated for the new
unique_id
in the new dataframe (as seen in
fcst.ts.target_transforms[0].scaler_.stats_
), the same does not happen for
fcst.ts.uids
. In the provided example, after fitting the model on the M3 dataset and then applying it to the M4 dataset,
fcst.ts.uids
still contains the unique_id values from M3, instead of the updated values from M4.
Copy code
import lightgbm as lgb
import numpy as np
import pandas as pd
from datasetsforecast.m3 import M3
from datasetsforecast.m4 import M4

from mlforecast import MLForecast
from mlforecast.target_transforms import *

Y_df_M3, _, _ = M3.load(directory='./', group='Monthly')
Y_df_M4, _, _ = M4.load(directory='./', group='Monthly')
Y_df_M4['ds'] = pd.to_datetime(Y_df_M4['ds'])

models = [lgb.LGBMRegressor(verbosity=-1)]
fcst = MLForecast(
    models=models, 
    lags=range(1, 13),
    freq='MS',
    target_transforms=[LocalStandardScaler()],
)
fcst.fit(Y_df_M3);

print('total M3 unique_id: ', len(Y_df_M3['unique_id'].unique()))
print('total uids before transfer learning: ', len(fcst.ts.uids))
print('scaler len before transfer learning: ', len(fcst.ts.target_transforms[0].scaler_.stats_))

Y_hat_df = fcst.predict(h=12, new_df=Y_df_M4)

print('total M4 unique_id: ', len(Y_df_M4['unique_id'].unique()))
print('total uids after transfer learning: ', len(fcst.ts.uids))
print('scaler len after transfer learning: ', len(fcst.ts.target_transforms[0].scaler_.stats_))
Copy code
total M3 unique_id:  1428
total uids before transfer learning:  1428
scaler len before transfer learning:  1428
total M4 unique_id:  48000
total uids after transfer learning:  1428
scaler len after transfer learning:  48000
It would be useful to have
fcst.ts.uids
updated to reflect the new unique_id values. This is particularly important for correctly retrieving scaler values when performing an inverse transform on SHAP values for the new predictions, as shown below:
Copy code
# Create dictionary for stdscaler
scaler_dict = {
    unique_id: [
        scaler_stats[0],  # Mean
        scaler_stats[1],  # Std deviation
    ]
    for unique_id, scaler_stats in zip(
        fcst.ts.uids,  # Still contains M3 unique_ids
        fcst.ts.target_transforms[0].scaler_.stats_,
    )
}
I have opened an issue here: https://github.com/Nixtla/mlforecast/issues/484
j
interesting issue. do you except not to see ids from both data sets in uids, or only from the new_df? i think it makes sense that the original ids are (still) present in iuds. maybe you even need a new object like uids_new?
j
The transfer learning in this library is just taking a pretrained model and applying it to new data, not updating it in any way. If the target transforms are changing then that's the bug, not the ids not updating
a
Then I think it would be great to have metadata also for new_df in new objects like uids_new and new_target_transforms What do you think? @José Morales
j
but then there is the question how to apply this. because the transfer learning is intended to use a trained model on any new articles / data sets. so you could get forecasts from 5 different data sets. now in iuds_new do you want to save the full history or always the lasst set of articles where the model was applied to?
a
I think that just the last one is ok
The important thing is to find a way to map the new ids to the target transform values (the mean and the std dev) because i need to inverse transform shap values for each unique_id
j
The ids are always sorted, so you can sort yours, but the target transforms won't be available because thats a bug
a
Is there a way then to apply the LocalStandardScaler outside the mlforecast object so I can create the corrispondence?
j
You can deep copy the ts attribute and use fit_transform on your new data. That one will have both the ids and the transforms for the new data
a
That works! Thanks
👍 1