Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ValueError: Unknown solver highs-ds #1211

Open
anilsh opened this issue Feb 11, 2023 · 6 comments
Open

ValueError: Unknown solver highs-ds #1211

anilsh opened this issue Feb 11, 2023 · 6 comments
Labels
Waiting for OP's Response Waiting for original poster's response, and will close if that doesn't happen for a while.

Comments

@anilsh
Copy link

anilsh commented Feb 11, 2023

In ExponentiatedGradient, the following error is coming. The error goes away after making run_linprog_step=False but this slows down the code and doesn't converge in even 100 iterations.

Also, the arguments doesn't support providing another solver.

The stack trace is:

Cell In[13], line 25, in reduction_exp_gradient(base_model)
     23     # train model 
---> 25     model_exp_grad.fit(gfr.X_train, gfr.y_train, sensitive_features=gfr.S_train)


File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\fairlearn\reductions\_exponentiated_gradient\exponentiated_gradient.py:200, in ExponentiatedGradient.fit(self, X, y, **kwargs)
    196     gap_LP = np.PINF
    197 else:
    198     # saddle point optimization over the convex hull of
    199     # classifiers returned so far
--> 200     Q_LP, self.lambda_vecs_LP_[t], result_LP = lagrangian.solve_linprog(
    201         self.nu
    202     )
    203     gap_LP = result_LP.gap()
    205 # keep values from exponentiated gradient or linear programming

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\fairlearn\reductions\_exponentiated_gradient\_lagrangian.py:168, in _Lagrangian.solve_linprog(self, nu)
    166 A_eq = np.concatenate((np.ones((1, n_hs)), np.zeros((1, 1))), axis=1)
    167 b_eq = np.ones(1)
--> 168 result = opt.linprog(
    169     c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq=b_eq, method="highs-ds"
    170 )
    171 Q = pd.Series(result.x[:-1], self.hs.index)
    172 dual_c = np.concatenate((b_ub, -b_eq))

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\scipy\optimize\_linprog.py:554, in linprog(c, A_ub, b_ub, A_eq, b_eq, bounds, method, callback, options, x0)
    550         x, status, message, iteration = _linprog_rs(
    551             c, c0=c0, A=A, b=b, x0=x0, callback=callback,
    552             postsolve_args=postsolve_args, **solver_options)
    553     else:
--> 554         raise ValueError('Unknown solver %s' % method)
    556 # Eliminate artificial variables, re-introduce presolved variables, etc.
    557 # need modified bounds here to translate variables appropriately
    558 disp = solver_options.get('disp', False)

ValueError: Unknown solver highs-ds
@anilsh
Copy link
Author

anilsh commented Feb 11, 2023

It worked after upgrading scipy to '1.10.0' but it creates problem with LogisticRegression().

Cell In[19], line 28, in reduction_exp_gradient(base_model)
     26     # train model 
     27     print ('Training base model using specified constraints..')
---> 28     model_exp_grad.fit(gfr.X_train, gfr.y_train, sensitive_features=gfr.S_train)
     29 #     self.inprocess['model'] = model_exp_grad
     30 
     31     # make predictions
     32     y_pred = model_exp_grad.predict(gfr.X_test) 

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\fairlearn\reductions\_exponentiated_gradient\exponentiated_gradient.py:168, in ExponentiatedGradient.fit(self, X, y, **kwargs)
    165 lambda_EG = self.lambda_vecs_EG_.mean(axis=1)
    167 # select classifier according to best_h method
--> 168 h, h_idx = lagrangian.best_h(lambda_vec)
    170 if t == 0:
    171     if self.nu is None:

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\fairlearn\reductions\_exponentiated_gradient\_lagrangian.py:234, in _Lagrangian.best_h(self, lambda_vec)
    228 def best_h(self, lambda_vec):
    229     """Solve the best-response problem.
    230 
    231     Returns the classifier that solves the best-response problem for
    232     the vector of Lagrange multipliers `lambda_vec`.
    233     """
--> 234     classifier = self._call_oracle(lambda_vec)
    236     def h(X):
    237         pred = classifier.predict(X)

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\fairlearn\reductions\_exponentiated_gradient\_lagrangian.py:222, in _Lagrangian._call_oracle(self, lambda_vec)
    219     estimator = clone(estimator=self.estimator, safe=False)
    221 oracle_call_start_time = time()
--> 222 estimator.fit(self.constraints.X, redY, **{self.sample_weight_name: redW})
    223 self.oracle_execution_times.append(time() - oracle_call_start_time)
    224 self.n_oracle_calls += 1

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\sklearn\linear_model\_logistic.py:1407, in LogisticRegression.fit(self, X, y, sample_weight)
   1405 else:
   1406     prefer = 'processes'
-> 1407 fold_coefs_ = Parallel(n_jobs=self.n_jobs, verbose=self.verbose,
   1408                        **_joblib_parallel_args(prefer=prefer))(
   1409     path_func(X, y, pos_class=class_, Cs=[C_],
   1410               l1_ratio=self.l1_ratio, fit_intercept=self.fit_intercept,
   1411               tol=self.tol, verbose=self.verbose, solver=solver,
   1412               multi_class=multi_class, max_iter=self.max_iter,
   1413               class_weight=self.class_weight, check_input=False,
   1414               random_state=self.random_state, coef=warm_start_coef_,
   1415               penalty=penalty, max_squared_sum=max_squared_sum,
   1416               sample_weight=sample_weight)
   1417     for class_, warm_start_coef_ in zip(classes_, warm_start_coef))
   1419 fold_coefs_, _, n_iter_ = zip(*fold_coefs_)
   1420 self.n_iter_ = np.asarray(n_iter_, dtype=np.int32)[:, 0]

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\joblib\parallel.py:1048, in Parallel.__call__(self, iterable)
   1039 try:
   1040     # Only set self._iterating to True if at least a batch
   1041     # was dispatched. In particular this covers the edge
   (...)
   1045     # was very quick and its callback already dispatched all the
   1046     # remaining jobs.
   1047     self._iterating = False
