def get_incorrect_aggregates_final_scoring(
  ratings: pd.DataFrame,
  noteParams: pd.DataFrame,
  raterParamsWithRatingCounts: pd.DataFrame,
) -> pd.DataFrame:
  """Computes non-helpful tag aggregates for each note. Intended to be called in final scoring.

  Args:
    ratings: initial input ratings DF containing all ratings
    noteParams: MF results for notes
    raterParamsWithRatingCounts: MF results for raters. Should include c.incorrectTagRatingsMadeByRaterKey and c.totalRatingsMadeByRaterKey.
    raterIncorrectTagRatingCounts: should contain: c.raterParticipantIdKey,

  Returns:
    pd.DataFrame containing one row per note that was scored during MF.  Columns correspond to
    aggregates for the Not-Helpful tags, including raw totals, totals adjusted based on the
    distance between the rater and the note and ratios based on the adjusted weight totals.
  """
  # consider only ratings with some NH tag
  notHelpfulTaggedRatings = ratings.loc[ratings[c.notHelpfulTagsTSVOrder].sum(axis=1) > 0]

  # join user totals, note factors, and rater factors with each rating
  ratings_w_user_totals = (
    notHelpfulTaggedRatings[[c.raterParticipantIdKey, c.noteIdKey, c.notHelpfulIncorrectTagKey]]
    .merge(noteParams[[c.noteIdKey, c.internalNoteFactor1Key]], on=c.noteIdKey)
    .merge(
      raterParamsWithRatingCounts[
        [
          c.raterParticipantIdKey,
          c.internalRaterFactor1Key,
          c.incorrectTagRatingsMadeByRaterKey,
          c.totalRatingsMadeByRaterKey,
        ]
      ],
      on=c.raterParticipantIdKey,
    )
  )

  # Keep users with clipped factors within a certain interval of notes' (e.g. within 0.3)
  interval_filter = (
    np.abs(
      ratings_w_user_totals[c.internalRaterFactor1Key].clip(-0.4, 0.4)
      - ratings_w_user_totals[c.internalNoteFactor1Key].clip(-0.4, 0.4)
    )
    < c.intervalHalfWidth
  )

  incorrectAggregates = _get_incorrect_tfidf_ratio(ratings_w_user_totals, interval_filter)
  return incorrectAggregates
Computes non-helpful tag aggregates for each note. Intended to be called in final scoring.

  Args:
    ratings: initial input ratings DF containing all ratings
    noteParams: MF results for notes
    raterParamsWithRatingCounts: MF results for raters. Should include c.incorrectTagRatingsMadeByRaterKey and c.totalRatingsMadeByRaterKey.
    raterIncorrectTagRatingCounts: should contain: c.raterParticipantIdKey,

  Returns:
    pd.DataFrame containing one row per note that was scored during MF.  Columns correspond to
    aggregates for the Not-Helpful tags, including raw totals, totals adjusted based on the
    distance between the rater and the note and ratios based on the adjusted weight totals.
  
sourcecode/scoring/incorrect_filter.py