B
    	\-                 @   s   d Z ddlZddlmZ ddlmZ ddlmZ ddl	m
Z
mZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ G dd deeZdS )z$Kernel Principal Components Analysis    N)linalg)eigsh   )check_random_state)check_is_fittedcheck_array)NotFittedError)BaseEstimatorTransformerMixin)KernelCenterer)pairwise_kernelsc               @   sd   e Zd ZdZdddZedd ZdddZdd Zdd Z	dddZ
d ddZdd Zdd ZdS )!	KernelPCAa  Kernel Principal component analysis (KPCA)

    Non-linear dimensionality reduction through the use of kernels (see
    :ref:`metrics`).

    Read more in the :ref:`User Guide <kernel_PCA>`.

    Parameters
    ----------
    n_components : int, default=None
        Number of components. If None, all non-zero components are kept.

    kernel : "linear" | "poly" | "rbf" | "sigmoid" | "cosine" | "precomputed"
        Kernel. Default="linear".

    gamma : float, default=1/n_features
        Kernel coefficient for rbf, poly and sigmoid kernels. Ignored by other
        kernels.

    degree : int, default=3
        Degree for poly kernels. Ignored by other kernels.

    coef0 : float, default=1
        Independent term in poly and sigmoid kernels.
        Ignored by other kernels.

    kernel_params : mapping of string to any, default=None
        Parameters (keyword arguments) and values for kernel passed as
        callable object. Ignored by other kernels.

    alpha : int, default=1.0
        Hyperparameter of the ridge regression that learns the
        inverse transform (when fit_inverse_transform=True).

    fit_inverse_transform : bool, default=False
        Learn the inverse transform for non-precomputed kernels.
        (i.e. learn to find the pre-image of a point)

    eigen_solver : string ['auto'|'dense'|'arpack'], default='auto'
        Select eigensolver to use. If n_components is much less than
        the number of training samples, arpack may be more efficient
        than the dense eigensolver.

    tol : float, default=0
        Convergence tolerance for arpack.
        If 0, optimal value will be chosen by arpack.

    max_iter : int, default=None
        Maximum number of iterations for arpack.
        If None, optimal value will be chosen by arpack.

    remove_zero_eig : boolean, default=False
        If True, then all components with zero eigenvalues are removed, so
        that the number of components in the output may be < n_components
        (and sometimes even zero due to numerical instability).
        When n_components is None, this parameter is ignored and components
        with zero eigenvalues are removed regardless.

    random_state : int, RandomState instance or None, optional (default=None)
        If int, random_state is the seed used by the random number generator;
        If RandomState instance, random_state is the random number generator;
        If None, the random number generator is the RandomState instance used
        by `np.random`. Used when ``eigen_solver`` == 'arpack'.

        .. versionadded:: 0.18

    copy_X : boolean, default=True
        If True, input X is copied and stored by the model in the `X_fit_`
        attribute. If no further changes will be done to X, setting
        `copy_X=False` saves memory by storing a reference.

        .. versionadded:: 0.18

    n_jobs : int or None, optional (default=None)
        The number of parallel jobs to run.
        ``None`` means 1 unless in a :obj:`joblib.parallel_backend` context.
        ``-1`` means using all processors. See :term:`Glossary <n_jobs>`
        for more details.

        .. versionadded:: 0.18

    Attributes
    ----------
    lambdas_ : array, (n_components,)
        Eigenvalues of the centered kernel matrix in decreasing order.
        If `n_components` and `remove_zero_eig` are not set,
        then all values are stored.

    alphas_ : array, (n_samples, n_components)
        Eigenvectors of the centered kernel matrix. If `n_components` and
        `remove_zero_eig` are not set, then all components are stored.

    dual_coef_ : array, (n_samples, n_features)
        Inverse transform matrix. Only available when
        ``fit_inverse_transform`` is True.

    X_transformed_fit_ : array, (n_samples, n_components)
        Projection of the fitted data on the kernel principal components.
        Only available when ``fit_inverse_transform`` is True.

    X_fit_ : (n_samples, n_features)
        The data used to fit the model. If `copy_X=False`, then `X_fit_` is
        a reference. This attribute is used for the calls to transform.

    Examples
    --------
    >>> from sklearn.datasets import load_digits
    >>> from sklearn.decomposition import KernelPCA
    >>> X, _ = load_digits(return_X_y=True)
    >>> transformer = KernelPCA(n_components=7, kernel='linear')
    >>> X_transformed = transformer.fit_transform(X)
    >>> X_transformed.shape
    (1797, 7)

    References
    ----------
    Kernel PCA was introduced in:
        Bernhard Schoelkopf, Alexander J. Smola,
        and Klaus-Robert Mueller. 1999. Kernel principal
        component analysis. In Advances in kernel methods,
        MIT Press, Cambridge, MA, USA 327-352.
    Nlinear            ?Fautor   Tc             C   sr   |r|dkrt d|| _|| _|| _|| _|| _|| _|| _|| _|	| _	|| _
|
| _|| _|| _|| _|| _d S )Nprecomputedz7Cannot fit_inverse_transform with a precomputed kernel.)
ValueErrorn_componentskernelkernel_paramsgammadegreecoef0alphafit_inverse_transformeigen_solverremove_zero_eigtolmax_iterrandom_staten_jobscopy_X)selfr   r   r   r   r   r   r   r   r   r   r    r   r!   r#   r"    r%   ?lib/python3.7/site-packages/sklearn/decomposition/kernel_pca.py__init__   s$    zKernelPCA.__init__c             C   s
   | j dkS )Nr   )r   )r$   r%   r%   r&   	_pairwise   s    zKernelPCA._pairwisec             C   sF   t | jr| jpi }n| j| j| jd}t||f| jd| jd|S )N)r   r   r   T)ZmetricZfilter_paramsr"   )callabler   r   r   r   r   r   r"   )r$   XYparamsr%   r%   r&   _get_kernel   s    


zKernelPCA._get_kernelc             C   s\  | j |}| jdkr"|jd }nt|jd | j}| jdkr`|jd dkrZ|dk rZd}qfd}n| j}|dkrtj||jd | |jd d fd	\| _| _	nF|dkrt
| j}|d
d|jd }t||d| j| j|d\| _| _	| j ddd
 }| j| | _| j	dd|f | _	| js,| jdkrX| j	dd| jdkf | _	| j| jdk | _|S )z Fit's using kernel KNr   r      
   ZarpackZdenser   )ZeigvalsZLA)Zwhichr   maxiterv0)	_centererfit_transformr   shapeminr   r   Zeighlambdas_alphas_r   r!   Zuniformr   r   r    Zargsortr   )r$   Kr   r   r!   r2   indicesr%   r%   r&   _fit_transform   s6    

,
zKernelPCA._fit_transformc             C   sb   t |drtd|jd }| |}|jd d |d   | j7  < tj||ddd| _|| _	d S )NZtocsrz6Inverse transform not implemented for sparse matrices!r   r   T)Zsym_posZoverwrite_a)
hasattrNotImplementedErrorr5   r-   Zflatr   r   Zsolve
dual_coef_X_transformed_fit_)r$   X_transformedr*   Z	n_samplesr9   r%   r%   r&   _fit_inverse_transform   s    


z KernelPCA._fit_inverse_transformc             C   sh   t |d| jd}t | _| |}| | | jr^tt	| j
}t| j|}| || || _| S )a_  Fit the model from data in X.

        Parameters
        ----------
        X : array-like, shape (n_samples, n_features)
            Training vector, where n_samples in the number of samples
            and n_features is the number of features.

        Returns
        -------
        self : object
            Returns the instance itself.
        Zcsr)Zaccept_sparsecopy)r   r#   r   r3   r-   r;   r   npZdiagsqrtr7   dotr8   rA   X_fit_)r$   r*   yr9   Zsqrt_lambdasr@   r%   r%   r&   fit   s    

zKernelPCA.fitc             K   s6   | j |f| | jt| j }| jr2| || |S )al  Fit the model from data in X and transform X.

        Parameters
        ----------
        X : array-like, shape (n_samples, n_features)
            Training vector, where n_samples in the number of samples
            and n_features is the number of features.

        Returns
        -------
        X_new : array-like, shape (n_samples, n_components)
        )rH   r8   rC   rD   r7   r   rA   )r$   r*   rG   r,   r@   r%   r%   r&   r4     s
    zKernelPCA.fit_transformc             C   s:   t | d | j| || j}t|| jt| j	 S )zTransform X.

        Parameters
        ----------
        X : array-like, shape (n_samples, n_features)

        Returns
        -------
        X_new : array-like, shape (n_samples, n_components)
        rF   )
r   r3   	transformr-   rF   rC   rE   r8   rD   r7   )r$   r*   r9   r%   r%   r&   rI     s    
zKernelPCA.transformc             C   s*   | j std| || j}t|| jS )aI  Transform X back to original space.

        Parameters
        ----------
        X : array-like, shape (n_samples, n_components)

        Returns
        -------
        X_new : array-like, shape (n_samples, n_features)

        References
        ----------
        "Learning to Find Pre-Images", G BakIr et al, 2004.
        z|The fit_inverse_transform parameter was not set to True when instantiating and hence the inverse transform is not available.)r   r   r-   r?   rC   rE   r>   )r$   r*   r9   r%   r%   r&   inverse_transform-  s    zKernelPCA.inverse_transform)Nr   Nr   r   Nr   Fr   r   NFNTN)N)N)N)__name__
__module____qualname____doc__r'   propertyr(   r-   r;   rA   rH   r4   rI   rJ   r%   r%   r%   r&   r      s   z    

,

r   )rN   ZnumpyrC   Zscipyr   Zscipy.sparse.linalgr   Zutilsr   Zutils.validationr   r   
exceptionsr   baser	   r
   Zpreprocessingr   Zmetrics.pairwiser   r   r%   r%   r%   r&   <module>   s   