Repository: biolab/orange3

Issue:
API change in scikit-learn latest release
Release notes for scikit-learn == 1.2.0 : https://scikit-learn.org/stable/whats_new/v1.2.html

> API Change The n_features_ attribute of [decomposition.PCA](https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html#sklearn.decomposition.PCA) is deprecated in favor of n_features_in_ and will be removed in 1.4. [#24421](https://github.com/scikit-learn/scikit-learn/pull/24421) by [Kshitij Mathur](https://github.com/Kshitij68).


Error msg when running tests for Louvain Clustering
```

Traceback (most recent call last):
  File "/Users/jakakokosar/Documents/dev/orange/orange3/Orange/widgets/unsupervised/owlouvainclustering.py", line 301, in __on_done
    result = future.result()
  File "/Users/jakakokosar/.pyenv/versions/3.10.8/lib/python3.10/concurrent/futures/_base.py", line 451, in result
    return self.__get_result()
  File "/Users/jakakokosar/.pyenv/versions/3.10.8/lib/python3.10/concurrent/futures/_base.py", line 403, in __get_result
    raise self._exception
  File "/Users/jakakokosar/.pyenv/versions/3.10.8/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/Users/jakakokosar/Documents/dev/orange/orange3/Orange/widgets/unsupervised/owlouvainclustering.py", line 613, in run_on_data
    data = res.pca_projection = pca(data)(data)
  File "/Users/jakakokosar/Documents/dev/orange/orange3/Orange/projection/base.py", line 50, in __call__
    clf = self.fit(data.X, data.Y)
  File "/Users/jakakokosar/Documents/dev/orange/orange3/Orange/projection/pca.py", line 268, in fit
    proj = proj.fit(X, Y)
  File "/Users/jakakokosar/.pyenv/versions/orange/lib/python3.10/site-packages/sklearn/decomposition/_pca.py", line 435, in fit
    self._fit(X)
  File "/Users/jakakokosar/Documents/dev/orange/orange3/Orange/projection/pca.py", line 142, in _fit
    return self._fit_truncated(X, n_components, self._fit_svd_solver)
  File "/Users/jakakokosar/Documents/dev/orange/orange3/Orange/projection/pca.py", line 204, in _fit_truncated
    self.n_samples_, self.n_features_ = n_samples, n_features
AttributeError: can't set attribute 'n_features_'

```


Discussion:

Resolving patch:
diff --git a/Orange/projection/pca.py b/Orange/projection/pca.py
--- a/Orange/projection/pca.py
+++ b/Orange/projection/pca.py
@@ -99,12 +99,12 @@ class ImprovedPCA(skl_decomposition.PCA):
     # pylint: disable=too-many-branches
     def _fit(self, X):
         """Dispatch to the right submethod depending on the chosen solver."""
-        X = check_array(
+        X = self._validate_data(
             X,
-            accept_sparse=["csr", "csc"],
             dtype=[np.float64, np.float32],
-            ensure_2d=True,
-            copy=self.copy,
+            reset=False,
+            accept_sparse=["csr", "csc"],
+            copy=self.copy
         )
 
         # Handle n_components==None
@@ -201,7 +201,7 @@ def _fit_truncated(self, X, n_components, svd_solver):
                 random_state=random_state,
             )
 
-        self.n_samples_, self.n_features_ = n_samples, n_features
+        self.n_samples_ = n_samples
         self.components_ = V
         self.n_components_ = n_components
 
@@ -221,12 +221,12 @@ def _fit_truncated(self, X, n_components, svd_solver):
     def transform(self, X):
         check_is_fitted(self, ["mean_", "components_"], all_or_any=all)
 
-        X = check_array(
+        X = self._validate_data(
             X,
             accept_sparse=["csr", "csc"],
             dtype=[np.float64, np.float32],
-            ensure_2d=True,
-            copy=self.copy,
+            reset=False,
+            copy=self.copy
         )
 
         if self.mean_ is not None:


Test patch: