docs: def roc(self, num_thresholds, target_class, probability_column=None):
      """Get true positive rate, false positive rate values from evaluation results.
  
      Args:
        num_thresholds: an integer. Number of thresholds.
        target_class: a string indciating the target class, i.e. "daisy" in flower classification.
        probability_column: the name of the probability column. If None, defaults to
            value of target_class.
  
      Returns:
        A DataFrame with columns: 'tpr', 'fpr', 'threshold' with number of rows
        equal to num_thresholds.
  
      Raises:
        Exception if the CSV headers do not include 'target' or probability_column, or BigQuery
        does not return 'target' or probability_column column.
      """
  
      if not probability_column:
        probability_column = target_class
  
      thresholds = np.linspace(0, 1, num_thresholds + 1)
      if self._input_csv_files:
        df = self._get_data_from_csv_files()
        if 'target' not in df or probability_column not in df:
          raise ValueError('Cannot find "target" or "%s" column' % probability_column)
  
        total_positive = sum(1 for x in df['target'] if x == target_class)
        total_negative = len(df) - total_positive
        true_positives, false_positives = [], []
        for threshold in thresholds:
          true_positive_count = len(df[(df[probability_column] > threshold) &
                                    (df['target'] == target_class)])
          false_positive_count = len(df[(df[probability_column] > threshold) &
                                     (df['target'] != target_class)])
          true_positives.append(true_positive_count)
          false_positives.append(false_positive_count)
  
        data = []
        for tp, fp, t in zip(true_positives, false_positives, thresholds):
          tpr = (float)(tp) / total_positive if total_positive > 0. else 0.
          fpr = (float)(fp) / total_negative if total_negative > 0. else 0.
          data.append({'tpr': tpr, 'fpr': fpr, 'threshold': t})
        return pd.DataFrame(data)
  
      elif self._bigquery:
        true_positive_query = bq.Query("""
          SELECT
            COUNT(*) as true_positive
          FROM
            %s
          CROSS JOIN
            (SELECT * FROM UNNEST ([%s]) as t)
          WHERE
            %s > t AND target = '%s'
          GROUP BY t
          ORDER BY t
        """ % (self._bigquery, ','.join(map(str, thresholds)), probability_column, target_class))
  
        false_positive_query = bq.Query("""
          SELECT
            COUNT(*) as false_positive
          FROM
            %s
          CROSS JOIN
            (SELECT * FROM UNNEST ([%s]) as t)
          WHERE
            %s > t AND target != '%s'
          GROUP BY t
          ORDER BY t
        """ % (self._bigquery, ','.join(map(str, thresholds)), probability_column, target_class))
  
        total_positive_query = bq.Query("""
          SELECT
            COUNT(*) as total_positive
          FROM
            %s
          WHERE
            target = '%s'
        """ % (self._bigquery, target_class))
  
        total_negative_query = bq.Query("""
          SELECT
            COUNT(*) as total_negative
          FROM
            %s
          WHERE
            target != '%s'
        """ % (self._bigquery, target_class))
  
        true_positives = true_positive_query.execute().result()
        false_positives = false_positive_query.execute().result()
        total_positive = total_positive_query.execute().result()[0]['total_positive']
        total_negative = total_negative_query.execute().result()[0]['total_negative']
        data = []
        for tp, fp, t in zip(true_positives, false_positives, thresholds):
          tpr = (float)(tp['true_positive']) / total_positive if total_positive > 0. else 0.
          fpr = (float)(fp['false_positive']) / total_negative if total_negative > 0. else 0.
          data.append({'tpr': tpr, 'fpr': fpr, 'threshold': t})
        data.append({'tpr': 0., 'fpr': 0., 'threshold': 1.0})
        return pd.DataFrame(data)