o
    ?HhI                     @   s  d dl Z d dlmZ d dlmZ d dlZd dlmZ d dl	m
Z
mZmZmZmZmZ d dlmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZmZmZ d dlmZ d1ddZe  fddZ!eeddZ"d2ddZ#dd Z$G dd de%Z&G dd dee
Z'G dd dee
Z(G dd dee
Z)G dd  d ee
Z*G d!d" d"ee
Z+G d#d$ d$e
Z,G d%d& d&eZ-G d'd( d(eeZ.G d)d* d*eee
Z/G d+d, d,eee
Z0G d-d. d.eee
Z1G d/d0 d0eee
Z2dS )3    N)defaultdict)partial)assert_array_equal)BaseEstimatorClassifierMixinMetaEstimatorMixinRegressorMixinTransformerMixinclone)_Scorermean_squared_error)BaseCrossValidator)GroupsConsumerMixin)SIMPLE_METHODS)MetadataRouterMethodMappingprocess_routing)_check_partial_fit_first_callTc                 K   sb   t  }|d j}|d j}t| dstdd | _|s%dd | D }| j| | | dS )	zUtility function to store passed metadata to a method of obj.

    If record_default is False, kwargs whose values are "default" are skipped.
    This is so that checks on keyword arguments whose default was not changed
    are skipped.

          _recordsc                   S   s   t tS N)r   list r   r   e/home/air/sanwanet/gpt-api/venv/lib/python3.10/site-packages/sklearn/tests/metadata_routing_common.py<lambda>*   s    z!record_metadata.<locals>.<lambda>c                 S   s(   i | ]\}}t |tr|d kr||qS )default
isinstancestr).0keyvalr   r   r   
<dictcomp>,   s    z#record_metadata.<locals>.<dictcomp>N)inspectstackfunctionhasattrr   r   itemsappend)objrecord_defaultkwargsr%   calleecallerr   r   r   record_metadata   s   


r/   c           
   	   K   s   t | dt |t |t }|D ]Y}t| t| ks/J d|  d|  | D ]8\}}|| }	||v rN|	durNt|	|	 sMJ q3t
|	tjrZt|	| q3|	|u skJ d|	 d| d| q3qdS )a  Check whether the expected metadata is passed to the object's method.

    Parameters
    ----------
    obj : estimator object
        sub-estimator to check routed params for
    method : str
        sub-estimator's method where metadata is routed to, or otherwise in
        the context of metadata routing referred to as 'callee'
    parent : str
        the parent method which should have called `method`, or otherwise in
        the context of metadata routing referred to as 'caller'
    split_params : tuple, default=empty
        specifies any parameters which are to be checked as being a subset
        of the original values
    **kwargs : dict
        passed metadata
    r   z	Expected z vs Nz
. Method: )getattrdictgetr   setkeysr(   npisinallr   ndarrayr   )
r*   methodparentsplit_paramsr,   all_recordsrecordr!   valuerecorded_valuer   r   r   check_recorded_metadata4   s&    
r@   F)r+   c                 C   s   t | tr$| D ]\}}|dur||v r|| }nd}t|j|d qdS |du r*g n|}tD ]}||v r5q.t| |}dd |j D }|rHJ q.dS )a  Check if a metadata request dict is empty.

    One can exclude a method or a list of methods from the check using the
    ``exclude`` parameter. If metadata_request is a MetadataRouter, then
    ``exclude`` can be of the form ``{"object" : [method, ...]}``.
    N)excludec                 S   s&   g | ]\}}t |ts|d ur|qS r   r   )r    propaliasr   r   r   
<listcomp>w   s    z+assert_request_is_empty.<locals>.<listcomp>)r   r   assert_request_is_emptyrouterr   r0   requestsr(   )metadata_requestrA   nameroute_mapping_excluder9   mmrpropsr   r   r   rE   b   s"   



rE   c                    s^      D ]\}}t| |}|j|ksJ q fddtD }|D ]}tt| |jr,J q d S )Nc                    s   g | ]}| vr|qS r   r   )r    r9   
dictionaryr   r   rD      s    z(assert_request_equal.<locals>.<listcomp>)r(   r0   rG   r   len)requestrO   r9   rG   rL   empty_methodsr   rN   r   assert_request_equal   s   
rS   c                   @   s   e Zd Zdd Zdd ZdS )	_Registryc                 C      | S r   r   )selfmemor   r   r   __deepcopy__      z_Registry.__deepcopy__c                 C   rU   r   r   rV   r   r   r   __copy__   rY   z_Registry.__copy__N)__name__
__module____qualname__rX   r[   r   r   r   r   rT      s    rT   c                   @   sB   e Zd ZdZdddZdddZddd	Zdd
dZdddZdS )ConsumingRegressorac  A regressor consuming metadata.

    Parameters
    ----------
    registry : list, default=None
        If a list, the estimator will append itself to the list in order to have
        a reference to the estimator later on. Since that reference is not
        required in all tests, registration can be skipped by leaving this value
        as None.
    Nc                 C   
   || _ d S r   registryrV   rb   r   r   r   __init__      
