1111)
1212from  sklearn .linear_model ._base  import  LinearClassifierMixin 
1313
14- from  sklearn .base  import  MultiOutputMixin 
1514from  sklearn .multioutput  import  MultiOutputClassifier 
1615from  sklearn .svm  import  LinearSVC 
1716from  sklearn .utils  import  check_array 
@@ -36,8 +35,8 @@ class PCovC(LinearClassifierMixin, _BasePCov):
3635            (1 - \alpha) \mathbf{Z}\mathbf{Z}^T 
3736
3837    where :math:`\alpha` is a mixing parameter, :math:`\mathbf{X}` is an input matrix of shape 
39-     :math:`(n_{samples}, n_{features})`, and :math:`\mathbf{Z}` is a matrix  of class confidence scores 
40-     of shape :math:`(n_{samples}, n_{classes})`. For :math:`(n_{samples} < n_{features})`, 
38+     :math:`(n_{samples}, n_{features})`, and :math:`\mathbf{Z}` is a tensor  of class confidence scores 
39+     of shape :math:`(n_{samples}, n_{classes}, n_{labels} )`. For :math:`(n_{samples} < n_{features})`, 
4140    this can be more efficiently computed using the eigendecomposition of a modified covariance matrix 
4241    :math:`\mathbf{\tilde{C}}` 
4342
@@ -112,10 +111,10 @@ class PCovC(LinearClassifierMixin, _BasePCov):
112111        - ``sklearn.linear_model.LogisticRegressionCV()`` 
113112        - ``sklearn.svm.LinearSVC()`` 
114113        - ``sklearn.discriminant_analysis.LinearDiscriminantAnalysis()`` 
115-         - ``sklearn.multioutput.MultiOutputClassifier ()`` 
114+         - ``sklearn.linear_model.Perceptron ()`` 
116115        - ``sklearn.linear_model.RidgeClassifier()`` 
117116        - ``sklearn.linear_model.RidgeClassifierCV()`` 
118-         - ``sklearn.linear_model.Perceptron ()`` 
117+         - ``sklearn.multioutput.MultiOutputClassifier ()`` 
119118
120119        If a pre-fitted classifier 
121120        is provided, it is used to compute :math:`{\mathbf{Z}}`. 
@@ -175,11 +174,15 @@ class PCovC(LinearClassifierMixin, _BasePCov):
175174        the projector, or weights, from the input space :math:`\mathbf{X}` 
176175        to the latent-space projection :math:`\mathbf{T}` 
177176
178-     pxz_ : ndarray of size :math:`({n_{features}, })`, :math:`({n_{features}, n_{classes}})` 
177+     pxz_ : ndarray of size :math:`({n_{features}, {n_{classes}}})`, or list of 
178+         ndarrays of size :math:`({n_{features}, {n_{classes_i}}})` for a dataset 
179+         with :math: `i` labels. 
179180        the projector, or weights, from the input space :math:`\mathbf{X}` 
180181        to the class confidence scores :math:`\mathbf{Z}`. 
181182
182-     ptz_ : ndarray of size :math:`({n_{components}, })`, :math:`({n_{components}, n_{classes}})` 
183+     ptz_ : ndarray of size :math:`({n_{components}, {n_{classes}}})`, or list of 
184+         ndarrays of size :math:`({n_{components}, {n_{classes_i}}})` for a dataset 
185+         with :math: `i` labels. 
183186        the projector, or weights, from from the latent-space projection 
184187        :math:`\mathbf{T}` to the class confidence scores :math:`\mathbf{Z}`. 
185188
@@ -267,7 +270,7 @@ def fit(self, X, Y, W=None):
267270            Classification weights, optional when classifier is ``precomputed``. If 
268271            not passed, it is assumed that the weights will be taken from a 
269272            linear classifier fit between :math:`\mathbf{X}` and :math:`\mathbf{Y}`. 
270-             In the multioutput case, 
273+             In the multioutput case, use  
271274            `` W = np.hstack([est_.coef_.T for est_ in classifier.estimators_])``. 
272275        """ 
273276        X , Y  =  validate_data (self , X , Y , multi_output = True , y_numeric = False )
@@ -329,15 +332,15 @@ def fit(self, X, Y, W=None):
329332                W  =  np .hstack ([_ .coef_ .T  for  _  in  _ .estimators_ ])
330333            else :
331334                W  =  _ .coef_ .T 
332-         else :
335+         elif   W   is   None :
333336            self .z_classifier_  =  check_cl_fit (classifier , X , Y )
334337            if  multioutput :
335338                W  =  np .hstack ([est_ .coef_ .T  for  est_  in  self .z_classifier_ .estimators_ ])
336339            else :
337340                W  =  self .z_classifier_ .coef_ .T 
338341
339342        Z  =  X  @ W 
340- 
343+          
341344        if  self .space_  ==  "feature" :
342345            self ._fit_feature_space (X , Y , Z )
343346        else :
@@ -348,19 +351,12 @@ def fit(self, X, Y, W=None):
348351        self .classifier_  =  clone (classifier ).fit (X  @ self .pxt_ , Y )
349352
350353        if  multioutput :
351-             self .ptz_  =  np .hstack (
352-                 [est_ .coef_ .T  for  est_  in  self .classifier_ .estimators_ ]
353-             )
354-             # print(f"pxt {self.pxt_.shape}") 
355-             # print(f"ptz {self.ptz_.shape}") 
356-             self .pxz_  =  self .pxt_  @ self .ptz_ 
357-             # print(f"pxz {self.pxz_.shape}") 
354+             self .ptz_  =  [est_ .coef_ .T  for  est_  in  self .classifier_ .estimators_ ]
355+             self .pxz_  =  [self .pxt_  @ ptz  for  ptz  in  self .ptz_ ]
358356        else :
359357            self .ptz_  =  self .classifier_ .coef_ .T 
360-             # print(self.ptz_.shape) 
361358            self .pxz_  =  self .pxt_  @ self .ptz_ 
362359
363-         # print(self.ptz_.shape) 
364360        if  not  multioutput  and  type_of_target (Y ) ==  "binary" :
365361            self .pxz_  =  self .pxz_ .reshape (
366362                X .shape [1 ],
@@ -531,3 +527,4 @@ def score(self, X, y, sample_weight=None):
531527
532528    # Inherit the docstring from scikit-learn 
533529    score .__doc__  =  LinearClassifierMixin .score .__doc__ 
530+     
0 commit comments