docstr: :param first_names: users first names (optional - if last_names/zip_codes are provided)
  :param last_names: users last names (optional - if first_names/zip_codes are provided)
  :param zip_codes: users zip codes (optional - if first_names/last_names are provided)
  :param features: features for correlation test
  :param method: 'pearson'/'kendall'/'spearman' (default - 'pearson')
  :return: features-groups correlation DataFrame
docstr_tok: [":","param","first_names",":","users","first","names","(","optional","-","if","last_names\/zip_codes","are","provided",")",":","param","last_names",":","users","last","names","(","optional","-","if","first_names\/zip_codes","are","provided",")",":","param","zip_codes",":","users","zip","codes","(","optional","-","if","first_names\/last_names","are","provided",")",":","param","features",":","features","for","correlation","test",":","param","method",":","'pearson'\/'kendall'\/'spearman","'","(","default","-","'pearson","'",")",":","return",":","features-groups","correlation","DataFrame"]
code: def get_features_groups_correlation(
      self,
      first_names: Sequence[str] = None,
      last_names: Sequence[str] = None,
      zip_codes: Sequence[str] = None,
      features: pd.DataFrame = None,
      method: str = "pearson",
  ) -> pd.DataFrame:
      """
      :param first_names: users first names (optional - if last_names/zip_codes are provided)
      :param last_names: users last names (optional - if first_names/zip_codes are provided)
      :param zip_codes: users zip codes (optional - if first_names/last_names are provided)
      :param features: features for correlation test
      :param method: 'pearson'/'kendall'/'spearman' (default - 'pearson')
      :return: features-groups correlation DataFrame
      """
      if (
          first_names is None
          and last_names is None
          and zip_codes is None
      ):
          raise ValueError(
              "first_names/last_names/zip_codes must be provided"
          )
      if features is None or type(features) != pd.DataFrame:
          raise ValueError("features DataFrame must be provided")
      if not self.__is_same_length(
          [first_names, last_names, zip_codes, features]
      ):
          raise ValueError("Input data has different lengths")
      if method not in {"pearson", "kendall", "spearman"}:
          raise ValueError(
              "method should be 'pearson'/'kendall'/'spearman'"
          )
      p_groups = self.get_p_groups(
          first_names,
          last_names,
          zip_codes,
          detect_gender_bias=True,
          detect_race_bias=True,
      )
      features = features.reset_index(drop=True)
      return pd.concat(
          [
              features.corrwith(
                  other=p_groups[col], method=method
              ).rename(col + "_correlation")
              for col in p_groups.columns
          ],
          axis=1,
      )
  
imports: from bias_detector.BiasMetric import BiasMetric
  from bias_detector.BiasReport import BiasReport
  from bias_detector.models.FirstNameModel import FirstNameModel
  from bias_detector.models.FirstNameZipcodeModel import FirstNameZipcodeModel
  from bias_detector.models.FullNameModel import FullNameModel
  from bias_detector.models.FullNameZipcodeModel import FullNameZipcodeModel
  from bias_detector.bias_metrics.BiasMetricImpl import BiasMetricImpl
  from bias_detector.bias_metrics.BiasMetricInput import BiasMetricInput
  from bias_detector.bias_metrics.FprDiff import FprDiff
  from bias_detector.bias_metrics.PositivePredProbDiff import PositivePredProbDiff
  from bias_detector.bias_metrics.TprDiff import TprDiff
  from bias_detector.common import *
  import surgeo
label_desc: Use image node_id 5 for calling the BiasDetector obj's underlying member method code with example usage: obj.get_features_groups_correlation(first_names, last_names, zip_codes, features, method) and returns: pd