zConsumingRegressor.__init__r   c                 C   (   | j d ur| j |  t| ||d | S Nsample_weightmetadatarb   r)   record_metadata_not_defaultrV   Xyri   rj   r   r   r   partial_fit      
zConsumingRegressor.partial_fitc                 C   rf   rg   rk   rm   r   r   r   fit   rq   zConsumingRegressor.fitc                 C   s    t | ||d tjt|fdS )Nrh   shaperl   r5   zerosrP   rm   r   r   r   predict   s   zConsumingRegressor.predictc                 C      t | ||d dS Nrh   r   rl   rm   r   r   r   score      zConsumingRegressor.scorer   r   r   Nr   r   )	r\   r]   r^   __doc__rd   rp   rr   rw   r{   r   r   r   r   r_      s    


	
	r_   c                   @   sL   e Zd ZdZdddZdd Zddd	Zd
d Zdd Zdd Z	dd Z
dS )NonConsumingClassifier5A classifier which accepts no metadata on any method.        c                 C   r`   r   )alpha)rV   r   r   r   r   rd      re   zNonConsumingClassifier.__init__c                 C   s   t || _t || _| S r   )r5   uniqueclasses_	ones_likecoef_rV   rn   ro   r   r   r   rr      s   zNonConsumingClassifier.fitNc                 C   rU   r   r   )rV   rn   ro   classesr   r   r   rp      rY   z"NonConsumingClassifier.partial_fitc                 C   
   |  |S r   )rw   rV   rn   r   r   r   decision_function   re   z(NonConsumingClassifier.decision_functionc                 C   s>   t jt|fd}d|d t|d < d|t|d d < |S )Nrs   r   r   r   )r5   emptyrP   )rV   rn   y_predr   r   r   rw      s   zNonConsumingClassifier.predictc                 C   sd   t jt|dfd}t ddg|d t|d d d f< t ddg|t|d d d d f< |S )Nr   rs         ?r   )r5   r   rP   asarray)rV   rn   y_probar   r   r   predict_proba   s   &&z$NonConsumingClassifier.predict_probac                 C   r   r   )r   r   r   r   r   predict_log_proba   s   
z(NonConsumingClassifier.predict_log_proba)r   r   )r\   r]   r^   r   rd   rr   rp   r   rw   r   r   r   r   r   r   r      s    

r   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	NonConsumingRegressorr   c                 C   rU   r   r   r   r   r   r   rr      rY   zNonConsumingRegressor.fitc                 C   rU   r   r   r   r   r   r   rp      rY   z!NonConsumingRegressor.partial_fitc                 C   s   t t|S r   )r5   onesrP   r   r   r   r   rw      s   zNonConsumingRegressor.predictN)r\   r]   r^   r   rr   rp   rw   r   r   r   r   r      s
    r   c                   @   sb   e Zd ZdZdddZ	dddZdd	d
ZdddZdddZdddZ	dddZ
dddZdS )ConsumingClassifiera  A classifier consuming metadata.

    Parameters
    ----------
    registry : list, default=None
        If a list, the estimator will append itself to the list in order to have
        a reference to the estimator later on. Since that reference is not
        required in all tests, registration can be skipped by leaving this value
        as None.

    alpha : float, default=0
        This parameter is only used to test the ``*SearchCV`` objects, and
        doesn't do anything.
    Nr   c                 C   s   || _ || _d S r   )r   rb   )rV   rb   r   r   r   r   rd        
zConsumingClassifier.__init__r   c                 C   s2   | j d ur| j |  t| ||d t| | | S rg   )rb   r)   rl   r   )rV   rn   ro   r   ri   rj   r   r   r   rp     s   

zConsumingClassifier.partial_fitc                 C   s@   | j d ur| j |  t| ||d t|| _t|| _| S rg   )rb   r)   rl   r5   r   r   r   r   rm   r   r   r   rr     s   
zConsumingClassifier.fitc                 C   sN   t | ||d tjt|fdd}d|t|d d < d|d t|d < |S )Nrh   int8)rt   dtyper   r   r   rl   r5   r   rP   rV   rn   ri   rj   y_scorer   r   r   rw      s   zConsumingClassifier.predictc                 C   sr   t | ||d tjt|dfd}tddg|d t|d d d f< tddg|t|d d d d f< |S )Nrh   r   rs   r   r   )rl   r5   r   rP   r   )rV   rn   ri   rj   r   r   r   r   r   )  s   &&z!ConsumingClassifier.predict_probac                 C   s"   t | ||d tjt|dfdS )Nrh   r   rs   ru   rV   rn   ri   rj   r   r   r   r   2  s   z%ConsumingClassifier.predict_log_probac                 C   sL   t | ||d tjt|fd}d|t|d d < d|d t|d < |S )Nrh   rs   r   r   r   r   r   r   r   r   r   8  s   z%ConsumingClassifier.decision_functionc                 C   rx   ry   rz   rm   r   r   r   r{   A  r|   zConsumingClassifier.score)Nr   r~   r}   )r\   r]   r^   r   rd   rp   rr   rw   r   r   r   r{   r   r   r   r   r      s    




	
	
	r   c                   @   sB   e Zd ZdZdddZdddZddd	Zdd
dZdddZdS )ConsumingTransformera~  A transformer which accepts metadata on fit and transform.

    Parameters
    ----------
    registry : list, default=None
        If a list, the estimator will append itself to the list in order to have
        a reference to the estimator later on. Since that reference is not
        required in all tests, registration can be skipped by leaving this value
        as None.
    Nc                 C   r`   r   ra   rc   r   r   r   rd   T  re   zConsumingTransformer.__init__r   c                 C   s.   | j d ur| j |  t| ||d d| _| S )Nrh   T)rb   r)   rl   fitted_rm   r   r   r   rr   W  s   
