docs: def estimate_skeleton(self, significance_level=0.01):
          """Estimates a graph skeleton (UndirectedGraph) for the data set.
          Uses the build_skeleton method (PC algorithm); independencies are
          determined using a chisquare statistic with the acceptance threshold
          of `significance_level`. Returns a tuple `(skeleton, separating_sets).
  
          Parameters
          ----------
          significance_level: float, default: 0.01
              The significance level to use for conditional independence tests in the data set.
  
              `significance_level` is the desired Type 1 error probability of
              falsely rejecting the null hypothesis that variables are independent,
              given that they are. The lower `significance_level`, the less likely
              we are to accept dependencies, resulting in a sparser graph.
  
          Returns
          -------
          skeleton: UndirectedGraph
              An estimate for the undirected graph skeleton of the BN underlying the data.
  
          separating_sets: dict
              A dict containing for each pair of not directly connected nodes a
              separating set of variables that makes then conditionally independent.
              (needed for edge orientation procedures)
  
          Reference
          ---------
          [1] Neapolitan, Learning Bayesian Networks, Section 10.1.2, Algorithm 10.2 (page 550)
              http://www.cs.technion.ac.il/~dang/books/Learning%20Bayesian%20Networks(Neapolitan,%20Richard).pdf
          [2] Chi-square test https://en.wikipedia.org/wiki/Pearson%27s_chi-squared_test#Test_of_independence
  
          Examples
          --------
          >>> import pandas as pd
          >>> import numpy as np
          >>> from pgmpy.estimators import ConstraintBasedEstimator
          >>>
          >>> data = pd.DataFrame(np.random.randint(0, 2, size=(5000, 5)), columns=list('ABCDE'))
          >>> data['F'] = data['A'] + data['B'] + data ['C']
          >>> est = ConstraintBasedEstimator(data)
          >>> skel, sep_sets = est.estimate_skeleton()
          >>> skel.edges()
          [('A', 'F'), ('B', 'F'), ('C', 'F')]
          >>> # all independencies are unconditional:
          >>> sep_sets
          {('D', 'A'): (), ('C', 'A'): (), ('C', 'E'): (), ('E', 'F'): (), ('B', 'D'): (),
           ('B', 'E'): (), ('D', 'F'): (), ('D', 'E'): (), ('A', 'E'): (), ('B', 'A'): (),
           ('B', 'C'): (), ('C', 'D'): ()}
          >>>
          >>> data = pd.DataFrame(np.random.randint(0, 2, size=(5000, 3)), columns=list('XYZ'))
          >>> data['X'] += data['Z']
          >>> data['Y'] += data['Z']
          >>> est = ConstraintBasedEstimator(data)
          >>> skel, sep_sets = est.estimate_skeleton()
          >>> skel.edges()
          [('X', 'Z'), ('Y', 'Z')]
          >>> # X, Y dependent, but conditionally independent given Z:
          >>> sep_sets
          {('X', 'Y'): ('Z',)}
          """
  
          nodes = self.state_names.keys()
  
          def is_independent(X, Y, Zs):
              """Returns result of hypothesis test for the null hypothesis that
              X _|_ Y | Zs, using a chi2 statistic and threshold `significance_level`.
              """
              chi2, p_value, sufficient_data = self.test_conditional_independence(X, Y, Zs)
              return p_value >= significance_level
  
          return self.build_skeleton(nodes, is_independent)