
    0Ph/h                     (   d dl Z d dlmZ d dlmZmZ d dlZd dlm	Z	 ddl
mZ ddlmZmZmZ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 ddlmZm Z  ddl!m"Z" d Z#d Z$ G d d          Z% G d d          Z& G d deeee          Z'dS )    N)sqrt)IntegralReal)sparse   )config_context)BaseEstimatorClassNamePrefixFeaturesOutMixinClusterMixinTransformerMixin_fit_context)ConvergenceWarning)pairwise_distances_argmin)euclidean_distances)HiddenInterval
StrOptions)	row_norms)check_is_fittedvalidate_data   )AgglomerativeClusteringc              #     K   | j         d         }| j        }| j        }| j        }t	          |          D ]O}t          j        | j         d                   }||         ||dz            }}|||         }	|||         ||	<   |V  PdS )zThis little hack returns a densified row when iterating over a sparse
    matrix, instead of constructing a sparse matrix for every row that is
    expensive.
    r   r   N)shapeindicesdataindptrrangenpzeros)
X	n_samples	X_indicesX_dataX_indptrirowstartptrendptrnonzero_indicess
             V/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/sklearn/cluster/_birch.py_iterate_sparse_Xr,      s      
 
I	IVFxH9  hqwqz""#A;Q&#HVO4%hvo6O				     c                 p   t                      }t                      }t          ||| j        | j        | j        j                  }t          ||| j        | j        | j        j                  }||_        ||_        | j        rL| j        || j        _        | j        |_        ||_        ||_        | j        |_        | j        || j        _        t          | j
        | j        d          }|j        d         }t          j        |                                ||f          }	||	f         \  }
}|
|k     }d||	d         <   t!          | j                  D ]b\  }}||         r+|                    |           |                    |           8|                    |           |                    |           c||fS )a  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.
    	thresholdbranching_factoris_leaf
n_featuresdtypeNT)Y_norm_squaredsquaredr   )_CFSubcluster_CFNoder2   r3   init_centroids_r4   child_
prev_leaf_
next_leaf_r   
centroids_squared_norm_r   r   unravel_indexargmax	enumeratesubclusters_append_subclusterupdate)noder0   r1   new_subcluster1new_subcluster2	new_node1	new_node2dist
n_clustersfarthest_idx
node1_dist
node2_distnode1_closeridx
subclusters                  r+   _split_noderR   .   s    $ooO#ooO)?"(  I )?"(  I 'O&O| 3?&)2DO&#	(	(	#	?&)2DO&(:D  D AJ#DKKMMJ
3KLLL!</2J

*L %)La!$T%677 / /Z 	/''
333"":....''
333"":....O++r-   c                   *    e Zd ZdZd Zd Zd Zd ZdS )r8   aV  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_ : list
        List of subclusters for a particular CFNode.

    prev_leaf_ : _CFNode
        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 of 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 of shape (branching_factor + 1,)
        manipulate init_sq_norm_ throughout. similar to ``init_centroids_``.

    centroids_ : ndarray of shape (branching_factor + 1, n_features)
        View of ``init_centroids_``.

    squared_norm_ : ndarray of shape (branching_factor + 1,)
        View of ``init_sq_norm_``.

    c                    || _         || _        || _        || _        g | _        t          j        |dz   |f|          | _        t          j        |dz   |          | _        g | _	        d | _
        d | _        d S )Nr   )r4   )r0   r1   r2   r3   rB   r   r    r9   init_sq_norm_r>   r;   r<   )selfr0   r1   r2   r3   r4   s         r+   __init__z_CFNode.__init__   s    " 0$ !x)9A)=z(JRWXXXX'7!';eDDr-   c                    t          | j                  }| j                            |           |j        | j        |<   |j        | j        |<   | j        d |dz   d d f         | _        | j        d |dz            | _        d S )Nr   )	lenrB   append	centroid_r9   sq_norm_rU   r=   r>   )rV   rQ   r"   s      r+   rC   z_CFNode.append_subcluster   s    )**	  ,,,*4*>Y'(2(;9%
 .Q/AB!/)a-@r-   c                     | j                             |          }|| j         |<   |j        | j        |<   |j        | j        |<   |                     |           dS )zZRemove a subcluster from a node and update it with the
        split subclusters.
        N)rB   indexr[   r9   r\   rU   rC   )rV   rQ   rF   rG   inds        r+   update_split_subclustersz _CFNode.update_split_subclusters   sa     %%j11!0#$3$=S!"1":3/////r-   c                    | j         s|                     |           dS | j        }| j        }t	          j        | j        |j                  }|dz  }|| j        z  }t	          j	        |          }| j         |         }|j
        |j
                            |          }|sK|                    |           | j         |         j        | j        |<   | j         |         j        | j        |<   dS t!          |j
        ||          \  }}	|                     |||	           t%          | j                   | j        k    rdS dS |                    || j                  }
|
r |j        | j        |<   |j        | j        |<   dS t%          | j                   | j        k     r|                     |           dS |                     |           dS )z&Insert a new subcluster into the node.Fg       NT)rB   rC   r0   r1   r   dotr=   r[   r>   argminr:   insert_cf_subclusterrD   r9   r\   rU   rR   r`   rY   merge_subcluster)rV   rQ   r0   r1   dist_matrixclosest_indexclosest_subclustersplit_childrF   rG   mergeds              r+   rd   z_CFNode.insert_cf_subcluster   s     	"":...5N	0 fT_j.BCCtt))	+..!.}= $0,3HHTTK  #))*5556:6G!7 $]3 594E!5 "=1 u 4?&-$4 40
 --&   t())D,AAA4u (88T^TTF 6H6R$]34F4O"=1u T&''$*???&&z222u
 &&z222tr-   N)__name__
__module____qualname____doc__rW   rC   r`   rd    r-   r+   r8   r8   m   sc        - -^  
A 
A 
A0 0 0C C C C Cr-   r8   c                   @    e Zd ZdZdddZd Zd Zed             ZdS )r7   a  Each subcluster in a CFNode is called a CFSubcluster.

    A CFSubcluster can have a CFNode has its child.

    Parameters
    ----------
    linear_sum : ndarray of shape (n_features,), default=None
        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 of shape (branching_factor + 1, n_features)
        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 of shape (branching_factor + 1,)
        Squared norm of the subcluster. Used to prevent recomputing when
        pairwise minimum distances are computed.
    N
linear_sumc                    |d| _         d| _        dx| _        | _        n@d| _         |x| _        | _        t	          j        | j        | j                  x| _        | _        d | _        d S )Nr           r   )
n_samples_squared_sum_r[   linear_sum_r   rb   r\   r:   )rV   rr   s     r+   rW   z_CFSubcluster.__init__,  st    DO #D011DNT--DO0::DNT-02 $"21 1 D r-   c                     | xj         |j         z  c_         | xj        |j        z  c_        | xj        |j        z  c_        | j        | j         z  | _        t	          j        | j        | j                  | _        d S N)ru   rw   rv   r[   r   rb   r\   )rV   rQ   s     r+   rD   z_CFSubcluster.update9  so    :00J22Z44)DO;t~t~>>r-   c                    | j         |j         z   }| j        |j        z   }| j        |j        z   }d|z  |z  }t          j        ||          }||z  |z
  }||dz  k    r(|||||f\  | _        | _        | _         | _        | _        dS dS )zUCheck if a cluster is worthy enough to be merged. If
        yes then merge.
        r   r   TF)rv   rw   ru   r   rb   r[   r\   )	rV   nominee_clusterr0   new_ssnew_lsnew_nnew_centroidnew_sq_norm	sq_radiuss	            r+   re   z_CFSubcluster.merge_subcluster@  s     "_%AA!O$??/"<<E	V+f\<88 UN[0		1$$ kB !4ur-   c                 j    | j         | j        z  | j        z
  }t          t	          d|                    S )zReturn radius of the subclusterr   )rv   ru   r\   r   max)rV   r   s     r+   radiusz_CFSubcluster.radius_  s2     %7$-G	C9%%&&&r-   )	rk   rl   rm   rn   rW   rD   re   propertyr   ro   r-   r+   r7   r7     sv        ! !F &*     ? ? ?  > ' ' X' ' 'r-   r7   c            
       T    e Zd ZU dZ eeddd          g eeddd          gde eeddd          gdgd e e	d	h                    gd
