def _run_stable_matrix_factorization(
    self,
    ratingsForTraining: pd.DataFrame,
    userEnrollmentRaw: pd.DataFrame,
  ):
    """Train a matrix factorization model on the ratingsForTraining data.
    Due to stability issues when trained on the entire dataset with no initialization, this is done in
    two steps:
    1. Train a model on the subset of the data with modeling group 13 (stable initialization).
    2. Train a model on the entire dataset, initializing with the results from step 1.
    Without this initialization, the factors for some subsets of the data with low crossover between raters can
    flip relative to each other from run to run.

    Args:
        ratingsForTraining (pd.DataFrame)
        userEnrollmentRaw (pd.DataFrame)

    Returns:
        noteParams (pd.DataFrame)
        raterParams (pd.DataFrame)
        globalIntercept (float)
    """
    if self._modelingGroupToInitializeForStability is None:
      return self._run_regular_matrix_factorization(ratingsForTraining)

    with self.time_block("Prepare data for stable initialization"):
      ratingsForStableInitialization = get_ratings_for_stable_init(
        ratingsForTraining,
        userEnrollmentRaw,
        self._modelingGroupToInitializeForStability,
      )

    with self.time_block("MF on stable-initialization subset"):
      initializationMF = self._mfRanker.get_new_mf_with_same_args()
      noteParamsInit, raterParamsInit, globalInterceptInit = initializationMF.run_mf(
        ratingsForStableInitialization, run_name=f"{self.get_name()}/stable_init"
      )

    with self.time_block("First full MF (initializated with stable-initialization)"):
      modelResult = self._mfRanker.run_mf(
        ratingsForTraining,
        noteInit=noteParamsInit,
        userInit=raterParamsInit,
        globalInterceptInit=globalInterceptInit,
        run_name=f"{self.get_name()}/full_init",
      )
    return modelResult
Train a matrix factorization model on the ratingsForTraining data.
    Due to stability issues when trained on the entire dataset with no initialization, this is done in
    two steps:
    1. Train a model on the subset of the data with modeling group 13 (stable initialization).
    2. Train a model on the entire dataset, initializing with the results from step 1.
    Without this initialization, the factors for some subsets of the data with low crossover between raters can
    flip relative to each other from run to run.

    Args:
        ratingsForTraining (pd.DataFrame)
        userEnrollmentRaw (pd.DataFrame)

    Returns:
        noteParams (pd.DataFrame)
        raterParams (pd.DataFrame)
        globalIntercept (float)
    
sourcecode/scoring/mf_base_scorer.py