ó
‡ˆ\c           @   s>  d  d l  m Z d  d l 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 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 „  Z d „  Z d e f d „  ƒ  YZ  d e f d „  ƒ  YZ! d e e e f d „  ƒ  YZ" d S(   iÿÿÿÿ(   t   divisionN(   t   sparse(   t   sqrti   (   t   euclidean_distances(   t   TransformerMixint   ClusterMixint   BaseEstimator(   t   xrange(   t   check_array(   t	   row_normst   safe_sparse_dot(   t   check_is_fitted(   t   NotFittedErrort   ConvergenceWarningi   (   t   AgglomerativeClusteringc   
      c   s•   |  j  d } |  j } |  j } |  j } xf t | ƒ D]X } t j |  j  d ƒ } | | | | d } } | | | !}	 | | | !| |	 <| Vq5 Wd S(   s£   This little hack returns a densified row when iterating over a sparse
    matrix, instead of constructing a sparse matrix for every row that is
    expensive.
    i    i   N(   t   shapet   indicest   datat   indptrR   t   npt   zeros(
   t   Xt	   n_samplest	   X_indicest   X_datat   X_indptrt   it   rowt   startptrt   endptrt   nonzero_indices(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyt   _iterate_sparse_X   s    			c         C   s«  t  ƒ  } t  ƒ  } t | | d |  j d |  j ƒ} t | | d |  j d |  j ƒ} | | _ | | _ |  j rØ |  j d k	 r | |  j _ n  |  j | _ | | _ | | _ |  j | _ |  j d k	 rØ | |  j _ qØ n  t |  j	 d |  j
 d t ƒ} | j d } t j | j ƒ  | | f ƒ }	 | |	 f \ }
 } |
 | k  } x^ t |  j ƒ D]M \ } } | | rƒ| j | ƒ | j | ƒ qP| j | ƒ | j | ƒ qPW| | f S(   s¾  The node has to be split if there is no place for a new subcluster
    in the node.
    1. Two empty nodes and two empty subclusters are initialized.
    2. The pair of distant subclusters are found.
    3. The properties of the empty subclusters and nodes are updated
       according to the nearest distance between the subclusters to the
       pair of distant subclusters.
    4. The two nodes are set as children to the two subclusters.
    t   is_leaft
   n_featurest   Y_norm_squaredt   squaredi    N(   t   _CFSubclustert   _CFNodeR    R!   t   child_t
   prev_leaf_t   Nonet
   next_leaf_R   t
   centroids_t   squared_norm_t   TrueR   R   t   unravel_indext   argmaxt	   enumeratet   subclusters_t   append_subclustert   update(   t   nodet	   thresholdt   branching_factort   new_subcluster1t   new_subcluster2t	   new_node1t	   new_node2t   distt
   n_clusterst   farthest_idxt
   node1_distt
   node2_distt   node1_closert   idxt
   subcluster(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyt   _split_node(   sB    
							
R%   c           B   s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   s  Each node in a CFTree is called a CFNode.

    The CFNode can have a maximum of branching_factor
    number of CFSubclusters.

    Parameters
    ----------
    threshold : float
        Threshold needed for a new subcluster to enter a CFSubcluster.

    branching_factor : int
        Maximum number of CF subclusters in each node.

    is_leaf : bool
        We need to know if the CFNode is a leaf or not, in order to
        retrieve the final subclusters.

    n_features : int
        The number of features.

    Attributes
    ----------
    subclusters_ : array-like
        list of subclusters for a particular CFNode.

    prev_leaf_ : _CFNode
        prev_leaf. Useful only if is_leaf is True.

    next_leaf_ : _CFNode
        next_leaf. Useful only if is_leaf is True.
        the final subclusters.

    init_centroids_ : ndarray, shape (branching_factor + 1, n_features)
        manipulate ``init_centroids_`` throughout rather than centroids_ since
        the centroids are just a view of the ``init_centroids_`` .

    init_sq_norm_ : ndarray, shape (branching_factor + 1,)
        manipulate init_sq_norm_ throughout. similar to ``init_centroids_``.

    centroids_ : ndarray
        view of ``init_centroids_``.

    squared_norm_ : ndarray
        view of ``init_sq_norm_``.

    c         C   s~   | |  _  | |  _ | |  _ | |  _ g  |  _ t j | d | f ƒ |  _ t j | d ƒ |  _ g  |  _	 d  |  _ d  |  _ d  S(   Ni   (   R4   R5   R    R!   R0   R   R   t   init_centroids_t   init_sq_norm_R+   R(   R'   R)   (   t   selfR4   R5   R    R!   (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyt   __init__‰   s    							c         C   s}   t  |  j ƒ } |  j j | ƒ | j |  j | <| j |  j | <|  j d  | d … d  d  … f |  _ |  j | d  |  _ d  S(   Ni   (	   t   lenR0   t   appendt	   centroid_RC   t   sq_norm_RD   R*   R+   (   RE   RA   R   (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyR1   ˜   s    &c         C   sP   |  j  j | ƒ } | |  j  | <| j |  j | <| j |  j | <|  j | ƒ d S(   sZ   Remove a subcluster from a node and update it with the
        split subclusters.
        N(   R0   t   indexRI   RC   RJ   RD   R1   (   RE   RA   R6   R7   t   ind(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyt   update_split_subclusters¤   s
    c         C   s«  |  j  s |  j | ƒ t S|  j } |  j } t j |  j | j ƒ } | d 9} | |  j	 7} t j
 | ƒ } |  j  | } | j d k	 r.| j j | ƒ } | sÝ | j | ƒ |  j  | j |  j | <|  j  | j |  j | <t St | j | | ƒ \ } }	 |  j | | |	 ƒ t |  j  ƒ |  j k r't St Sny | j | |  j ƒ }
 |
 rm| j |  j | <| j |  j | <t St |  j  ƒ |  j k  r–|  j | ƒ t S|  j | ƒ t Sd S(   s&   Insert a new subcluster into the node.g       ÀN(   R0   R1   t   FalseR4   R5   R   t   dotR*   RI   R+   t   argminR&   R(   t   insert_cf_subclusterR2   RC   RJ   RD   RB   RM   RG   R,   t   merge_subcluster(   RE   RA   R4   R5   t   dist_matrixt   closest_indext   closest_subclustert   split_childR6   R7   t   merged(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyRQ   ¯   sH    			
		(   t   __name__t
   __module__t   __doc__RF   R1   RM   RQ   (    (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyR%   Z   s
   .			R$   c           B   s;   e  Z d  Z d d „ Z d „  Z d „  Z e d „  ƒ Z RS(   s7  Each subcluster in a CFNode is called a CFSubcluster.

    A CFSubcluster can have a CFNode has its child.

    Parameters
    ----------
    linear_sum : ndarray, shape (n_features,), optional
        Sample. This is kept optional to allow initialization of empty
        subclusters.

    Attributes
    ----------
    n_samples_ : int
        Number of samples that belong to each subcluster.

    linear_sum_ : ndarray
        Linear sum of all the samples in a subcluster. Prevents holding
        all sample data in memory.

    squared_sum_ : float
        Sum of the squared l2 norms of all samples belonging to a subcluster.

    centroid_ : ndarray
        Centroid of the subcluster. Prevent recomputing of centroids when
        ``CFNode.centroids_`` is called.

    child_ : _CFNode
        Child Node of the subcluster. Once a given _CFNode is set as the child
        of the _CFNode, it is set to ``self.child_``.

    sq_norm_ : ndarray
        Squared norm of the subcluster. Used to prevent recomputing when
        pairwise minimum distances are computed.
    c         C   sr   | d  k r* d |  _ d |  _ d |  _ n; d |  _ | |  _ |  _ t j |  j |  j ƒ |  _ |  _ d  |  _ d  S(   Ni    g        i   (	   R(   t
   n_samples_t   squared_sum_t   linear_sum_RI   R   RO   RJ   R&   (   RE   t
   linear_sum(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyRF     s    			c         C   sh   |  j  | j  7_  |  j | j 7_ |  j | j 7_ |  j |  j  |  _ t j |  j |  j ƒ |  _ d  S(   N(   R[   R]   R\   RI   R   RO   RJ   (   RE   RA   (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyR2   "  s
    c   
      C   s»   |  j  | j  } |  j | j } |  j | j } d | | } t j | | ƒ } d | | } | | | | }	 |	 | d k r· | | | | | f \ |  _ |  _ |  _  |  _ |  _ t St S(   sU   Check if a cluster is worthy enough to be merged. If
        yes then merge.
        i   iþÿÿÿi   (	   R\   R]   R[   R   RO   RI   RJ   R,   RN   (
   RE   t   nominee_clusterR4   t   new_sst   new_lst   new_nt   new_centroidt   new_normt   dot_productt	   sq_radius(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyRR   )  s    3c         C   s;   d t  j |  j |  j ƒ } t |  j | |  j |  j ƒ S(   s   Return radius of the subclusteriþÿÿÿ(   R   RO   R]   RI   R   R\   R[   RJ   (   RE   Re   (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyt   radius;  s    N(	   RX   RY   RZ   R(   RF   R2   RR   t   propertyRg   (    (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyR$   ó   s
   "		t   Birchc           B   sz   e  Z d  Z d d d e e d „ Z d d „ Z d „  Z d „  Z d d d „ Z	 d	 „  Z
 d
 „  Z d „  Z d d „ Z RS(   sf  Implements the Birch clustering algorithm.

    It is a memory-efficient, online-learning algorithm provided as an
    alternative to :class:`MiniBatchKMeans`. It constructs a tree
    data structure with the cluster centroids being read off the leaf.
    These can be either the final cluster centroids or can be provided as input
    to another clustering algorithm such as :class:`AgglomerativeClustering`.

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

    Parameters
    ----------
    threshold : float, default 0.5
        The radius of the subcluster obtained by merging a new sample and the
        closest subcluster should be lesser than the threshold. Otherwise a new
        subcluster is started. Setting this value to be very low promotes
        splitting and vice-versa.

    branching_factor : int, default 50
        Maximum number of CF subclusters in each node. If a new samples enters
        such that the number of subclusters exceed the branching_factor then
        that node is split into two nodes with the subclusters redistributed
        in each. The parent subcluster of that node is removed and two new
        subclusters are added as parents of the 2 split nodes.

    n_clusters : int, instance of sklearn.cluster model, default 3
        Number of clusters after the final clustering step, which treats the
        subclusters from the leaves as new samples.

        - `None` : the final clustering step is not performed and the
          subclusters are returned as they are.

        - `sklearn.cluster` Estimator : If a model is provided, the model is
          fit treating the subclusters as new samples and the initial data is
          mapped to the label of the closest subcluster.

        - `int` : the model fit is :class:`AgglomerativeClustering` with
          `n_clusters` set to be equal to the int.

    compute_labels : bool, default True
        Whether or not to compute labels for each fit.

    copy : bool, default True
        Whether or not to make a copy of the given data. If set to False,
        the initial data will be overwritten.

    Attributes
    ----------
    root_ : _CFNode
        Root of the CFTree.

    dummy_leaf_ : _CFNode
        Start pointer to all the leaves.

    subcluster_centers_ : ndarray,
        Centroids of all subclusters read directly from the leaves.

    subcluster_labels_ : ndarray,
        Labels assigned to the centroids of the subclusters after
        they are clustered globally.

    labels_ : ndarray, shape (n_samples,)
        Array of labels assigned to the input data.
        if partial_fit is used instead of fit, they are assigned to the
        last batch of data.

    Examples
    --------
    >>> from sklearn.cluster import Birch
    >>> X = [[0, 1], [0.3, 1], [-0.3, 1], [0, -1], [0.3, -1], [-0.3, -1]]
    >>> brc = Birch(branching_factor=50, n_clusters=None, threshold=0.5,
    ... compute_labels=True)
    >>> brc.fit(X) # doctest: +NORMALIZE_WHITESPACE
    Birch(branching_factor=50, compute_labels=True, copy=True, n_clusters=None,
       threshold=0.5)
    >>> brc.predict(X)
    array([0, 0, 0, 1, 1, 1])

    References
    ----------
    * Tian Zhang, Raghu Ramakrishnan, Maron Livny
      BIRCH: An efficient data clustering method for large databases.
      http://www.cs.sfu.ca/CourseCentral/459/han/papers/zhang96.pdf

    * Roberto Perdisci
      JBirch - Java implementation of BIRCH clustering algorithm
      https://code.google.com/archive/p/jbirch

    Notes
    -----
    The tree data structure consists of nodes with each node consisting of
    a number of subclusters. The maximum number of subclusters in a node
    is determined by the branching factor. Each subcluster maintains a
    linear sum, squared sum and the number of samples in that subcluster.
    In addition, each subcluster can also have a node as its child, if the
    subcluster is not a member of a leaf node.

    For a new point entering the root, it is merged with the subcluster closest
    to it and the linear sum, squared sum and the number of samples of that
    subcluster are updated. This is done recursively till the properties of
    the leaf node are updated.
    g      à?i2   i   c         C   s1   | |  _  | |  _ | |  _ | |  _ | |  _ d  S(   N(   R4   R5   R;   t   compute_labelst   copy(   RE   R4   R5   R;   Rj   Rk   (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyRF   ¬  s
    				c         C   s    t  t |  _ |  _ |  j | ƒ S(   sÑ   
        Build a CF Tree for the input data.

        Parameters
        ----------
        X : {array-like, sparse matrix}, shape (n_samples, n_features)
            Input data.

        y : Ignored

        (   R,   RN   t   fit_t   partial_fit_t   _fit(   RE   R   t   y(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyt   fit´  s    c         C   sô  t  | d d d |  j ƒ} |  j } |  j } | d k rH t d ƒ ‚ n  | j \ } } t |  d ƒ } t |  d d  ƒ } t |  d ƒ s” | rñ | rñ t | | d	 t	 d
 | ƒ|  _
 t | | d	 t	 d
 | ƒ|  _ |  j
 |  j _ |  j |  j
 _ n  t j | ƒ s	t } n t } x | | ƒ D] }	 t d |	 ƒ }
 |  j
 j |
 ƒ } | rt |  j
 | | ƒ \ } } |  `
 t | | d	 t d
 | ƒ|  _
 |  j
 j | ƒ |  j
 j | ƒ qqWt j g  |  j ƒ  D] } | j ^ qÂƒ } | |  _ |  j | ƒ |  S(   Nt   accept_sparset   csrRk   i   s,   Branching_factor should be greater than one.Rm   t   root_Rl   R    R!   R^   (   R   Rk   R4   R5   t
   ValueErrorR   t   getattrR(   R%   R,   Rs   t   dummy_leaf_R)   R'   R   t   issparset   iterR   R$   RQ   RB   RN   R1   R   t   concatenatet   _get_leavesR*   t   subcluster_centers_t   _global_clustering(   RE   R   R4   R5   R   R!   t   partial_fitt   has_roott	   iter_funct   sampleRA   t   splitR6   R7   t   leaft	   centroids(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyRn   Ã  sF    			%	c         C   s?   |  j  j } g  } x& | d k	 r: | j | ƒ | j } q W| S(   s–   
        Retrieve the leaves of the CF Node.

        Returns
        -------
        leaves : array-like
            List of the leaf nodes.
        N(   Rv   R)   R(   RH   (   RE   t   leaf_ptrt   leaves(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyRz   ö  s    	c         C   sK   t  t |  _ |  _ | d k r- |  j ƒ  |  S|  j | ƒ |  j | ƒ Sd S(   s;  
        Online learning. Prevents rebuilding of CFTree from scratch.

        Parameters
        ----------
        X : {array-like, sparse matrix}, shape (n_samples, n_features), None
            Input data. If X is not provided, only the global clustering
            step is done.

        y : Ignored

        N(   R,   RN   Rm   Rl   R(   R|   t
   _check_fitRn   (   RE   R   Ro   (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyR}     s    
c         C   so   t  |  d ƒ } t  |  d ƒ } | p' | s9 t d ƒ ‚ n  | rk | j d |  j j d k rk t d ƒ ‚ n  d  S(   NR{   Rm   s#   Fit training data before predictingi   sE   Training data and predicted data do not have same number of features.(   t   hasattrR   R   R{   Rt   (   RE   R   t	   is_fittedt   has_partial_fit(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyR†     s    #c         C   se   t  | d d ƒ} |  j | ƒ t | |  j j ƒ } | d 9} | |  j 7} |  j t j | d d ƒS(   sf  
        Predict data using the ``centroids_`` of subclusters.

        Avoid computation of the row norms of X.

        Parameters
        ----------
        X : {array-like, sparse matrix}, shape (n_samples, n_features)
            Input data.

        Returns
        -------
        labels : ndarray, shape(n_samples)
            Labelled data.
        Rq   Rr   iþÿÿÿt   axisi   (	   R   R†   R
   R{   t   Tt   _subcluster_normst   subcluster_labels_R   RP   (   RE   R   t   reduced_distance(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyt   predict+  s    
c         C   s   t  |  d ƒ t | |  j ƒ S(   s¼  
        Transform X into subcluster centroids dimension.

        Each dimension represents the distance from the sample point to each
        cluster centroid.

        Parameters
        ----------
        X : {array-like, sparse matrix}, shape (n_samples, n_features)
            Input data.

        Returns
        -------
        X_trans : {array-like, sparse matrix}, shape (n_samples, n_clusters)
            Transformed data.
        R{   (   R   R   R{   (   RE   R   (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyt	   transformB  s    c         C   s?  |  j  } |  j } | d k	 o$ |  j } t } t | t ƒ ro t d |  j  ƒ } t | ƒ |  j  k  rš t	 } qš n+ | d k	 rš t
 | d ƒ rš t d ƒ ‚ n  t |  j d t	 ƒ|  _ | d k sÄ | rt j t | ƒ ƒ |  _ | r t j d t | ƒ |  j  f t ƒ q n | j |  j ƒ |  _ | r;|  j | ƒ |  _ n  d S(   sN   
        Global clustering for the subclusters obtained after fitting
        R;   t   fit_predicts:   n_clusters should be an instance of ClusterMixin or an intR#   sT   Number of subclusters found (%d) by Birch is less than (%d). Decrease the threshold.N(   R;   R{   R(   Rj   RN   t
   isinstancet   intR   RG   R,   R‡   Rt   R	   RŒ   R   t   arangeR   t   warningst   warnR   R‘   R   t   labels_(   RE   R   t	   clustererRƒ   Rj   t   not_enough_centroids(    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyR|   V  s0    		 N(   RX   RY   RZ   R,   RF   R(   Rp   Rn   Rz   R}   R†   R   R   R|   (    (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyRi   D  s   f		3				(#   t
   __future__R    R•   t   numpyR   t   scipyR   t   mathR   t   metrics.pairwiseR   t   baseR   R   R   t   externals.six.movesR   t   utilsR   t   utils.extmathR	   R
   t   utils.validationR   t
   exceptionsR   R   t   hierarchicalR   R   RB   t   objectR%   R$   Ri   (    (    (    s4   lib/python2.7/site-packages/sklearn/cluster/birch.pyt   <module>   s"   		2™Q