






'''simple docstring'''







import warnings

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.metrics import pairwise_distances

warnings.filterwarnings('ignore')

__A      :       str      =	"""K-MEANS-CLUST/ """


def 						_UpperCamelCase							(     snake_case__							,			snake_case__							,			snake_case__=None							):
      if seed is not None:  # useful for obtaining consistent results
            np.random.seed(snake_case__							)
      __A		   =      data.shape[0]  # number of data points

      # Pick K indices from range [0, N).
      __A		   =      np.random.randint(0							,			snake_case__							,			snake_case__							)

      # Keep centroids as dense format, as many entries will be nonzero due to averaging.
      # As long as at least one document in a cluster contains a word,
      # it will carry a nonzero weight in the TF-IDF vector of the centroid.
      __A		   =      data[rand_indices, :]

      return centroids


def 						_UpperCamelCase							(     snake_case__							,			snake_case__							):
      return pairwise_distances(snake_case__							,			snake_case__							,			metric="euclidean"							)


def 						_UpperCamelCase							(     snake_case__							,			snake_case__							):
      # Compute distances between each data point and the set of centroids:
      # Fill in the blank (RHS only)
      __A		   =      centroid_pairwise_dist(snake_case__							,			snake_case__							)

      # Compute cluster assignments for each data point:
      # Fill in the blank (RHS only)
      __A		   =      np.argmin(snake_case__							,			axis=1							)

      return cluster_assignment


def 						_UpperCamelCase							(     snake_case__							,			snake_case__							,			snake_case__							):
      __A		   =      []
      for i in range(snake_case__							):
            # Select all data points that belong to cluster i. Fill in the blank (RHS only)
            __A		   =      data[cluster_assignment == i]
            # Compute the mean of the data points. Fill in the blank (RHS only)
            __A		   =      member_data_points.mean(axis=0							)
            new_centroids.append(snake_case__							)
      __A		   =      np.array(snake_case__							)

      return new_centroids


def 						_UpperCamelCase							(     snake_case__							,			snake_case__							,			snake_case__							,			snake_case__							):
      __A		   =      0.0
      for i in range(snake_case__							):
            # Select all data points that belong to cluster i. Fill in the blank (RHS only)
            __A		   =      data[cluster_assignment == i, :]

            if member_data_points.shape[0] > 0:  # check if i-th cluster is non-empty
                  # Compute distances from centroid to data points (RHS only)
                  __A		   =      pairwise_distances(
                      snake_case__							,			[centroids[i]]							,			metric="euclidean"							)
                  __A		   =      distances**2
                  heterogeneity += np.sum(snake_case__							)

      return heterogeneity


def 						_UpperCamelCase							(     snake_case__							,			snake_case__							):
      plt.figure(figsize=(7, 4)							)
      plt.plot(snake_case__							,			linewidth=4							)
      plt.xlabel("# Iterations"							)
      plt.ylabel("Heterogeneity"							)
      plt.title(f"Heterogeneity of clustering over time, K={k:d}"							)
      plt.rcParams.update({"font.size": 16}							)
      plt.show()


def 						_UpperCamelCase							(     snake_case__							,			snake_case__							,			snake_case__							,			snake_case__=500							,			snake_case__=None							,			snake_case__=False							):
      __A		   =      initial_centroids[:]
      __A		   =      None

      for itr in range(snake_case__							):
            if verbose:
                  print(snake_case__							,			end=""							)

            # 1. Make cluster assignments using nearest centroids
            __A		   =      assign_clusters(snake_case__							,			snake_case__							)

            # 2. Compute a new centroid for each of the k clusters, averaging all data
            #    points assigned to that cluster.
            __A		   =      revise_centroids(snake_case__							,			snake_case__							,			snake_case__							)

            # Check for convergence: if none of the assignments changed, stop
            if (
                prev_cluster_assignment is not None
                and (prev_cluster_assignment == cluster_assignment).all()
            ):
                  break

            # Print number of new assignments
            if prev_cluster_assignment is not None:
                  __A		   =      np.sum(prev_cluster_assignment != cluster_assignment							)
                  if verbose:
                        print(
                            f"    {num_changed:5d} elements changed their cluster assignment."							)

        # Record heterogeneity convergence metric
            if record_heterogeneity is not None:
                  # YOUR CODE HERE
                  __A		   =      compute_heterogeneity(snake_case__							,			snake_case__							,			snake_case__							,			snake_case__							)
                  record_heterogeneity.append(snake_case__							)

            __A		   =      cluster_assignment[:]

      return centroids, cluster_assignment


# Mock test below
if False:  # change to true to run this test case.
    from sklearn import datasets as ds

    __A      :       Optional[Any]      =	ds.load_iris()
    __A      :       int      =	3
    __A      :       List[str]      =	[]
    __A      :       int      =	get_initial_centroids(dataset['data'], k, seed=0)
    __A      :       Union[str, Any]      =	kmeans(
        dataset['data'],
        k,
        initial_centroids,
        maxiter=4_0_0,
        record_heterogeneity=heterogeneity,
        verbose=True,
    )
    plot_heterogeneity(heterogeneity, k)


def 						_UpperCamelCase							(     snake_case__							,			snake_case__							,			snake_case__=None							):
      # Fill missing values with given rules
      if fill_missing_report:
            __A		   =      df.fillna(value=snake_case__							)
      __A		   =      1
      __A		   =      df.select_dtypes(np.number							).columns
      __A		   =      (
          df.groupby(["Cluster"]							)[  # construct report dataframe
              numeric_cols
          ]  # group by cluster number
          .agg(
              [
                  ("sum", np.sum),
                  ("mean_with_zeros", lambda snake_case__							: np.mean(np.nan_to_num(snake_case__							)							)),
                  ("mean_without_zeros", lambda snake_case__							: x.replace(0							,			np.NaN							).mean()),
                  (
                      "mean_25-75",
                      lambda snake_case__							: np.mean(
                          np.nan_to_num(
                              sorted(snake_case__							)[
                                  round(len(snake_case__							) * 25 / 100							) : round(len(snake_case__							) * 75 / 100							)
                              ]							)							),
                  ),
                  ("mean_with_na", np.mean),
                  ("min", lambda snake_case__							: x.min()),
                  ("5%", lambda snake_case__							: x.quantile(0.05							)),
                  ("25%", lambda snake_case__							: x.quantile(0.25							)),
                  ("50%", lambda snake_case__							: x.quantile(0.50							)),
                  ("75%", lambda snake_case__							: x.quantile(0.75							)),
                  ("95%", lambda snake_case__							: x.quantile(0.95							)),
                  ("max", lambda snake_case__							: x.max()),
                  ("count", lambda snake_case__							: x.count()),
                  ("stdev", lambda snake_case__							: x.std()),
                  ("mode", lambda snake_case__							: x.mode()[0]),
                  ("median", lambda snake_case__							: x.median()),
                  ("# > 0", lambda snake_case__							: (x > 0).sum()),
              ]							)
          .T.reset_index()
          .rename(index=snake_case__							,			columns={"level_0": "Features", "level_1": "Type"}							)
      )  # rename columns
      # calculate the size of cluster(count of clientID's)
      __A		   =      report[
          (report["Features"] == "dummy") & (report["Type"] == "count")
      ].copy()  # avoid SettingWithCopyWarning
      __A		   =      (
          "ClusterSize"  # rename created cluster df to match report column names
      )
      __A		   =      "# of Customers"
      __A		   =      pd.DataFrame(
          clustersize.iloc[:, 2:].values
          / clustersize.iloc[:, 2:].values.sum()							)
      __A		   =      "% of Customers"  # rename created cluster df to match report column names
      __A		   =      "ClusterProportion"
      __A		   =      clusterproportion.columns.tolist()
      __A		   =      cols[-2:] + cols[:-2]
      __A		   =      clusterproportion[cols]  # rearrange columns to match report
      __A		   =      report.columns
      __A		   =      pd.DataFrame(
          abs(
              report[report["Type"] == "count"].iloc[:, 2:].values
              - clustersize.iloc[:, 2:].values							)							)  # generating df with count of nan values
      __A		   =      0
      __A		   =      "# of nan"
      __A		   =      report[
          report["Type"] == "count"
      ].Features.tolist()  # filling values in order to match report
      __A		   =      a.columns.tolist()
      __A		   =      cols[-2:] + cols[:-2]
      __A		   =      a[cols]  # rearrange columns to match report
      __A		   =      report.columns  # rename columns to match report
      __A		   =      report.drop(
          report[report.Type == "count"].index							)  # drop count values except cluster size
      __A		   =      pd.concat(
          [report, a, clustersize, clusterproportion]							,			axis=0							)  # concat report with clustert size and nan values
      __A		   =      report["Features"].isin(snake_case__							)
      __A		   =      report.columns.tolist()
      __A		   =      cols[0:2] + cols[-1:] + cols[2:-1]
      __A		   =      report[cols]
      __A		   =      {
          "ClusterSize": 9,
          "ClusterProportion": 8,
          "mean_with_zeros": 7,
          "mean_with_na": 6,
          "max": 5,
          "50%": 4,
          "min": 3,
          "25%": 2,
          "75%": 1,
          "# of nan": 0,
          "# > 0": -1,
          "sum_with_na": -2,
      }
      __A		   =      (
          report.assign(
              Sortera=lambda snake_case__							: x.Type.map(snake_case__							)							,			Sortera=lambda snake_case__							: list(reversed(range(len(snake_case__							)							)							)							)							,			)
          .sort_values(["Sorter1", "Mark", "Sorter2"]							,			ascending=snake_case__							)
          .drop(["Sorter1", "Sorter2"]							,			axis=1							)
      )
      __A		   =      ""
      __A		   =      report.reset_index()
      __A		   =      report.drop(columns=["index"]							)
      return report


if __name__ == "__main__":
    import doctest

    doctest.testmod()










'''simple docstring'''







import copy
import inspect

from transformers.testing_utils import require_torch, torch_device
from transformers.utils.backbone_utils import BackboneType






@require_torch
class 					a__    :
     '''simple docstring'''







     _snake_case             =  ()
     _snake_case             =  True






     def     _UpperCamelCase   (self    :	Optional[Any]					)  ->       Union[str, Any]:
           __A		   =      self.config_class

           # test default config
           __A		   =      config_class()
           self.assertIsNotNone(lowercase__					)
           __A		   =      ["stem"] + [f"stage{idx}" for idx in range(1				,				len(config.depths					) + 1					)]
           self.assertEqual(config.stage_names				,				lowercase__					)
           self.assertTrue(set(config.out_features					).issubset(set(config.stage_names					)					)					)

           # Test out_features and out_indices are correctly set
           # out_features and out_indices both None
           __A		   =      config_class(out_features=lowercase__				,				out_indices=lowercase__					)
           self.assertEqual(config.out_features				,				[config.stage_names[-1]]					)
           self.assertEqual(config.out_indices				,				[len(config.stage_names					) - 1]					)

           # out_features and out_indices both set
           __A		   =      config_class(out_features=["stem", "stage1"]				,				out_indices=[0, 1]					)
           self.assertEqual(config.out_features				,				["stem", "stage1"]					)
           self.assertEqual(config.out_indices				,				[0, 1]					)

           # Only out_features set
           __A		   =      config_class(out_features=["stage1", "stage3"]					)
           self.assertEqual(config.out_features				,				["stage1", "stage3"]					)
           self.assertEqual(config.out_indices				,				[1, 3]					)

           # Only out_indices set
           __A		   =      config_class(out_indices=[0, 2]					)
           self.assertEqual(config.out_features				,				[config.stage_names[0], config.stage_names[2]]					)
           self.assertEqual(config.out_indices				,				[0, 2]					)

           # Error raised when out_indices do not correspond to out_features
           with self.assertRaises(lowercase__					):
                 __A		   =      config_class(out_features=["stage1", "stage2"]				,				out_indices=[0, 2]					)






     def     _UpperCamelCase   (self    :	Optional[int]					)  ->       Optional[Any]:
           __A   ,				__A		   =      self.model_tester.prepare_config_and_inputs_for_common()

           for model_class in self.all_model_classes:
                 __A		   =      model_class(lowercase__					)
                 __A		   =      inspect.signature(model.forward					)
                 # signature.parameters is an OrderedDict => so arg_names order is deterministic
                 __A		   =      [*signature.parameters.keys()]
                 __A		   =      ["pixel_values"]
                 self.assertListEqual(arg_names[:1]				,				lowercase__					)






     def     _UpperCamelCase   (self    :	Dict					)  ->       Union[str, Any]:
           __A   ,				__A		   =      self.model_tester.prepare_config_and_inputs_for_common()

           for model_class in self.all_model_classes:
                 __A		   =      model_class(lowercase__					)
                 self.assertEqual(len(model.channels					)				,				len(config.out_features					)					)
                 __A		   =      model.num_features
                 __A		   =      [config.stage_names.index(lowercase__					) for feat in config.out_features]
                 __A		   =      [num_features[idx] for idx in out_indices]
                 self.assertListEqual(model.channels				,				lowercase__					)

                 __A		   =      copy.deepcopy(lowercase__					)
                 __A		   =      None
                 __A		   =      model_class(lowercase__					)
                 self.assertEqual(len(model.channels					)				,				1					)
                 self.assertListEqual(model.channels				,				[num_features[-1]]					)

                 __A		   =      copy.deepcopy(lowercase__					)
                 __A		   =      None
                 __A		   =      model_class(lowercase__					)
                 self.assertEqual(len(model.channels					)				,				1					)
                 self.assertListEqual(model.channels				,				[num_features[-1]]					)






     def     _UpperCamelCase   (self    :	Optional[Any]					)  ->       Optional[Any]:
           __A   ,				__A		   =      self.model_tester.prepare_config_and_inputs_for_common()

           for model_class in self.all_model_classes:
                 __A		   =      model_class(lowercase__					)
                 model.to(lowercase__					)
                 model.eval()
                 __A		   =      model(**lowercase__					)

                 self.assertEqual(len(result.feature_maps					)				,				len(config.out_features					)					)
                 self.assertEqual(len(model.channels					)				,				len(config.out_features					)					)
                 self.assertEqual(len(result.feature_maps					)				,				len(config.out_indices					)					)
                 self.assertEqual(len(model.channels					)				,				len(config.out_indices					)					)

                 # Check output of last stage is taken if out_features=None, out_indices=None
                 __A		   =      copy.deepcopy(lowercase__					)
                 __A		   =      None
                 __A		   =      model_class(lowercase__					)
                 model.to(lowercase__					)
                 model.eval()
                 __A		   =      model(**lowercase__					)

                 self.assertEqual(len(result.feature_maps					)				,				1					)
                 self.assertEqual(len(model.channels					)				,				1					)

                 __A		   =      copy.deepcopy(lowercase__					)
                 __A		   =      None
                 __A		   =      model_class(lowercase__					)
                 model.to(lowercase__					)
                 model.eval()
                 __A		   =      model(**lowercase__					)

                 self.assertEqual(len(result.feature_maps					)				,				1					)
                 self.assertEqual(len(model.channels					)				,				1					)

                 # Check backbone can be initialized with fresh weights
                 __A		   =      copy.deepcopy(lowercase__					)
                 __A		   =      False
                 __A		   =      model_class(lowercase__					)
                 model.to(lowercase__					)
                 model.eval()
                 __A		   =      model(**lowercase__					)






     def     _UpperCamelCase   (self    :	Dict					)  ->       Optional[int]:
           __A   ,				__A		   =      self.model_tester.prepare_config_and_inputs_for_common()

           for backbone_class in self.all_model_classes:
                 __A		   =      backbone_class(lowercase__					)

                 self.assertTrue(hasattr(lowercase__				,				"backbone_type"					)					)
                 self.assertTrue(hasattr(lowercase__				,				"stage_names"					)					)
                 self.assertTrue(hasattr(lowercase__				,				"num_features"					)					)
                 self.assertTrue(hasattr(lowercase__				,				"out_indices"					)					)
                 self.assertTrue(hasattr(lowercase__				,				"out_features"					)					)
                 self.assertTrue(hasattr(lowercase__				,				"out_feature_channels"					)					)
                 self.assertTrue(hasattr(lowercase__				,				"channels"					)					)

                 self.assertIsInstance(backbone.backbone_type				,				lowercase__					)
                 # Verify num_features has been initialized in the backbone init
                 self.assertIsNotNone(backbone.num_features					)
                 self.assertTrue(len(backbone.channels					) == len(backbone.out_indices					)					)
                 self.assertTrue(len(backbone.stage_names					) == len(backbone.num_features					)					)
                 self.assertTrue(len(backbone.channels					) <= len(backbone.num_features					)					)
                 self.assertTrue(len(backbone.out_feature_channels					) == len(backbone.stage_names					)					)






     def     _UpperCamelCase   (self    :	Tuple					)  ->       int:
           __A   ,				__A		   =      self.model_tester.prepare_config_and_inputs_for_common()
           __A		   =      inputs_dict["pixel_values"].shape[0]

           for backbone_class in self.all_model_classes:
                 __A		   =      backbone_class(lowercase__					)
                 backbone.to(lowercase__					)
                 backbone.eval()

                 __A		   =      backbone(**lowercase__					)

                 # Test default outputs and verify feature maps
                 self.assertIsInstance(outputs.feature_maps				,				lowercase__					)
                 self.assertTrue(len(outputs.feature_maps					) == len(backbone.channels					)					)
                 for feature_map, n_channels in zip(outputs.feature_maps				,				backbone.channels					):
                       self.assertTrue(feature_map.shape[:2]				,				(batch_size, n_channels)					)
                 self.assertIsNone(outputs.hidden_states					)
                 self.assertIsNone(outputs.attentions					)

                 # Test output_hidden_states=True
                 __A		   =      backbone(**lowercase__				,				output_hidden_states=lowercase__					)
                 self.assertIsNotNone(outputs.hidden_states					)
                 self.assertTrue(len(outputs.hidden_states					)				,				len(backbone.stage_names					)					)
                 for hidden_state, n_channels in zip(outputs.hidden_states				,				backbone.channels					):
                       self.assertTrue(hidden_state.shape[:2]				,				(batch_size, n_channels)					)

                 # Test output_attentions=True
                 if self.has_attentions:
                       __A		   =      backbone(**lowercase__				,				output_attentions=lowercase__					)
                       self.assertIsNotNone(outputs.attentions					)


