{
  "id": 664215,
  "title": "Which Weighted R² should be used for validation / LB matching?",
  "url": "/competitions/csiro-biomass/discussion/664215",
  "author_name": "",
  "post_date": "2025-12-23T07:25:33.511677Z",
  "votes": -1,
  "comment_count": 1,
  "views": 0,
  "content": "<p>I see two common implementations of <strong>Weighted R²</strong> being used across notebooks, and I wanted to clarify whether <strong>both are correct</strong> and which one best matches the leaderboard metric.</p>\n<h3>**Implementation 1 **</h3>\n<pre><code>def weighted_r2_score_lb(y_true: np.ndarray, y_pred: np.ndarray, weights: np.ndarray):\n   r2s = []\n   for i in range(y_true.shape[1]):\n       yt, yp = y_true[:, i], y_pred[:, i]\n       ss_res = np.sum((yt - yp) ** 2)\n       ss_tot = np.sum((yt - yt.mean()) ** 2)\n       r2 = 1.0 - ss_res / ss_tot if ss_tot &gt; 0 else 0.0\n       r2s.append(r2)\n   r2s = np.array(r2s)\n   return np.sum(r2s * weights) / weights.sum(), r2s\n</code></pre>\n<hr>\n<h3>**Implementation 2 **</h3>\n<pre><code>def weighted_r2_score_nb(y_true: np.ndarray, y_pred: np.ndarray):\n   \"\"\"\n   y_true, y_pred: shape (N, 5): Green/Clover/Dead/GDM/Total\n   \"\"\"\n   weights = np.array([0.1, 0.1, 0.1, 0.2, 0.5])\n   r2_scores = []\n   for i in range(5):\n       y_t = y_true[:, i]\n       y_p = y_pred[:, i]\n       ss_res = np.sum((y_t - y_p) ** 2)\n       ss_tot = np.sum((y_t - np.mean(y_t)) ** 2)\n       r2 = 1 - ss_res / ss_tot if ss_tot &gt; 0 else 0.0\n       r2_scores.append(r2)\n   r2_scores = np.array(r2_scores)\n   weighted_r2 = np.sum(r2_scores * weights) / np.sum(weights)\n   return weighted_r2, r2_scores\n</code></pre>",
  "messages": [
    {
      "id": "3380849",
      "postDate": "12/23/2025 07:25:33",
      "content": "<p>I see two common implementations of <strong>Weighted R²</strong> being used across notebooks, and I wanted to clarify whether <strong>both are correct</strong> and which one best matches the leaderboard metric.</p>\n<h3>**Implementation 1 **</h3>\n<pre><code>def weighted_r2_score_lb(y_true: np.ndarray, y_pred: np.ndarray, weights: np.ndarray):\n   r2s = []\n   for i in range(y_true.shape[1]):\n       yt, yp = y_true[:, i], y_pred[:, i]\n       ss_res = np.sum((yt - yp) ** 2)\n       ss_tot = np.sum((yt - yt.mean()) ** 2)\n       r2 = 1.0 - ss_res / ss_tot if ss_tot &gt; 0 else 0.0\n       r2s.append(r2)\n   r2s = np.array(r2s)\n   return np.sum(r2s * weights) / weights.sum(), r2s\n</code></pre>\n<hr>\n<h3>**Implementation 2 **</h3>\n<pre><code>def weighted_r2_score_nb(y_true: np.ndarray, y_pred: np.ndarray):\n   \"\"\"\n   y_true, y_pred: shape (N, 5): Green/Clover/Dead/GDM/Total\n   \"\"\"\n   weights = np.array([0.1, 0.1, 0.1, 0.2, 0.5])\n   r2_scores = []\n   for i in range(5):\n       y_t = y_true[:, i]\n       y_p = y_pred[:, i]\n       ss_res = np.sum((y_t - y_p) ** 2)\n       ss_tot = np.sum((y_t - np.mean(y_t)) ** 2)\n       r2 = 1 - ss_res / ss_tot if ss_tot &gt; 0 else 0.0\n       r2_scores.append(r2)\n   r2_scores = np.array(r2_scores)\n   weighted_r2 = np.sum(r2_scores * weights) / np.sum(weights)\n   return weighted_r2, r2_scores\n</code></pre>",
      "rawMarkdown": "I see two common implementations of **Weighted R²** being used across notebooks, and I wanted to clarify whether **both are correct** and which one best matches the leaderboard metric.\n\n\n### **Implementation 1 **\n\n```python\ndef weighted_r2_score_lb(y_true: np.ndarray, y_pred: np.ndarray, weights: np.ndarray):\n    r2s = []\n    for i in range(y_true.shape[1]):\n        yt, yp = y_true[:, i], y_pred[:, i]\n        ss_res = np.sum((yt - yp) ** 2)\n        ss_tot = np.sum((yt - yt.mean()) ** 2)\n        r2 = 1.0 - ss_res / ss_tot if ss_tot > 0 else 0.0\n        r2s.append(r2)\n    r2s = np.array(r2s)\n    return np.sum(r2s * weights) / weights.sum(), r2s\n```\n---\n\n### **Implementation 2 **\n\n```python\ndef weighted_r2_score_nb(y_true: np.ndarray, y_pred: np.ndarray):\n    \"\"\"\n    y_true, y_pred: shape (N, 5): Green/Clover/Dead/GDM/Total\n    \"\"\"\n    weights = np.array([0.1, 0.1, 0.1, 0.2, 0.5])\n    r2_scores = []\n    for i in range(5):\n        y_t = y_true[:, i]\n        y_p = y_pred[:, i]\n        ss_res = np.sum((y_t - y_p) ** 2)\n        ss_tot = np.sum((y_t - np.mean(y_t)) ** 2)\n        r2 = 1 - ss_res / ss_tot if ss_tot > 0 else 0.0\n        r2_scores.append(r2)\n    r2_scores = np.array(r2_scores)\n    weighted_r2 = np.sum(r2_scores * weights) / np.sum(weights)\n    return weighted_r2, r2_scores\n```",
      "votes": null
    },
    {
      "id": "3380895",
      "postDate": "12/23/2025 09:50:00",
      "content": "<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F21139256%2F88235adb698ec97913d8fdb5b935ee48%2Fsent.jpeg?generation=1766483599413012&amp;alt=media\" alt=\"metric used\">\nI'm using this, matches the implementation mentioned in overview </p>",
      "rawMarkdown": "![metric used](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F21139256%2F88235adb698ec97913d8fdb5b935ee48%2Fsent.jpeg?generation=1766483599413012&alt=media)\nI'm using this, matches the implementation mentioned in overview",
      "votes": null
    }
  ],
  "comments": [
    {
      "id": 3380895,
      "author_name": "harrykesh",
      "author_url": "",
      "post_date": "12/23/2025 09:50:00",
      "content": "<p><img src=\"https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F21139256%2F88235adb698ec97913d8fdb5b935ee48%2Fsent.jpeg?generation=1766483599413012&amp;alt=media\" alt=\"metric used\">\nI'm using this, matches the implementation mentioned in overview </p>",
      "votes": null,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "3380849": "I see two common implementations of **Weighted R²** being used across notebooks, and I wanted to clarify whether **both are correct** and which one best matches the leaderboard metric.\n\n\n### **Implementation 1 **\n\n```python\ndef weighted_r2_score_lb(y_true: np.ndarray, y_pred: np.ndarray, weights: np.ndarray):\n    r2s = []\n    for i in range(y_true.shape[1]):\n        yt, yp = y_true[:, i], y_pred[:, i]\n        ss_res = np.sum((yt - yp) ** 2)\n        ss_tot = np.sum((yt - yt.mean()) ** 2)\n        r2 = 1.0 - ss_res / ss_tot if ss_tot > 0 else 0.0\n        r2s.append(r2)\n    r2s = np.array(r2s)\n    return np.sum(r2s * weights) / weights.sum(), r2s\n```\n---\n\n### **Implementation 2 **\n\n```python\ndef weighted_r2_score_nb(y_true: np.ndarray, y_pred: np.ndarray):\n    \"\"\"\n    y_true, y_pred: shape (N, 5): Green/Clover/Dead/GDM/Total\n    \"\"\"\n    weights = np.array([0.1, 0.1, 0.1, 0.2, 0.5])\n    r2_scores = []\n    for i in range(5):\n        y_t = y_true[:, i]\n        y_p = y_pred[:, i]\n        ss_res = np.sum((y_t - y_p) ** 2)\n        ss_tot = np.sum((y_t - np.mean(y_t)) ** 2)\n        r2 = 1 - ss_res / ss_tot if ss_tot > 0 else 0.0\n        r2_scores.append(r2)\n    r2_scores = np.array(r2_scores)\n    weighted_r2 = np.sum(r2_scores * weights) / np.sum(weights)\n    return weighted_r2, r2_scores\n```",
    "3380895": "![metric used](https://www.googleapis.com/download/storage/v1/b/kaggle-forum-message-attachments/o/inbox%2F21139256%2F88235adb698ec97913d8fdb5b935ee48%2Fsent.jpeg?generation=1766483599413012&alt=media)\nI'm using this, matches the implementation mentioned in overview"
  },
  "source": "meta"
}