Skip to content

Fix to scipy.minimize changes#124

Merged
desilinguist merged 3 commits into
mainfrom
fix-scipy-change
Jul 7, 2023
Merged

Fix to scipy.minimize changes#124
desilinguist merged 3 commits into
mainfrom
fix-scipy-change

Conversation

@ikeuchi-screen

Copy link
Copy Markdown
Collaborator

Motivation

Fix for changes in scipy-1.11.0

The scipy.optimize.minimize function was changed in scipy-1.11.0.

SciPy 1.11.0 Release Notes
https://scipy.github.io/devdocs/release/1.11.0-notes.html#expired-deprecations

The scipy.optimize.minimize function now raises an error for x0 with x0.ndim > 1.

How to reproduce the error

Executing the following code will result in an error.

Confirmatory factor analysis example.

import pandas as pd
from factor_analyzer import (ConfirmatoryFactorAnalyzer, ModelSpecificationParser)

df_features = pd.read_csv('tests/data/test11.csv')
model_dict = {"F1": ["V1", "V2", "V3", "V4"], "F2": ["V5", "V6", "V7", "V8"]}
model_spec = ModelSpecificationParser.parse_model_specification_from_dict(df_features, model_dict)
cfa = ConfirmatoryFactorAnalyzer(model_spec, disp=False)
cfa.fit(df_features.values)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In [1], line 8
      6 model_spec = ModelSpecificationParser.parse_model_specification_from_dict(df_features, model_dict)
      7 cfa = ConfirmatoryFactorAnalyzer(model_spec, disp=False)
----> 8 cfa.fit(df_features.values)

File ~\factor_analyzer\confirmatory_factor_analyzer.py:742, in ConfirmatoryFactorAnalyzer.fit(self, X, y)
    737     assert len(self.bounds) == len(x0), error_msg
    739 # fit the actual model using L-BFGS algorithm;
    740 # the constraints are set inside the objective function,
    741 # so that we can avoid using linear programming methods (e.g. SLSQP)
--> 742 res = minimize(
    743     self._objective,
    744     x0,
    745     method="L-BFGS-B",
    746     options={"maxiter": self.max_iter, "disp": self.disp},
    747     bounds=self.bounds,
    748     args=(cov_mtx, self.model.loadings),
    749 )
    751 # if the optimizer failed to converge, print the message
    752 if not res.success:

File ~\AppData\Roaming\Python\Python39\site-packages\scipy\optimize\_minimize.py:533, in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options)
    530 x0 = np.atleast_1d(np.asarray(x0))
    532 if x0.ndim != 1:
--> 533     raise ValueError("'x0' must only have one dimension.")
    535 if x0.dtype.kind in np.typecodes["AllInteger"]:
    536     x0 = np.asarray(x0, dtype=float)

ValueError: 'x0' must only have one dimension.

Expected Behavior

https://github.com/EducationalTestingService/factor_analyzer#examples

Description of the changes

The error can be avoided by setting x0 in the minimize function to 1d-vector.

res = minimize(
    self._objective,
    x0.flatten(),
    method="L-BFGS-B",
    options={"maxiter": self.max_iter, "disp": self.disp},
    bounds=self.bounds,
    args=(cov_mtx, self.model.loadings),
)

@desilinguist

Copy link
Copy Markdown
Collaborator

@ikeuchi-screen I think I know why the code coverage is not being computed. I am going to use this PR to also fix the coverage issue in a bit. Thanks for your patience!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants