in graspologic/cluster/divisive_cluster.py [0:0]
def _fit(self, X: np.ndarray) -> np.ndarray:
pred = self._cluster_and_decide(X)
self.children: Tuple["DivisiveCluster"] = cast(
Tuple["DivisiveCluster"], tuple()
)
uni_labels = np.unique(pred)
labels = pred.reshape((-1, 1)).copy()
if len(uni_labels) > 1:
for ul in uni_labels:
inds = pred == ul
new_X = X[inds]
dc = DivisiveCluster(
cluster_method=self.cluster_method,
max_components=self.max_components,
min_split=self.min_split,
max_level=self.max_level,
cluster_kws=self.cluster_kws,
delta_criter=self.delta_criter,
)
dc.parent = self
if (
len(new_X) > self.max_components
and len(new_X) >= self.min_split
and self.depth + 1 < self.max_level
):
child_labels = dc._fit(new_X)
while labels.shape[1] <= child_labels.shape[1]:
labels = np.column_stack(
(labels, np.zeros((len(X), 1), dtype=int))
)
labels[inds, 1 : child_labels.shape[1] + 1] = child_labels
else:
# make a "GaussianMixture" model for clusters
# that were not fitted
if self.cluster_method == "gmm":
cluster_idx = len(dc.parent.children) - 1
parent_model = dc.parent.model_
model = GaussianMixture()
model.weights_ = np.array([1])
model.means_ = parent_model.means_[cluster_idx].reshape(1, -1)
model.covariance_type = parent_model.covariance_type
if model.covariance_type == "tied":
model.covariances_ = parent_model.covariances_
model.precisions_ = parent_model.precisions_
model.precisions_cholesky_ = (
parent_model.precisions_cholesky_
)
else:
cov_types = ["spherical", "diag", "full"]
n_features = model.means_.shape[-1]
cov_shapes = [
(1,),
(1, n_features),
(1, n_features, n_features),
]
cov_shape_idx = cov_types.index(model.covariance_type)
model.covariances_ = parent_model.covariances_[
cluster_idx
].reshape(cov_shapes[cov_shape_idx])
model.precisions_ = parent_model.precisions_[
cluster_idx
].reshape(cov_shapes[cov_shape_idx])
model.precisions_cholesky_ = (
parent_model.precisions_cholesky_[cluster_idx].reshape(
cov_shapes[cov_shape_idx]
)
)
dc.model_ = model
return labels