{
  "id": 521838,
  "title": "Compact way to calculate (full or partial) score from `train.csv` ",
  "url": "/competitions/rsna-2024-lumbar-spine-degenerative-classification/discussion/521838",
  "author_name": "coderRKJ",
  "post_date": "2024-07-23T07:21:40.081000",
  "votes": 2,
  "comment_count": 0,
  "views": 0,
  "content": "<p>I am sharing a function for calculating score directly from <code>train.csv</code> dataframe. It will automatically filter out any <code>nan</code> row_id values and take common row_id values between <code>train.csv</code> and <code>submission.csv</code> generated by you inference script. Get the latest score function for this competition from <a href=\"https://www.kaggle.com/code/metric/rsna-lumbar-metric-71549\" target=\"_blank\">https://www.kaggle.com/code/metric/rsna-lumbar-metric-71549</a> notebook:</p>\n<pre><code> pandas  pd\n\n ():\n    target_cols, target_weights = (sample_weights.keys()), (sample_weights.values())\n\n    pred = submission.copy() \n    \n    pred[target_cols] = pred[target_cols].div(pred[target_cols].(axis=), axis=)\n\n    \n    unpivoted = train_df.melt(\n        id_vars=, var_name=, value_name=\n    )\n    unpivoted[] = \n    unpivoted[row_id_column_name] = unpivoted[].astype() +  + unpivoted[]\n    solution = unpivoted.pivot(index=row_id_column_name, columns=, values=).fillna()\n\n    \n    solution = solution.rename(columns={np.nan: }).rename(columns= x: x.lower().replace(, ))\n    solution.columns.set_names(, inplace=) \n\n    \n       solution:\n        solution.sample_weight =  - solution.sample_weight\n    :\n        solution[] = \n    solution.sample_weight *= solution[target_cols].apply( row: (target_weights * row).(), axis=, raw=)\n    solution = solution[solution.sample_weight &gt; ].reset_index()\n\n    \n    common_row_df = solution[[row_id_column_name]].merge(pred[[row_id_column_name]], on=row_id_column_name)\n    solution, pred = (\n        solution.merge(common_row_df, how=, on=row_id_column_name),\n        pred.merge(common_row_df, how=, on=row_id_column_name),\n    )\n    \n     score(solution, pred, row_id_column_name, any_severe_scalar)\n</code></pre>\n<p>Example usage:</p>\n<pre><code> pathlib  Path\n\nINPUT_DIR = Path()\nscore_from_train(pd.read_csv(), pd.read_csv(INPUT_DIR / ))\n</code></pre>\n<p>You can use this for calculating CV for entire train images or a subset inside a validation fold. For the latter, pass only the <code>row_id</code> values you want to test on in <code>submission</code>.</p>",
  "messages": [
    {
      "id": 2932720,
      "postDate": "2024-07-23T07:21:40.080Z",
      "content": "<p>I am sharing a function for calculating score directly from <code>train.csv</code> dataframe. It will automatically filter out any <code>nan</code> row_id values and take common row_id values between <code>train.csv</code> and <code>submission.csv</code> generated by you inference script. Get the latest score function for this competition from <a href=\"https://www.kaggle.com/code/metric/rsna-lumbar-metric-71549\" target=\"_blank\">https://www.kaggle.com/code/metric/rsna-lumbar-metric-71549</a> notebook:</p>\n<pre><code> pandas  pd\n\n ():\n    target_cols, target_weights = (sample_weights.keys()), (sample_weights.values())\n\n    pred = submission.copy() \n    \n    pred[target_cols] = pred[target_cols].div(pred[target_cols].(axis=), axis=)\n\n    \n    unpivoted = train_df.melt(\n        id_vars=, var_name=, value_name=\n    )\n    unpivoted[] = \n    unpivoted[row_id_column_name] = unpivoted[].astype() +  + unpivoted[]\n    solution = unpivoted.pivot(index=row_id_column_name, columns=, values=).fillna()\n\n    \n    solution = solution.rename(columns={np.nan: }).rename(columns= x: x.lower().replace(, ))\n    solution.columns.set_names(, inplace=) \n\n    \n       solution:\n        solution.sample_weight =  - solution.sample_weight\n    :\n        solution[] = \n    solution.sample_weight *= solution[target_cols].apply( row: (target_weights * row).(), axis=, raw=)\n    solution = solution[solution.sample_weight &gt; ].reset_index()\n\n    \n    common_row_df = solution[[row_id_column_name]].merge(pred[[row_id_column_name]], on=row_id_column_name)\n    solution, pred = (\n        solution.merge(common_row_df, how=, on=row_id_column_name),\n        pred.merge(common_row_df, how=, on=row_id_column_name),\n    )\n    \n     score(solution, pred, row_id_column_name, any_severe_scalar)\n</code></pre>\n<p>Example usage:</p>\n<pre><code> pathlib  Path\n\nINPUT_DIR = Path()\nscore_from_train(pd.read_csv(), pd.read_csv(INPUT_DIR / ))\n</code></pre>\n<p>You can use this for calculating CV for entire train images or a subset inside a validation fold. For the latter, pass only the <code>row_id</code> values you want to test on in <code>submission</code>.</p>",
      "rawMarkdown": "I am sharing a function for calculating score directly from `train.csv` dataframe. It will automatically filter out any `nan` row_id values and take common row_id values between `train.csv` and `submission.csv` generated by you inference script. Get the latest score function for this competition from https://www.kaggle.com/code/metric/rsna-lumbar-metric-71549 notebook:\n```python\nimport pandas as pd\n\ndef score_from_train(\n    submission: pd.DataFrame,  # Pass submission.csv as a DataFrame\n    train_df: pd.DataFrame,  # Pass train.csv as a DataFrame\n    row_id_column_name=\"row_id\",\n    any_severe_scalar=1.0,\n    sample_weights: dict[str, int]={\"normal_mild\": 1, \"moderate\": 2, \"severe\": 4},\n):\n    target_cols, target_weights = list(sample_weights.keys()), list(sample_weights.values())\n    \n    pred = submission.copy() # Copy to prevent changes in original\n    # Normalize values to have a sum of 1.0\n    pred[target_cols] = pred[target_cols].div(pred[target_cols].sum(axis=1), axis=0)\n\n    # Unpivot and pivot back to get submission format solution\n    unpivoted = train_df.melt(\n        id_vars=\"study_id\", var_name=\"condition_level\", value_name=\"severity\"\n    )\n    unpivoted[\"values\"] = 1.0\n    unpivoted[row_id_column_name] = unpivoted[\"study_id\"].astype(str) + \"_\" + unpivoted[\"condition_level\"]\n    solution = unpivoted.pivot(index=row_id_column_name, columns=\"severity\", values=\"values\").fillna(0.0)\n\n    # Rename columns to submission format and take `nan` column as sample_weight\n    solution = solution.rename(columns={np.nan: \"sample_weight\"}).rename(columns=lambda x: x.lower().replace(\"/\", \"_\"))\n    solution.columns.set_names(None, inplace=True) # Remove severity label \n    \n    # Calculate sample_weight and keep only those with sample_weight > 0.0\n    if \"sample_weight\" in solution:\n        solution.sample_weight = 1.0 - solution.sample_weight\n    else:\n        solution[\"sample_weight\"] = 1.0\n    solution.sample_weight *= solution[target_cols].apply(lambda row: (target_weights * row).sum(), axis=1, raw=True)\n    solution = solution[solution.sample_weight > 0.0].reset_index()\n\n    # Order both dataframes based on common `row_id` values\n    common_row_df = solution[[row_id_column_name]].merge(pred[[row_id_column_name]], on=row_id_column_name)\n    solution, pred = (\n        solution.merge(common_row_df, how=\"right\", on=row_id_column_name),\n        pred.merge(common_row_df, how=\"right\", on=row_id_column_name),\n    )\n    # score from https://www.kaggle.com/code/metric/rsna-lumbar-metric-71549?scriptVersionId=181722791 (Version 10)\n    return score(solution, pred, row_id_column_name, any_severe_scalar)\n```\nExample usage:\n```python\nfrom pathlib import Path\n\nINPUT_DIR = Path(\"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification\")\nscore_from_train(pd.read_csv(\"submission.csv\"), pd.read_csv(INPUT_DIR / \"train.csv\"))\n```\nYou can use this for calculating CV for entire train images or a subset inside a validation fold. For the latter, pass only the `row_id` values you want to test on in `submission`.",
      "votes": 2
    }
  ],
  "comments": [],
  "raw_markdown_by_id": {
    "2932720": "I am sharing a function for calculating score directly from `train.csv` dataframe. It will automatically filter out any `nan` row_id values and take common row_id values between `train.csv` and `submission.csv` generated by you inference script. Get the latest score function for this competition from https://www.kaggle.com/code/metric/rsna-lumbar-metric-71549 notebook:\n```python\nimport pandas as pd\n\ndef score_from_train(\n    submission: pd.DataFrame,  # Pass submission.csv as a DataFrame\n    train_df: pd.DataFrame,  # Pass train.csv as a DataFrame\n    row_id_column_name=\"row_id\",\n    any_severe_scalar=1.0,\n    sample_weights: dict[str, int]={\"normal_mild\": 1, \"moderate\": 2, \"severe\": 4},\n):\n    target_cols, target_weights = list(sample_weights.keys()), list(sample_weights.values())\n    \n    pred = submission.copy() # Copy to prevent changes in original\n    # Normalize values to have a sum of 1.0\n    pred[target_cols] = pred[target_cols].div(pred[target_cols].sum(axis=1), axis=0)\n\n    # Unpivot and pivot back to get submission format solution\n    unpivoted = train_df.melt(\n        id_vars=\"study_id\", var_name=\"condition_level\", value_name=\"severity\"\n    )\n    unpivoted[\"values\"] = 1.0\n    unpivoted[row_id_column_name] = unpivoted[\"study_id\"].astype(str) + \"_\" + unpivoted[\"condition_level\"]\n    solution = unpivoted.pivot(index=row_id_column_name, columns=\"severity\", values=\"values\").fillna(0.0)\n\n    # Rename columns to submission format and take `nan` column as sample_weight\n    solution = solution.rename(columns={np.nan: \"sample_weight\"}).rename(columns=lambda x: x.lower().replace(\"/\", \"_\"))\n    solution.columns.set_names(None, inplace=True) # Remove severity label \n    \n    # Calculate sample_weight and keep only those with sample_weight > 0.0\n    if \"sample_weight\" in solution:\n        solution.sample_weight = 1.0 - solution.sample_weight\n    else:\n        solution[\"sample_weight\"] = 1.0\n    solution.sample_weight *= solution[target_cols].apply(lambda row: (target_weights * row).sum(), axis=1, raw=True)\n    solution = solution[solution.sample_weight > 0.0].reset_index()\n\n    # Order both dataframes based on common `row_id` values\n    common_row_df = solution[[row_id_column_name]].merge(pred[[row_id_column_name]], on=row_id_column_name)\n    solution, pred = (\n        solution.merge(common_row_df, how=\"right\", on=row_id_column_name),\n        pred.merge(common_row_df, how=\"right\", on=row_id_column_name),\n    )\n    # score from https://www.kaggle.com/code/metric/rsna-lumbar-metric-71549?scriptVersionId=181722791 (Version 10)\n    return score(solution, pred, row_id_column_name, any_severe_scalar)\n```\nExample usage:\n```python\nfrom pathlib import Path\n\nINPUT_DIR = Path(\"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification\")\nscore_from_train(pd.read_csv(\"submission.csv\"), pd.read_csv(INPUT_DIR / \"train.csv\"))\n```\nYou can use this for calculating CV for entire train images or a subset inside a validation fold. For the latter, pass only the `row_id` values you want to test on in `submission`."
  }
}