zConsumingTransformer.fitc                 C   s   t | ||d |d S ry   rz   r   r   r   r   	transforma     zConsumingTransformer.transformc                 C   s,   t | ||d | j||||dj|||dS rg   )rl   rr   r   rm   r   r   r   fit_transformg  s   z"ConsumingTransformer.fit_transformc                 C   s   t | ||d |d S ry   rz   r   r   r   r   inverse_transforms  r   z&ConsumingTransformer.inverse_transformr   r~   r}   NN)	r\   r]   r^   r   rd   rr   r   r   r   r   r   r   r   r   H  s    




r   c                   @   s.   e Zd ZdZd	ddZd
ddZdddZdS )"ConsumingNoFitTransformTransformerzA metadata consuming transformer that doesn't inherit from
    TransformerMixin, and thus doesn't implement `fit_transform`. Note that
    TransformerMixin's `fit_transform` doesn't route metadata to `transform`.Nc                 C   r`   r   ra   rc   r   r   r   rd     re   z+ConsumingNoFitTransformTransformer.__init__c                 C   rf   rg   )rb   r)   r/   rm   r   r   r   rr     s   
z&ConsumingNoFitTransformTransformer.fitc                 C   s   t | ||d |S rg   )r/   r   r   r   r   r     s   z,ConsumingNoFitTransformTransformer.transformr   NNNr   )r\   r]   r^   r   rd   rr   r   r   r   r   r   r   z  s
    

r   c                       s*   e Zd Zd fdd	Z fddZ  ZS )ConsumingScorerNc                    s   t  jtdi dd || _d S )Nr   rw   )
score_funcsignr,   response_method)superrd   r   rb   rc   	__class__r   r   rd     s   
zConsumingScorer.__init__c                    sH   | j d ur| j |  t| fi | |dd }t j|||||dS )Nri   ri   )rb   r)   rl   r2   r   _score)rV   method_callerclfrn   ro   r,   ri   r   r   r   r     s
   
zConsumingScorer._scorer   )r\   r]   r^   rd   r   __classcell__r   r   r   r   r     s    r   c                   @   s4   e Zd ZdddZdddZdddZdd	d
ZdS )ConsumingSplitterNc                 C   r`   r   ra   rc   r   r   r   rd     re   zConsumingSplitter.__init__r   c                 c   sj    | j d ur| j |  t| ||d t|d }ttd|}tt|t|}||fV  ||fV  d S )N)groupsrj   r   r   )rb   r)   rl   rP   r   range)rV   rn   ro   r   rj   split_indextrain_indicestest_indicesr   r   r   split  s   

