U
    OvfČP  ć                   @   sÜ  d dl Z d dlZd dlZd dlmZ d dlZd dl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 d dlmZ d d	lmZ d d
lmZmZmZ d dlm Z  dd Z!dd Z"dd Z#dd Z$dd Z%ej& 'dddddg”ej& 'dddg”dd Z(d d! Z)d"d# Z*d$d% Z+d&d' Z,ej& 'dddddg”d(d) Z-d*d+ Z.d,d- Z/d.d/ Z0d0d1 Z1ej& 'dddddg”d2d3 Z2ej& 'd4ddd5g”d6d7 Z3d8d9 Z4d:d; Z5d<d= Z6d>d? Z7d@dA Z8dBdC Z9dS )Dé    N)Ś	load_irisŚ
make_blobsŚmake_circles)ŚPCAŚ	KernelPCA)ŚNotFittedError)Ś
Perceptron)Ś
rbf_kernel)ŚGridSearchCV)ŚPipeline)ŚStandardScaler)Śassert_allcloseŚassert_array_almost_equalŚassert_array_equal)Ś_check_psd_eigenvaluesc                  C   są   t j d”} |  d”}|  d”}dd }dD ]®}ddd	|fD ]}t| }td
|||d}| |”}| |” |”}	t	t  
|”t  
|	” |jdkst| |”}
|
jd |jd ksŗt|r<| |
”}|j|jks<tq<q,dS )zÕNominal test for all solvers and all known kernels + a custom one

    It tests
     - that fit_transform is equivalent to fit+transform
     - that the shapes of transforms and inverse transforms are correct
    r   ©é   é   ©é   r   c                 [   s   |i kst t | |” ” S )N)ŚAssertionErrorŚnpZminimumŚsum)ŚxŚyŚkwargs© r   śO/tmp/pip-unpacked-wheel-qu3nn_q2/sklearn/decomposition/tests/test_kernel_pca.pyŚ	histogram#   s    z"test_kernel_pca.<locals>.histogram)ŚautoŚdenseŚarpackŚ
randomizedŚlinearŚrbfŚpolyr   )ŚkernelŚeigen_solverŚfit_inverse_transformé   N)r   ŚrandomŚRandomStateŚrandom_sampleŚcallabler   Śfit_transformŚfitŚ	transformr   ŚabsŚsizer   ŚshapeŚinverse_transform)ŚrngŚX_fitŚX_predr   r'   r&   ŚinvŚkpcaŚX_fit_transformedŚX_fit_transformed2ŚX_pred_transformedZX_pred2r   r   r   Śtest_kernel_pca   s2    


   ’
 ’

r=   c               	   C   sD   t dddd} d}tjt|d |  tj dd”” W 5 Q R X dS )zCheck that kPCA raises an error if the parameters are invalid

    Tests fitting inverse transform with a precomputed kernel raises a
    ValueError.
    é
   TŚprecomputed)Śn_componentsr(   r&   z6Cannot fit_inverse_transform with a precomputed kernel©ŚmatchN)r   ŚpytestŚraisesŚ
ValueErrorr/   r   r*   Śrandn)Z	estimatorZerr_msr   r   r   Ś"test_kernel_pca_invalid_parametersF   s      ’rG   c                  C   sb   t j d”} |  dd”}t| d |”}| |”}| ” }d|dddf< | |”}t|| dS )zćCheck robustness to mutations in the original training array

    Test that after fitting a kPCA model, it stays independent of any
    mutation of the values of the original data object by relying on an
    internal copy.
    r   r>   )Śrandom_statei  N)	r   r*   r+   Śrandr   r/   r0   Ścopyr   )ŚstateŚXr9   Ztransformed1ZX_copyZtransformed2r   r   r   Ś$test_kernel_pca_consistent_transformT   s    

rM   c               	   C   s   t j d”} |  dd”}d}|D ]j}t  d”}tdD ],}td|| d}| |”d ||ddf< q6t|t  	|dddf d” 
dd” q dS )	zTest that Kernel PCA produces deterministic output

    Tests that the same inputs and random state produce the same output.
    r   r>   )r!   r    )é   r   rN   r   )r@   r'   rH   N)r   r*   r+   rI   ŚzerosŚranger   r.   r   ZtileŚreshape)r5   rL   r'   ŚsolverZtransformed_XŚir9   r   r   r   Ś$test_kernel_pca_deterministic_outputg   s    
