mlebench/competitions/h-and-m-personalized-fashion-recommendations/grade.py (27 lines of code) (raw):

import pandas as pd from mlebench.grade_helpers import InvalidSubmissionError from mlebench.metrics import mean_average_precision_at_k def prepare_for_metric(submission: pd.DataFrame, answers: pd.DataFrame) -> dict: # Answers checks assert set(answers.columns) == { "customer_id", "prediction", }, "Answers DataFrame must have 'customer_id' and 'prediction' columns." # Submission checks if set(submission.columns) != {"customer_id", "prediction"}: raise InvalidSubmissionError( "Submission DataFrame must have 'customer_id' and 'prediction' columns." ) if not (set(submission["customer_id"]) >= set(answers["customer_id"])): raise InvalidSubmissionError( "Submission customer_id must be a superset of answers customer_id" ) # Filter the submission to only consider the customer_ids that exist in answers submission = submission[submission["customer_id"].isin(answers["customer_id"])] # Sort to ensure we're grading the right rows submission = submission.sort_values("customer_id").reset_index(drop=True) answers = answers.sort_values("customer_id").reset_index(drop=True) y_true = answers["prediction"].astype(str).str.split(" ").apply(set).tolist() y_pred = submission["prediction"].astype(str).str.split(" ").tolist() return {"actual": y_true, "predicted": y_pred} def grade(submission: pd.DataFrame, answers: pd.DataFrame) -> float: # Prepare the data for metric calculation prepped = prepare_for_metric(submission, answers) return mean_average_precision_at_k( actual=prepped["actual"], predicted=prepped["predicted"], k=12 )