Z
eed<   ddddd	d
dZ ed          dd            Zd Zd Z ed          dd            Zd Zd Zd ZddZ fdZ xZS )Bircha$  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>`.

    .. versionadded:: 0.16

    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 or None, 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.

        - :mod:`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.

        .. deprecated:: 1.6
            `copy` was deprecated in 1.6 and will be removed in 1.8. It has no effect
            as the estimator does not perform in-place operations on the input data.

    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 of 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.

    n_features_in_ : int
        Number of features seen during :term:`fit`.

        .. versionadded:: 0.24

    feature_names_in_ : ndarray of shape (`n_features_in_`,)
        Names of features seen during :term:`fit`. Defined only when `X`
        has feature names that are all strings.

        .. versionadded:: 1.0

    See Also
    --------
    MiniBatchKMeans : Alternative implementation that does incremental updates
        of the centers' positions using mini-batches.

    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.

    See :ref:`sphx_glr_auto_examples_cluster_plot_birch_vs_minibatchkmeans.py` for a
    comparison with :class:`~sklearn.cluster.MiniBatchKMeans`.

    References
    ----------
    * Tian Zhang, Raghu Ramakrishnan, Maron Livny
      BIRCH: An efficient data clustering method for large databases.
      https://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

    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(n_clusters=None)
    >>> brc.fit(X)
    Birch(n_clusters=None)
    >>> brc.predict(X)
    array([0, 0, 0, 1, 1, 1])
    rt   Nneither)closedr   leftboolean
deprecatedr0   r1   rK   compute_labelscopy_parameter_constraintsg      ?2      Tc                L    || _         || _        || _        || _        || _        d S ry   r   )rV   r0   r1   rK   r   r   s         r+   rW   zBirch.__init__  s-     # 0$,			r-   )prefer_skip_nested_validationc                 0    |                      |d          S )ad  
        Build a CF Tree for the input data.

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

        y : Ignored
            Not used, present here for API consistency by convention.

        Returns
        -------
        self
            Fitted estimator.
        Fpartial)_fitrV   r!   ys      r+   fitz	Birch.fit  s    $ yyEy***r-   c                    t          | dd           }|o| }| j        dk    r|rt          j        dt                     t          | |d|t          j        t          j        g          }| j	        }| j
        }|j        \  }}|r^t          ||d||j                  | _        t          ||d||j                  | _        | j        | j        _        | j        | j        _        t%          j        |          st(          }	nt*          }	 |	|          D ]}