rT   c            	      C   sČ   t j d”} t |  d””}t |  d””}dD ]}dD ]}td||ddd}| |”}| |” 	|”}t
t  |”t  |” | 	|”}|jd	 |jd	 ks tt t” | |” W 5 Q R X q8q0d
S )z¤Test that kPCA works on a sparse data input.

    Same test as ``test_kernel_pca except inverse_transform`` since it's not
    implemented for sparse matrices.
    r   r   r   )r   r!   r"   )r#   r$   r%   r   F)r&   r'   r(   rH   r)   N)r   r*   r+   ŚspZ
csr_matrixr,   r   r.   r/   r0   r   r1   r3   r   rC   rD   r   r4   )	r5   r6   r7   r'   r&   r9   r:   r;   r<   r   r   r   Śtest_kernel_pca_sparsex   s,    ū
 ’
rV   rR   r   r    r!   r"   Ś
n_featuresr   r>   c                 C   s   t j d”}| d|f”}| d|f”}| dkr4dnd}tt  t|| d |” |””t  t	|| dkrj| nd	d
 |” |”” dS )zTest that kPCA with linear kernel is equivalent to PCA for all solvers.

    KernelPCA with linear kernel should produce the same output as PCA.
    r   r   r   r!   é   r   )r'   r    Śfull)Z
svd_solverN)
r   r*   r+   r,   r   r1   r   r/   r0   r   )rR   rW   r5   r6   r7   Zn_compsr   r   r   Śtest_kernel_pca_linear_kernel   s    ’ž’žrZ   c                  C   sf   t j d”} |  d”}|  d”}dD ]<}dD ]2}t||d}| |” |”j}|d|fks,tq,q$dS )	zĒTest that `n_components` is correctly taken into account for projections

    For all solvers this tests that the output has the correct shape depending
    on the selected number of components.
    r   r   r   ©r    r!   r"   )r)   r   r   ©r@   r'   r   N)	r   r*   r+   r,   r   r/   r0   r3   r   )r5   r6   r7   r'   Ścr9   r3   r   r   r   Śtest_kernel_pca_n_components·   s    

r^   c                  C   s   t  ddgddgddgg”} t }| | ”}|jdks:ttdd}| | ”}|jdks\ttddd}| | ”}|jdkstd	S )
zĄCheck that the ``remove_zero_eig`` parameter works correctly.

    Tests that the null-space (Zero) eigenvalues are removed when
    remove_zero_eig=True, whereas they are not by default.
    ē      š?r)   )rX   r   r   ©r@   )rX   r   T)r@   Śremove_zero_eigN)r   Śarrayr   r.   r3   r   )rL   r9   ZXtr   r   r   Śtest_remove_zero_eigÉ   s    



rc   c               
   C   s   t  ddgddgg”} t ” h t dt” t jddD tdddd	}| | ” 	| ”}| 
| ”}tt  |”t  |” W 5 Q R X W 5 Q R X d
S )z¹Non-regression test for issue #12141 (PR #12143)

    This test checks that fit().transform() returns the same result as
    fit_transform() in case of non-removed zero eigenvalue.
    r)   r   ŚerrorŚwarn)Śallr   Fr    )r@   ra   r'   N)r   rb   ŚwarningsŚcatch_warningsŚsimplefilterŚRuntimeWarningZerrstater   r/   r0   r.   r   r1   )r6   ŚkŚAŚBr   r   r   Śtest_leave_zero_eigß   s    

rn   c                  C   sō   t j d”} |  d”}|  d”}dD ]Ź}td|dd |” |”}td|ddd t  ||j”” t  ||j””}td|ddd 	t  ||j””}td|ddd t  ||j”” t  ||j””}t
t  |”t  |” t
t  |”t  |” q$d	S )
z?Test that kPCA works with a precomputed kernel, for all solversr   r   r   r[   r   ©r'   rH   r?   )r'   r&   rH   N)r   r*   r+   r,   r   r/   r0   ŚdotŚTr.   r   r1   )r5   r6   r7   r'   ŚX_kpcaZX_kpca2ZX_kpca_trainZX_kpca_train2r   r   r   Śtest_kernel_pca_precomputedų   sT    

’ž’   ’żü’   ’ž   ’żü’rs   c                 C   st   ddgddgg}t d| ddd}| |” dd	gd	dgg}t d| ddd}| |” t|j|j t|j|j d
S )zŖCheck that the kernel centerer works.

    Tests that a non symmetric precomputed kernel is actually accepted
    because the kernel centerer does its job correctly.
    r)   r   rX   é(   r?   r   )r&   r'   r@   rH   é	   i÷’’’N)r   r/   r   Zeigenvectors_Śeigenvalues_)rR   ŚKr9   ZKcZkpca_cr   r   r   Ś)test_kernel_pca_precomputed_non_symmetric  s$    	   ’
   ’
