-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
-
The actual error is : sklearn.utils._param_validation.InvalidParameterError: The 'criterion' parameter of ExtraTreesRegressor must be a str among {'absolute_error', 'squared_error', 'friedman_mse', 'poisson'}. Got 'mse' instead
.
Tried on several strategies, get the same error at 14% completion. A very simple strategy (below) throws the error. Any insight on how to fix would be very nice.
from backtesting import Backtest, Strategy
from backtesting.test import GOOG
from backtesting.lib import crossover, resample_apply
import matplotlib.pyplot as plt
import seaborn as sns
import talib
#<><><><><><><><><><><><> Optimize Function <><><><><><><><><><><><>
def optim_func(series):
if series["# Trades"]<10:
return-1
return series["Equity Final [$]"]/series["Exposure Time [%]"]
#<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
class RsiOscillator(Strategy):
upper_bound = 70
lower_bound = 30
rsi_window = 14
def init(self):
self.daily_rsi = self.I(talib.RSI, self.data.Close, self.rsi_window)
self.weekly_rsi = resample_apply("W-FRI", talib.RSI, self.data.Close, self.rsi_window)
def next(self):
print(self.weekly_rsi[-1] > self.upper_bound)
if (crossover(self.daily_rsi,self.upper_bound) and self.weekly_rsi[-1] > self.upper_bound):
self.position.close()
elif (crossover(self.daily_rsi, self.lower_bound) and self.weekly_rsi[-1] < self.lower_bound):
self.buy()
bt = Backtest(GOOG,RsiOscillator,cash =1000.00,commission =.0025)
#stats = bt.run()
stats = bt.optimize(
upper_bound = [70,85],
lower_bound = [10,45],
rsi_window = [10,32],
maximize = optim_func,
constraint = lambda p:p.upper_bound > p.lower_bound,
method='skopt',
max_tries=200,
random_state=0,
return_heatmap=False,
return_optimization=True)# lambda prevents lower bound from being larger than upper bound
print(stats)
bt.plot()
Traceback (most recent call last):
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/spyder_kernels/py3compat.py:356 in compat_exec
exec(code, globals, locals)
File ~/.spyder-py3/My Scripts/backTest.py:48
stats = bt.optimize(
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/backtesting/backtesting.py:1490 in optimize
output = _optimize_skopt()
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/backtesting/backtesting.py:1456 in _optimize_skopt
res = forest_minimize(
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/skopt/optimizer/forest.py:186 in forest_minimize
return base_minimize(func, dimensions, base_estimator,
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/skopt/optimizer/base.py:300 in base_minimize
result = optimizer.tell(next_x, next_y)
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/skopt/optimizer/optimizer.py:493 in tell
return self._tell(x, y, fit=fit)
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/skopt/optimizer/optimizer.py:536 in _tell
est.fit(self.space.transform(self.Xi), self.yi)
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/sklearn/ensemble/_forest.py:340 in fit
self._validate_params()
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/sklearn/base.py:600 in _validate_params
validate_parameter_constraints(
File ~/anaconda3/envs/Virtual_1/lib/python3.10/site-packages/sklearn/utils/_param_validation.py:97 in validate_parameter_constraints
raise InvalidParameterError(
InvalidParameterError: The 'criterion' parameter of ExtraTreesRegressor must be a str among {'absolute_error', 'squared_error', 'friedman_mse', 'poisson'}. Got 'mse' instead.
Backtest.optimize: 14%|█▎ | 27/200 [00:19<00:10, 15.89it/s]
Beta Was this translation helpful? Give feedback.
All reactions
-
👀 1
Replies: 5 comments 3 replies
-
Having an issue with this as well. I see others are commenting on it in issue 880
Beta Was this translation helpful? Give feedback.
All reactions
-
hmm, thanks for the info. Im getting a different error now that I am using pycharm.
File "/Users/xxxx/anaconda3/envs/virtualenv/lib/python3.10/site-packages/numpy/__init__.py", line 305, in __getattr__
raise AttributeError(__former_attrs__[attr])
AttributeError: module 'numpy' has no attribute 'int'.
just using grid to get what I need but it would be nice to get this figured out.
Beta Was this translation helpful? Give feedback.
All reactions
-
Same error with skopt. I use the latest versions of the libraries.
Backtesting.py=0.3.3
, scikit-optimize=0.9.0
.
#Import import yfinance as yf import ta import pandas as pd from backtesting import Backtest, Strategy from backtesting.lib import crossover
#optimize skopt optim = bt.optimize(n1 = range(1,100,1), n2 = range(1,100,1), constraint = lambda x: x.n2 - x.n1 > 20, maximize = 'Equity Final [$]', method='skopt', max_tries=200, random_state=0) bt.plot() optim #Result
I run my code on google colab with Python version 3.10.12
and I also get the same error :
Backtest.optimize: 11% -------- 22/200 [00:01<00:11, 15.07it/s]
---------------------------------------------------------------------------
InvalidParameterError Traceback (most recent call last)
[<ipython-input-8-c02acc2c12b7>](https://localhost:8080/#) in <cell line: 2>()
1 #optimize skopt
----> 2 optim = bt.optimize(n1 = range(1,100,1),
3 n2 = range(1,100,1),
4 constraint = lambda x: x.n2 - x.n1 > 20,
5 maximize = 'Equity Final [$]',
8 frames
[/usr/local/lib/python3.10/dist-packages/sklearn/utils/_param_validation.py](https://localhost:8080/#) in validate_parameter_constraints(parameter_constraints, params, caller_name)
95 )
96
---> 97 raise InvalidParameterError(
98 f"The {param_name!r} parameter of {caller_name} must be"
99 f" {constraints_str}. Got {param_val!r} instead."
InvalidParameterError: The 'criterion' parameter of ExtraTreesRegressor must be a str among {'poisson', 'absolute_error', 'squared_error', 'friedman_mse'}. Got 'mse' instead.
The error always appears at the same iteration. If I use the grid method
there is no bug but I need the skopt method to reduce the number of iterations.
Anyone have an idea or found the solution?
Beta Was this translation helpful? Give feedback.
All reactions
-
I think I found the solution! Or at least I manage to do the optimization without error!
The problem comes from several files :
-
_param_validation.py (sklearn/utils/_param_validation.py)
-
backtesting.py (backtesting/backtesting.py)
-
forest.py (skopt/learning/forest.py)
Correction proposal :
-
In _param_validation.py (sklearn/utils/_param_validation.py)
(this file is not obliged to be modified, only the following two are obliged)
I think there is an indentation problem line 82. You need to indent the "else" block to be like this
for constraint in constraints: if constraint.is_satisfied_by(param_val): # this constraint is satisfied, no need to check further. break else: # No constraint is satisfied, raise with an informative message. # Ignore constraints that we don't want to expose in the error message, # i.e. options that are for internal purpose or not officially supported. constraints = [ constraint for constraint in constraints if not constraint.hidden ] if len(constraints) == 1: constraints_str = f"{constraints[0]}" else: constraints_str = ( f"{', '.join([str(c) for c in constraints[:-1]])} or" f" {constraints[-1]}" ) raise InvalidParameterError( f"The {param_name!r} parameter of {caller_name} must be" f" {constraints_str}. Got {param_val!r} instead." )
-
in backtesting.py (backtesting/backtesting.py)
At line 1460 in the ExtraTreesRegressor() model you must add criterion="squared_error" like this:
base_estimator=ExtraTreesRegressor(n_estimators=20, min_samples_leaf=2, criterion="squared_error"),
res = forest_minimize( func=objective_function, dimensions=dimensions, n_calls=max_tries, base_estimator=ExtraTreesRegressor(n_estimators=20, min_samples_leaf=2, criterion="squared_error"), acq_func='LCB', kappa=3, n_initial_points=min(max_tries, 20 + 3 * len(kwargs)), initial_point_generator='lhs', # 'sobel' requires n_initial_points ~ 2**N callback=DeltaXStopper(9e-7), random_state=random_state)
I would need you to know if it is squared_error
that we should put because before the modifications it used mse
-
in forest.py (skopt/learning/forest.py)
on line 438 and 440 replace
mse
withsquared_error
mean = super(ExtraTreesRegressor, self).predict(X) if return_std: if self.criterion != "squared_error": raise ValueError( "Expected impurity to be 'squared_error', got %s instead" % self.criterion) std = _return_std(X, self.estimators_, mean, self.min_variance) return mean, std return mean
I don't know if this is a correct way to solve this problem and if the optimization works normally.
I would need your help to know if it is valid what I explain and if it is necessary to use squared_error
instead of mse
?
Beta Was this translation helpful? Give feedback.
All reactions
-
I really appricate your effort.
I did your steps. And still got this error: sklearn.utils._param_validation.InvalidParameterError: The 'methods' parameter of HasMethods.__init__ must be an instance of 'str' or an instance of 'list'. Got ['fit'] instead.
It's a joke, spending all hours and got this nothing.
This library might be crazy and abonded. Thanks y'all hard work.
Got solution read below comments
Beta Was this translation helpful? Give feedback.
All reactions
-
After couple minutes, The solution is We need to uninstall scikit-learning and install older version
Reference: #880 (comment)
pip uninstall scikit-learn
pip install scikit-learn==1.1.3
Beta Was this translation helpful? Give feedback.
All reactions
-
🎉 1
-
Thank you very much for taking your time. I will try that thank you!
Edit: it works amazing !
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 1
-
I also had to downgrade numpy from 1.25 to 1.22.0
Beta Was this translation helpful? Give feedback.