t-          |
          }| j                            |          }|rmt1          | j        ||          \  }}| `t          ||d	||j                  | _        | j                            |           | j                            |           t          j        d
 |                                 D                       }|| _        | j        j        d         | _        |                     |           | S )Nroot_r   z`copy` was deprecated in 1.6 and will be removed in 1.8 since it has no effect internally. Simply leave this parameter to its default value to avoid this warning.csr)accept_sparseresetr4   Tr/   rq   Fc                     g | ]	}|j         
S ro   )r=   ).0leafs     r+   
<listcomp>zBirch._fit.<locals>.<listcomp>[  s    #S#S#SDO#S#S#Sr-   r   )getattrr   warningswarnFutureWarningr   r   float64float32r0   r1   r   r8   r4   r   dummy_leaf_r<   r;   r   issparseiterr,   r7   rd   rR   rC   concatenate_get_leavessubcluster_centers__n_features_out_global_clustering)rV   r!   r   has_root
first_callr0   r1   r"   r3   	iter_funcsamplerQ   splitrF   rG   	centroidss                   r+   r   z
Birch._fit  sP   4$//!.h/
9$$$M/ 	   :rz*
 
 
 N	0 !	:  	5 #!1%g  DJ  '#!1%g     D +/*D'$($4DJ! q!! 	*II)Iill 	> 	>F&&999JJ33J??E >3>J	+;4 40 J$'%5!)'  
 
,,_===
,,_===N#S#S@P@P@R@R#S#S#STT	#, #7=a@"""r-   c                 b    | j         j        }g }||                    |           |j        }||S )z
        Retrieve the leaves of the CF Node.

        Returns
        -------
        leaves : list of shape (n_leaves,)
            List of the leaf nodes.
        )r   r<   rZ   )rV   leaf_ptrleavess      r+   r   zBirch._get_leavesb  sC     #."MM(###*H " r-   c                 `    ||                                   | S |                     |d          S )a  
        Online learning. Prevents rebuilding of CFTree from scratch.

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

        y : Ignored
            Not used, present here for API consistency by convention.

        Returns
        -------
        self
            Fitted estimator.
        NTr   )r   r   r   s      r+   partial_fitzBirch.partial_fitr  s6    ( 9##%%%K99Q9---r-   c                 p    t          |            t          | |dd          }|                     |          S )ak  
        Predict data using the ``centroids_`` of subclusters.

        Avoid computation of the row norms of X.

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

        Returns
        -------
        labels : ndarray of shape(n_samples,)
            Labelled data.
        r   Fr   r   )r   r   _predictrV   r!   s     r+   predictzBirch.predict  s:      	$eDDD}}Qr-   c                     d| j         i}t          d          5  t          || j        |          }ddd           n# 1 swxY w Y   | j        |         S )z5Predict data using the ``centroids_`` of subclusters.r5   Tassume_finite)metric_kwargsN)_subcluster_normsr   r   r   subcluster_labels_)rV   r!   kwargsrc   s       r+   r   zBirch._predict  s    "D$:;$/// 	 	.4+6  F	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 &v..s   >AAc                     t          |            t          | |dd          }t          d          5  t          || j                  cddd           S # 1 swxY w Y   dS )a  
        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} of shape (n_samples, n_features)
            Input data.

        Returns
        -------
        X_trans : {array-like, sparse matrix} of shape (n_samples, n_clusters)
            Transformed data.
        r   Fr   Tr   N)r   r   r   r   r   r   s     r+   	transformzBirch.transform  s    " 	$eDDD$/// 	D 	D&q$*BCC	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	Ds   AAAc                 0   | j         }| j        }|duo| j        }d}t          |t                    r/t          | j                   }t          |          | j         k     rd}t          | j        d          | _        ||rZt          j
        t          |                    | _        |r1t          j        dt          |          | j         fz  t                     n|                    | j                  | _        |r|                     |          | _        dS dS )zN
        Global clustering for the subclusters obtained after fitting
        NF)rK   T)r6   zTNumber of subclusters found (%d) by BIRCH is less than (%d). Decrease the threshold.)rK   r   r   
isinstancer   r   rY   r   r   r   aranger   r   r   r   fit_predictr   labels_)rV   r!   	clustererr   r   not_enough_centroidss         r+   r   zBirch._global_clustering  s'    O	,	4-@T-@  %i** 	,/4?KKKI9~~//'+$ "+4+CT!R!R!R 4&(iI&?&?D## 99~~t78 '	   '0&;&;D<T&U&UD# 	,==++DLLL	, 	,r-   c                 |    t                                                      }ddg|j        _        d|j        _        |S )Nr   r   T)super__sklearn_tags__transformer_tagspreserves_dtype
input_tagsr   )rV   tags	__class__s     r+   r   zBirch.__sklearn_tags__  s7    ww''))1:I0F-!%r-   ry   )NN)rk   rl   rm   rn   r   r   r   r   r   r   r   dict__annotations__rW   r   r   r   r   r   r   r   r   r   r   __classcell__)r   s   @r+   r   r   g  s        | |~ htS$yAAAB%Xh4	JJJK\88Haf+U+U+UV$+FF::|n#=#=>>?$ $D         \555+ + + 65+&M M M^    \555. . . 65.4     (/ / /D D D,#, #, #, #,J        r-   r   )(r   mathr   numbersr   r   numpyr   scipyr   _configr   baser	   r
   r   r   r   
exceptionsr   metricsr   metrics.pairwiser   utils._param_validationr   r   r   utils.extmathr   utils.validationr   r    r   r,   rR   r8   r7   r   ro   r-   r+   <module>r      s	          " " " " " " " "           $ $ $ $ $ $              , + + + + + / / / / / / 2 2 2 2 2 2 B B B B B B B B B B % % % % % % = = = = = = = = % % % % % %  $<, <, <,~X X X X X X X Xv\' \' \' \' \' \' \' \'~C C C C C#\3C]C C C C Cr-   