rx   c                  C   s|   t ddddd\} }tddd}td	|fd
tddfg}tdt dd” d}t|d|d}| | |” |j	dksxt
dS )z©Check that kPCA works as expected in a grid search pipeline

    Test if we can do a grid-search to find parameters to separate
    circles with a perceptron model.
    é  ē333333Ó?ē©?r   ©Ś	n_samplesZfactorZnoiserH   r$   r   ©r&   r@   Ś
kernel_pcar   r   ©Zmax_iterē       @éž’’’)Zkernel_pca__gammarX   ©ZcvŚ
param_gridr)   N)r   r   r   r   Śdictr   Śaranger
   r/   Śbest_score_r   )rL   r   r9   Śpipeliner   Śgrid_searchr   r   r   Śtest_gridsearch_pipeline9  s    r   c                  C   s   t ddddd\} }tddd}td	|fd
tddfg}tt dd”d}t|d|d}t| dd}| 	||” |j
dkstdS )zŅCheck that kPCA works as expected in a grid search pipeline (2)

    Test if we can do a grid-search to find parameters to separate
    circles with a perceptron model. This test uses a precomputed kernel.
    ry   rz   r{   r   r|   r?   r   r~   r   r   r   r   r)   )ZPerceptron__max_iterrX   r   r   )ŚgammaN)r   r   r   r   r   r   r   r
   r	   r/   r   r   )rL   r   r9   r   r   r   ZX_kernelr   r   r   Ś$test_gridsearch_pipeline_precomputedH  s    r   c                  C   s~   t ddddd\} }tdd | |” | |”}|dk s:ttd	d
ddd}| | ”}tdd ||” ||”}|dksztdS )a  Check that kPCA projects in a space where nested circles are separable

    Tests that 2D nested circles become separable with a perceptron when
    projected in the first 2 kPCA using an RBF kernel, while raw samples
    are not directly separable in the original space.
    ry   rz   r{   r   r|   r   r   gé?r$   r   Tr   )r&   r@   r(   r   r_   N)r   r   r/   Zscorer   r   r.   )rL   r   Ztrain_scorer9   rr   r   r   r   Śtest_nested_circlesX  s       ’
r   c                  C   s^   ddgddgddgg} t dddd	}| | ” |j ” dks@tt |jt|jk”sZtd
S )z}Check that ``_check_psd_eigenvalues`` is correctly called in kPCA

    Non-regression test for issue #12140 (PR #12145).
    r   r)   gwĢ«   @g:0āyE>r   r#   r   T)r&   r@   r(   N)r   r/   rv   Śminr   r   rf   r   ©rL   r9   r   r   r   Śtest_kernel_conditioningt  s
    
r   c                 C   s  ddddddddgdddd	d	d	d
dgddddddddgdd	ddddddgdd	ddddddgdd	ddddddgdd
ddddddgddddddddgg}t d| dd}tjtdd | |” W 5 Q R X t d| dd}| dkrtjtdd | |” W 5 Q R X n
| |” dS )aŅ  Check how KernelPCA works with non-PSD kernels depending on n_components

    Tests for all methods what happens with a non PSD gram matrix (this
    can happen in an isomap scenario, or with custom kernel functions, or
    maybe with ill-posed datasets).

    When ``n_component`` is large enough to capture a negative eigenvalue, an
    error should be raised. Otherwise, KernelPCA should run without error
    since the negative eigenvalues are not selected.
    gģQøė@g      šæg¤p=
×# @g¤p=
×£@g
×£p=
ĄgĀõ(\)ĄgģQøėĄg      @g×£p=
×óægģQøėéægö(\Āõ@gö(\Āõ.@gøėQø @g333333&Ąg{®Gį:7Ąg      @g333333ĄgRøėQš?gĶĢĢĢĢĢģægq=
×£p@g     #@gö(\Āu5@r?   é   )r&   r'   r@   z*There are significant negative eigenvaluesrA   r   r"   N)r   rC   rD   rE   r/   )rR   rw   r9   r   r   r   Śtest_precomputed_kernel_not_psd  s(    ų
 ’r   r@   rN   c           
      C   sČ   d\}}t || dddd\}}|d|ddf ||dddf  }}t| ddd |” |”}t| d	dd |” |”}tt |”t |” t| d
