docs: def cluster(self, algorithm=None):
          """Cluster the codebook. The clusters of the data instances can be
          assigned based on the BMUs. The method populates the class variable
          Somoclu.clusters. If viewing methods are called after clustering, but
          without colors for best matching units, colors will be automatically
          assigned based on cluster membership.
  
          :param algorithm: Optional parameter to specify a scikit-learn
                            clustering algorithm. The default is K-means with
                            eight clusters.
          :type filename: sklearn.base.ClusterMixin.
          """
  
          import sklearn.base
          if algorithm is None:
              import sklearn.cluster
              algorithm = sklearn.cluster.KMeans()
          elif not isinstance(algorithm, sklearn.base.ClusterMixin):
              raise Exception("Cannot use algorithm of type " + type(algorithm))
          original_shape = self.codebook.shape
          self.codebook.shape = (self._n_columns * self._n_rows, self.n_dim)
          linear_clusters = algorithm.fit_predict(self.codebook)
          self.codebook.shape = original_shape
          self.clusters = np.zeros((self._n_rows, self._n_columns), dtype=int)
          for i, c in enumerate(linear_clusters):
              self.clusters[i // self._n_columns, i % self._n_columns] = c