class_docstr: This is the AccessAnomaly, a pyspark.ml.Estimator which
  creates the AccessAnomalyModel which is a pyspark.ml.Transformer
code: def _train_cf(
      self, als: ALS, df: DataFrame
  ) -> Tuple[DataFrame, DataFrame]:
      tenant_col = self.tenant_col
      indexed_user_col = self.indexed_user_col
      user_vec_col = self.user_vec_col
      indexed_res_col = self.indexed_res_col
      res_vec_col = self.res_vec_col
  
      spark_model = als.fit(df)
  
      user_mapping_df = (
          spark_model.userFactors.select(
              f.col("id").alias(indexed_user_col),
              f.col("features").alias(user_vec_col),
          )
          .join(
              df.select(indexed_user_col, tenant_col).distinct(),
              indexed_user_col,
          )
          .select(tenant_col, indexed_user_col, user_vec_col)
      )
  
      res_mapping_df = (
          spark_model.itemFactors.select(
              f.col("id").alias(indexed_res_col),
              f.col("features").alias(res_vec_col),
          )
          .join(
              df.select(indexed_res_col, tenant_col).distinct(),
              indexed_res_col,
          )
          .select(tenant_col, indexed_res_col, res_vec_col)
      )
  
      return user_mapping_df, res_mapping_df
  
imports: import os
  from typing import List, Optional, Tuple
  from synapse.ml.cyber.anomaly.complement_access import ComplementAccessTransformer
  from synapse.ml.cyber.feature import indexers, scalers
  from synapse.ml.cyber.utils import spark_utils
  import numpy
  from pyspark import SQLContext
  from pyspark.ml import Estimator, Transformer
  from pyspark.ml.param.shared import Param, Params
  from pyspark.ml.recommendation import ALS
  from pyspark.sql import DataFrame, functions, types
label_desc: Use image node_id 9 for calling the AccessAnomaly obj's underlying member method code with example usage: obj._train_cf(als, df) and returns: user_mapping_df,  res_mapping_df