def fit(
    self,
    notes: pd.DataFrame,
    ratings: pd.DataFrame,
    noteStatusHistory: pd.DataFrame,
    prescoringRaterModelOutput: pd.DataFrame,
  ) -> None:
    """Fit and evaluate a sklearn pipeline for predicting note status.

    Args:
      notes: pd.DataFrame
      ratings: pd.DataFrame
      noteStatusHistory: pd.DataFrame
      prescoringRaterModelOutput: pd.DataFrame

    Returns:
      sklearn pipeline covering containing full process of feature extraction, feature
      selection and prediction.
    """
    # Apply seed if necessary
    if self._seed is not None:
      logger.info(f"seeding pflip: {self._seed}")
      np.random.seed(self._seed)
    # Prepare datasets
    noteInfo = pd.concat(
      [
        self._prepare_note_info(
          notes,
          ratings,
          noteStatusHistory,
          prescoringRaterModelOutput,
          prepareForTraining=True,
          cutoff=_MIN,
        ),
        self._prepare_note_info(
          notes,
          ratings,
          noteStatusHistory,
          prescoringRaterModelOutput,
          prepareForTraining=True,
          cutoff=_MAX,
        ),
      ]
    )
    noteInfo = self._convert_col_types(noteInfo)
    noteInfo = noteInfo.sort_values(c.noteIdKey)
    if len(noteInfo) == 0:
      return
    logger.info(f"noteInfo summary: {get_df_fingerprint(noteInfo, [c.noteIdKey])}")
    # Dividing training data temporally provides a more accurate measurement, but would also
    # require excluding the newest data from training.
    trainDataFrame, validationDataFrame = train_test_split(noteInfo, train_size=self._trainSize)
    logger.info(f"pflip training data size: {len(trainDataFrame)}")
    logger.info(f"trainDataFrame summary: {get_df_fingerprint(trainDataFrame, [c.noteIdKey])}")
    logger.info(f"pflip validation data size: {len(validationDataFrame)}")
    logger.info(
      f"validationDataFrame summary: {get_df_fingerprint(validationDataFrame, [c.noteIdKey])}"
    )
    # Fit model
    self._pipeline = self._get_model_pipeline(trainDataFrame)
    trainDataFrame = self._transform_note_info(trainDataFrame)
    validationDataFrame = self._transform_note_info(validationDataFrame)
    self._pipeline.fit(trainDataFrame, self._get_label_vector(trainDataFrame))
    featureProfile = self._profile_pipeline(self._pipeline[0], trainDataFrame)
    logger.info(f"\ntraining feature matrix profile:\n{featureProfile}")
    # Evaluate model
    logger.info("Training Results:")
    threshold, _, _, _ = self._evaluate_model(trainDataFrame)
    self._predictionThreshold = threshold
    logger.info("Validation Results:")
    self._evaluate_model(validationDataFrame, threshold=threshold)
Fit and evaluate a sklearn pipeline for predicting note status.

    Args:
      notes: pd.DataFrame
      ratings: pd.DataFrame
      noteStatusHistory: pd.DataFrame
      prescoringRaterModelOutput: pd.DataFrame

    Returns:
      sklearn pipeline covering containing full process of feature extraction, feature
      selection and prediction.
    
sourcecode/scoring/pflip_plus_model.py