zConsumingSplitter.splitc                 C   s   dS )Nr   r   )rV   rn   ro   r   rj   r   r   r   get_n_splits  rY   zConsumingSplitter.get_n_splitsc                 c   s>    t |d }ttd|}tt|t |}|V  |V  d S )Nr   r   )rP   r   r   )rV   rn   ro   r   r   r   r   r   r   r   _iter_test_indices  s   
z$ConsumingSplitter._iter_test_indicesr   r~   )NNNNr   )r\   r]   r^   rd   r   r   r   r   r   r   r   r     s
    


r   c                   @   r   )	MetaRegressorz(A meta-regressor which is only a router.c                 C   r`   r   )	estimator)rV   r   r   r   r   rd     re   zMetaRegressor.__init__c                 K   s6   t | dfi |}t| jj||fi |jj| _d S Nrr   )r   r
   r   rr   
estimator_rV   rn   ro   
fit_paramsparamsr   r   r   rr     s   $zMetaRegressor.fitc                 C   s*   t | jjdj| jt jdddd}|S Nownerrr   r.   r-   r   method_mapping)r   r   r\   addr   r   rV   rF   r   r   r   get_metadata_routing  s
   z"MetaRegressor.get_metadata_routingNr\   r]   r^   r   rd   rr   r   r   r   r   r   r     s
    r   c                   @   s4   e Zd ZdZdddZdddZdd Zd	d
 ZdS )WeightedMetaRegressorz*A meta-regressor which is also a consumer.Nc                 C      || _ || _d S r   r   rb   rV   r   rb   r   r   r   rd     r   zWeightedMetaRegressor.__init__c                 K   \   | j d ur| j |  t| |d t| dfd|i|}t| jj||fi |jj| _| S Nr   rr   ri   rb   r)   r/   r   r
   r   rr   r   )rV   rn   ro   ri   r   r   r   r   r   rr        
 zWeightedMetaRegressor.fitc                 K   s*   t | dfi |}| jj|fi |jjS )Nrw   )r   r   rw   r   )rV   rn   predict_paramsr   r   r   r   rw        zWeightedMetaRegressor.predictc                 C   s:   t | jjd| j| jt jdddjdddd}|S )Nr   rr   r   rw   r   r   r   r\   add_self_requestr   r   r   r   r   r   r   r     s   
z*WeightedMetaRegressor.get_metadata_routingr   )r\   r]   r^   r   rd   rr   rw   r   r   r   r   r   r     s    

	r   c                   @   s,   e Zd ZdZd	ddZd	ddZdd ZdS )
WeightedMetaClassifierzEA meta-estimator which also consumes sample_weight itself in ``fit``.Nc                 C   r   r   r   r   r   r   r   rd     r   zWeightedMetaClassifier.__init__c                 K   r   r   r   )rV   rn   ro   ri   r,   r   r   r   r   rr     r   zWeightedMetaClassifier.fitc                 C   s0   t | jjd| j| jt jdddd}|S r   r   r   r   r   r   r     s   z+WeightedMetaClassifier.get_metadata_routingr   r   r   r   r   r   r     s
    

	r   c                   @   s4   e Zd ZdZdd ZdddZdddZd	d
 ZdS )MetaTransformerzA simple meta-transformer.c                 C   r`   r   )transformer)rV   r   r   r   r   rd     re   zMetaTransformer.__init__Nc                 K   s6   t | dfi |}t| jj||fi |jj| _| S r   )r   r
   r   rr   transformer_r   r   r   r   rr     s    zMetaTransformer.fitc                 K   s*   t | dfi |}| jj|fi |jjS )Nr   )r   r   r   r   )rV   rn   ro   transform_paramsr   r   r   r   r     r   zMetaTransformer.transformc                 C   s0   t | jjdj| jt jdddjddddS )Nr   rr   r   r   )r   r   )r   r   r\   r   r   r   rZ   r   r   r   r     s   z$MetaTransformer.get_metadata_routingr   )r\   r]   r^   r   rd   rr   r   r   r   r   r   r   r     s    

r   )Tr   )3r$   collectionsr   	functoolsr   numpyr5   numpy.testingr   sklearn.baser   r   r   r   r	   r
   sklearn.metrics._scorerr   r   sklearn.model_selectionr   sklearn.model_selection._splitr    sklearn.utils._metadata_requestsr   sklearn.utils.metadata_routingr   r   r   sklearn.utils.multiclassr   r/   tupler@   rl   rE   rS   r   rT   r_   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s<     
+

.#T2"