-> 1048     if self.dispatch_one_batch(iterator):
   1049         self._iterating = self._original_iterator is not None
   1051     while self.dispatch_one_batch(iterator):

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\joblib\parallel.py:864, in Parallel.dispatch_one_batch(self, iterator)
    862     return False
    863 else:
--> 864     self._dispatch(tasks)
    865     return True

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\joblib\parallel.py:782, in Parallel._dispatch(self, batch)
    780 with self._lock:
    781     job_idx = len(self._jobs)
--> 782     job = self._backend.apply_async(batch, callback=cb)
    783     # A job can complete so quickly than its callback is
    784     # called before we get here, causing self._jobs to
    785     # grow. To ensure correct results ordering, .insert is
    786     # used (rather than .append) in the following line
    787     self._jobs.insert(job_idx, job)

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\joblib\_parallel_backends.py:208, in SequentialBackend.apply_async(self, func, callback)
    206 def apply_async(self, func, callback=None):
    207     """Schedule a func to be run"""
--> 208     result = ImmediateResult(func)
    209     if callback:
    210         callback(result)

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\joblib\_parallel_backends.py:572, in ImmediateResult.__init__(self, batch)
    569 def __init__(self, batch):
    570     # Don't delay the application, to avoid keeping the input
    571     # arguments in memory
--> 572     self.results = batch()

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\joblib\parallel.py:263, in BatchedCalls.__call__(self)
    259 def __call__(self):
    260     # Set the default nested backend to self._backend but do not set the
    261     # change the default number of processes to -1
    262     with parallel_backend(self._backend, n_jobs=self._n_jobs):
--> 263         return [func(*args, **kwargs)
    264                 for func, args, kwargs in self.items]

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\joblib\parallel.py:263, in <listcomp>(.0)
    259 def __call__(self):
    260     # Set the default nested backend to self._backend but do not set the
    261     # change the default number of processes to -1
    262     with parallel_backend(self._backend, n_jobs=self._n_jobs):
--> 263         return [func(*args, **kwargs)
    264                 for func, args, kwargs in self.items]

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\sklearn\linear_model\_logistic.py:762, in _logistic_regression_path(X, y, pos_class, Cs, fit_intercept, max_iter, tol, verbose, solver, coef, class_weight, dual, penalty, intercept_scaling, multi_class, random_state, check_input, max_squared_sum, sample_weight, l1_ratio)
    755     iprint = [-1, 50, 1, 100, 101][
    756         np.searchsorted(np.array([0, 1, 2, 3]), verbose)]
    757     opt_res = optimize.minimize(
    758         func, w0, method="L-BFGS-B", jac=True,
    759         args=(X, target, 1. / C, sample_weight),
    760         options={"iprint": iprint, "gtol": tol, "maxiter": max_iter}
    761     )
--> 762     n_iter_i = _check_optimize_result(
    763         solver, opt_res, max_iter,
    764         extra_warning_msg=_LOGISTIC_SOLVER_CONVERGENCE_MSG)
    765     w0, loss = opt_res.x, opt_res.fun
    766 elif solver == 'newton-cg':

File ~\Anaconda3\envs\sheyzam-fairness-env\lib\site-packages\sklearn\utils\optimize.py:243, in _check_optimize_result(solver, result, max_iter, extra_warning_msg)
    235 if solver == "lbfgs":
    236     if result.status != 0:
    237         warning_msg = (
    238             "{} failed to converge (status={}):\n{}.\n\n"
    239             "Increase the number of iterations (max_iter) "
    240             "or scale the data as shown in:\n"
    241             "    https://scikit-learn.org/stable/modules/"
    242             "preprocessing.html"
--> 243         ).format(solver, result.status, result.message.decode("latin1"))
    244         if extra_warning_msg is not None:
    245             warning_msg += "\n" + extra_warning_msg

AttributeError: 'str' object has no attribute 'decode'

@romanlutz
Copy link
Member

@anilsh we have a bug template that provides instructions such as providing the versions of several key packages. Without that it's hard to impossible to help. Can you try adding this information?

@anilsh
Copy link
Author

anilsh commented Feb 16, 2023

Hi @romanlutz , the code works file when I use Scipy==1.6.0.
In 1.10.0, the solver throws an error str object has no member decode.

Fairlearn allow any version of Scipy above 1.4.1 but higher ones have changed significantly.

@romanlutz
Copy link
Member

@anilsh can you please follow the instructions from the bug template to print all dependencies? This sort of simple thing saves us several back-and-forth questions and speeds things up considerably. Thanks!

@anilsh
Copy link
Author

anilsh commented Feb 19, 2023

@romanlutz Can you please share the link to bug template? Couldn't find it.

@romanlutz
Copy link
Member

When you open an issue there's a template for "bug report". Just follow the instructions it contains.

@hildeweerts hildeweerts added the Waiting for OP's Response Waiting for original poster's response, and will close if that doesn't happen for a while. label Apr 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Waiting for OP's Response Waiting for original poster's response, and will close if that doesn't happen for a while.
Projects
None yet
Development

No branches or pull requests

3 participants