Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Optimize skopt produces invalidParameterError #986

Unanswered
MrDenfish asked this question in Q&A
Discussion options

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]
You must be logged in to vote

Replies: 5 comments 3 replies

Comment options

Having an issue with this as well. I see others are commenting on it in issue 880

You must be logged in to vote
1 reply
Comment options

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.

Comment options

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?

You must be logged in to vote
0 replies
Comment options

I think I found the solution! Or at least I manage to do the optimization without error!

The problem comes from several files :

  1. _param_validation.py (sklearn/utils/_param_validation.py)

  2. backtesting.py (backtesting/backtesting.py)

  3. 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 with squared_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 ?

You must be logged in to vote
1 reply
Comment options

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

Comment options

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
You must be logged in to vote
1 reply
Comment options

Thank you very much for taking your time. I will try that thank you!

Edit: it works amazing !

Comment options

I also had to downgrade numpy from 1.25 to 1.22.0

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /