code: def learn_network_structure(
      ts_returns_data,
      names,
      alphas=4,
      cv=5,
      mode="cd",
      assume_centered=False,
      n_components=2,
      n_neighbors=5,
      eigen_solver="dense",
      method="standard",
      neighbors_algorithm="auto",
      random_state=None,
      n_jobs=None,
      standardise=False,
  ):
      """
  
      Parameters
      ----------
      ts_returns_data : array-like of shape [n_samples, n_instruments]
                        time series matrix of returns
  
      names : array-like of shape [n_samples, 1]
              Individual names of the financial instrument
  
      alphas : int or positive float, optional
               Number of points on the grids to be used
  
      cv : int, optional
           Number of folds for cross-validation splitting strategy
  
      mode : str, optional
             Solver to use to compute the graph
  
      assume_centered : bool, optional
                    Centre the data if False.
  
      n_components : int
                     Number of components for the manifold
  
      n_neighbors: int
               Number of neighbours to consider for each point
  
      eigen_solver : str
                     Algorithm to compute eigenvalues
  
      method : str
           Algorithm to use for local linear embedding
      neighbors_algorithm : str
                            Algorithm to use for nearest neighbours search
  
      random_state : int, RandomState instance or None, optional
                     If int, random_state is the seed used by the random number generator.
                     If RandomState instance, random_state is the random number generator.
                     If None, the random number generator is the RandomState instance used by np.random.
                     Used when eigen_solver == ‘arpack’
  
      n_jobs : int or None, optional
               number of parallel jobs to run
  
      standardise : bool
                    standardise data if True
  
      Returns : sklearn.covariance.graph_lasso_.GraphicalLassoCV
  
            sklearn.manifold.locally_linear.LocallyLinearEmbedding
  
            array-like of shape [n_components, n_instruments]
            Transformed embedding vectors
  
            array-like of shape [n_instruments, 1]
            numeric identifier of each cluster
  
  
  
      -------
      """
  
      if not isinstance(ts_returns_data, (np.ndarray, np.generic)):
          raise TypeError("ts_returns_data must be of class ndarray")
  
      # learn graphical structure
      edge_model = covariance.GraphicalLassoCV(
          alphas=alphas,
          cv=cv,
          mode=mode,
          assume_centered=assume_centered,
      )
      edge_model.fit(ts_returns_data)
  
      # cluster using affinity propagation
      _, labels = cluster.affinity_propagation(edge_model.covariance_)
      n_labels = labels.max()
      for i in range(n_labels + 1):
          print(
              "Cluster %i: %s"
              % ((i + 1), ", ".join(names[labels == i]))
          )
  
      # find low-dimension embedding - useful for 2D plane visualisation
      node_position_model = manifold.LocallyLinearEmbedding(
          n_components=n_components,
          eigen_solver=eigen_solver,
          n_neighbors=n_neighbors,
          method=method,
          neighbors_algorithm=neighbors_algorithm,
          random_state=random_state,
          n_jobs=n_jobs,
      )
      embedding = node_position_model.fit_transform(ts_returns_data.T).T
  
      if standardise:
          # standardise returns
          standard_ret = ts_returns_data.copy()
          standard_ret /= ts_returns_data.std(axis=0)
  
          # learn graph model
          edge_model.fit(standard_ret)
  
          # cluster using affinity propagation
          _, labels = cluster.affinity_propagation(
              edge_model.covariance_
          )
          n_labels = labels.max()
          for i in range(n_labels + 1):
              print(
                  "Cluster %i: %s"
                  % ((i + 1), ", ".join(names[labels == i]))
              )
  
          # find low-dimension embedding - useful for 2D plane visualisation
          node_position_model = manifold.LocallyLinearEmbedding(
              n_components=n_components,
              eigen_solver=eigen_solver,
              n_neighbors=n_neighbors,
              method=method,
              neighbors_algorithm=neighbors_algorithm,
              random_state=random_state,
              n_jobs=n_jobs,
          )
          embedding = node_position_model.fit_transform(
              ts_returns_data.T
          ).T
  
      return edge_model, node_position_model, embedding, labels
  
label_desc: Use image node_id 1 for calling a global function with example usage: learn_network_structure(ts_returns_data, names, alphas, cv, mode, assume_centered, n_components, n_neighbors, eigen_solver, method, neighbors_algorithm, random_state, n_jobs, standardise) and returns: edge_model,  node_position_model,  embedding,  labels