dd |” |”}	tt |	”t |” dS )zGCheck that 'dense' 'arpack' & 'randomized' solvers give similar results)ič  éd   rz   r{   r   r|   Nr    ro   r!   r"   )r   r   r/   r0   r   r   r1   )
r@   Zn_trainZn_testrL   Ś_r6   r7   Zref_predZa_predZr_predr   r   r   Ś#test_kernel_pca_solvers_equivalenceø  s8       ’
*’ž’’ž’’ž’r   c                  C   s^   t dddd^} }tddddd	}| | ”}| |”}tj | | ”tj | ” d
k sZtdS )zōTest if the reconstruction is a good approximation.

    Note that in general it is not possible to get an arbitrarily good
    reconstruction because of kernel centering that does not
    preserve all the information of the original data.
    r   r   r   ©r}   rW   rH   rN   r$   Tgü©ńŅMbP?)r@   r&   r(   Śalphaē¹?N)r   r   r.   r4   r   ZlinalgZnormr   )rL   r   r9   ZX_transZ	X_reconstr   r   r   Ś0test_kernel_pca_inverse_transform_reconstructionŻ  s       ’

r   c               	   C   sH   t j d” dd”} t }| | ” t t” | 	| ” W 5 Q R X d S )Né   r   rX   )
r   r*   rF   rQ   r   r/   rC   rD   r   r4   r   r   r   r   Ś&test_kernel_pca_raise_not_fitted_errorī  s
    
r   c                  C   sj   t ddddgdddggddd\} }t  | ”} | |  ” 8 } t }| | ”j| |  tj””jksft	dS )zTest that the decomposition is similar for 32 and 64 bits data

    Non regression test for
    https://github.com/scikit-learn/scikit-learn/issues/18146
    é   r   r)   r   )r}   ZcentersrH   Zcluster_stdN)
r   r   r.   r   r   r3   Zastyper   Zfloat32r   )rL   r   r9   r   r   r   Śtest_32_64_decomposition_shapeö  s       ’
r   c                  C   sF   t dddd^} }tdd | ”}| ” }tdd tdD | d	S )
z&Check feature names out for KernelPCA.r   r   r   r   r   r`   c                 S   s   g | ]}d | qS )Z	kernelpcar   )Ś.0rS   r   r   r   Ś
<listcomp>  s     z5test_kernel_pca_feature_names_out.<locals>.<listcomp>N)r   r   r/   Zget_feature_names_outr   rP   )rL   r   r9   Śnamesr   r   r   Ś!test_kernel_pca_feature_names_out  s    r”   c                  C   s¬   t j d”} |  d”}d| ddd}d|jd  }tf dd	i| |”}tf d|i| |”}|j|kspt|j|ks~t| 	| 
|””}| 	| 
|””}t|| d	S )
z]Check that gamma is set correctly when not provided.

    Non-regression test for #26280
    r   r   r   Tr$   )r@   rH   r(   r&   r)   r   N)r   r*   r+   r,   r3   r   r/   Zgamma_r   r4   r0   r   )r5   rL   r   Zexpected_gammaZkpca1Zkpca2ZX1_reconZX2_reconr   r   r   Ś%test_kernel_pca_inverse_correct_gamma  s    
ür¢   c               	   C   sH   t  d” tddd\} }tjdd tddd | ” W 5 Q R X dS )	z©Check that KernelPCA works with pandas output when the solver is arpack.

    Non-regression test for:
    https://github.com/scikit-learn/scikit-learn/issues/27579
    ZpandasT)Zas_frameZ
return_X_y)Ztransform_outputr   r!   r\   N)rC   Zimportorskipr   ŚsklearnZconfig_contextr   r.   )rL   r   r   r   r   Śtest_kernel_pca_pandas_output,  s    
r¤   ):rg   Znumpyr   rC   Zscipy.sparseŚsparserU   r£   Zsklearn.datasetsr   r   r   Zsklearn.decompositionr   r   Zsklearn.exceptionsr   Zsklearn.linear_modelr   Zsklearn.metrics.pairwiser	   Zsklearn.model_selectionr
   Zsklearn.pipeliner   Zsklearn.preprocessingr   Zsklearn.utils._testingr   r   r   Zsklearn.utils.validationr   r=   rG   rM   rT   rV   ŚmarkZparametrizerZ   r^   rc   rn   rs   rx   r   r   r   r   r   r   r   r   r   r”   r¢   r¤   r   r   r   r   Ś<module>   sT   .%&

3
$	