Reputation: 821
I get the following error when I attempt to load a saved sklearn.preprocessing.MinMaxScaler
/shared/env/lib/python3.6/site-packages/sklearn/base.py:315: UserWarning: Trying to unpickle estimator MinMaxScaler from version 0.23.2 when using version 0.24.0. This might lead to breaking code or invalid results. Use at your own risk.
UserWarning)
[2021-01-08 19:40:28,805 INFO train.py:1317 - main ] EXCEPTION WORKER 100:
Traceback (most recent call last):
...
File "/shared/core/simulate.py", line 129, in process_obs
obs = scaler.transform(obs)
File "/shared/env/lib/python3.6/site-packages/sklearn/preprocessing/_data.py", line 439, in transform
if self.clip:
AttributeError: 'MinMaxScaler' object has no attribute 'clip'
I trained the scaler on one machine, saved it, and pushed it to a second machine where it was loaded and used to transform input.
# loading and transforming
import joblib
from sklearn.preprocessing import MinMaxScaler
scaler = joblib.load('scaler')
assert isinstance(scaler, MinMaxScaler)
data = scaler.transform(data) # throws exception
Upvotes: 8
Views: 17004
Reputation: 51
An approach that worked for me was to monkey-patch the MinMaxScaler.__setstate__
to set this attribute manually to false if non-existent with the snippet below:
from typing import Any, Dict
from sklearn.preprocessing import MinMaxScaler
original_minmax_setstate = MinMaxScaler.__setstate__
def __monkey_patch_minmax_setstate__(self, state: Dict[str, Any]) -> None:
state.setdefault("clip", False)
original_minmax_setstate(self, state)
MinMaxScaler.__setstate__ = __monkey_patch_minmax_setstate__
# Deserialize the scaler here
By adding this above the deserialization (unpickling), I managed to deserialize my object in a newer scikit-learn
version and then re-serialize it with the clip
alteration, no longer needing the monkey-patch afterwards.
Upvotes: 1
Reputation: 91
version issue of sklearn
You need to install in windows
pip install scikit-learn==0.24.0
I solve my Problem using this command
Upvotes: 0
Reputation: 1531
New property clip
was added to MinMaxScaler
in later version (since 0.24).
# loading and transforming
import joblib
from sklearn.preprocessing import MinMaxScaler
scaler = joblib.load('scaler')
assert isinstance(scaler, MinMaxScaler)
scaler.clip = False # add this line
data = scaler.transform(data) # throws exceptio
Explanation:
Becase clip
is defined in __init__
method it is part of MinMaxScaler.__dict__
. When you try to create object from pickle __setattr__
method is used to set all attributues, but clip
was not used in older version therefore is missing in your new MinMaxScale
instance. Simply add:
scaler.clip = False
and it should work fine.
Upvotes: 5
Reputation: 119
I solved this issue with pip install scikit-learn==0.23.2
in my conda or cmd. Essentially downgrading the scikit module helped.
Upvotes: 4
Reputation: 821
The issue is you are training the scaler on a machine with an older verion of sklearn than the machine you're using to load the scaler.
Noitce the UserWarning
UserWarning: Trying to unpickle estimator MinMaxScaler from version 0.23.2 when using version 0.24.0. This might lead to breaking code or invalid results. Use at your own risk. UserWarning)
The solution is to fix the version mismatch. Either by upgrading one sklearn to 0.24.0
or downgrading to 0.23.2
Upvotes: 12