連續分級機率評分(Continuous Ranked Probability Score, CRPS)或「連續機率排位分數」是一個函數或統計量,可以將分佈預測與真實值進行比較。
機器學習工作流程的一個重要部分是模型評估。這個過程本身可以被認為是常識:將資料分成訓練集和測試集,在訓練集上訓練模型,並使用評分函數評估其在測試集上的表現。
評分函數(或測量)是將真實值及其預測映射到單一且可比較的值 [1]。例如,對於連續預測可以使用 RMSE、MAE、MAPE 或 R 平方等評分函數。如果預測不是逐點估計,而是分佈呢?
在貝葉斯機器學習中,預測通常不是逐點估計,而是值的分佈。例如預測可以是分佈的估計參數,或是在非參數情況下,來自MCMC方法的樣本陣列。
在這種情況下,傳統的評分函數不適合統計設計;預測的分佈聚合成它們的平均值或中位數會導致關於預測分佈的分散和形狀的大量資訊的損失。
連續分級機率評分(CRPS)是一個分數函數,它將單一真實值與累積分佈函數(CDF)進行比較:
它在70 年代首次引入[4],主要用於天氣預報,現在在文獻和行業中重新受到關注[1] [6]。當目標變數是連續的並且模型預測目標的分佈時,它可以用作評估模型性能的指標;示例包括貝葉斯回歸或貝葉斯時間序列模型 [5]。
透過使用CDF, CRPS 對於參數和非參數預測都很有用:對於許多分佈,CRPS [3] 都有解析表達式,對於非參數預測, CRPS 使用經驗累積分佈函數(eCDF) 。
在計算測試集中每個觀察值的 CRPS 後,還需要將結果聚集成一個值。與RMSE 和MAE 類似,使用(可能是加權的)平均值對它們進行匯總:
將單一值與分佈進行比較的主要挑戰是如何將單一值轉換成為分佈的表示。 CRPS透過將基本真值轉換為帶有指標函數的退化分佈來解決這一問題。例如如果真值是7,我們可以用:
指標函數是有效的 CDF,可以滿足 CDF 的所有要求。然後就可以將預測分佈與真值的退化分佈進行比較。我們肯定希望預測的分佈盡可能接近真實情況;所以可以透過測量這兩個CDF 之間的(平方)面積來數學表示:
##MAE與MAE關係CRPS與著名的MAE(平均絕對誤差)密切相關。如果採用逐點預測將其視為退化CDF 並將其註入CRPS 方程式可以得到: 所以如果預測分佈是退化分佈(例如逐點估計),則CRPS 會降低為MAE。這有助於我們從另一個角度理解CRPS:它可以被視為將 MAE 推廣到分佈的預測中,或者說當預測分佈退化時,MAE 是 CRPS 的特殊情況。 當模型的預測是參數分佈時(例如需要預測分佈參數),CRPS 對一些常見的分佈有一個解析表達式 [3]。如果模型預測常態分佈的參數μ 和σ,則可以使用下列公式計算CRPS: 這個方案可以解決已知的分佈,如Beta, Gamma, Logistic ,對數常態分佈和其他[3]。 當預測是非參數的,或者更具體地說——預測是一系列模擬時,計算 eCDF 是一項繁重的任務。但是CRPS 也可以表示為:其中 X, X' 是 F 獨立同分佈。這些表達式雖然仍然需要一些計算量,但更容易計算。
import numpy as np # Adapted to numpy from pyro.ops.stats.crps_empirical # Copyright (c) 2017-2019 Uber Technologies, Inc. # SPDX-License-Identifier: Apache-2.0 def crps(y_true, y_pred, sample_weight=None): num_samples = y_pred.shape[0] absolute_error = np.mean(np.abs(y_pred - y_true), axis=0) if num_samples == 1: return np.average(absolute_error, weights=sample_weight) y_pred = np.sort(y_pred, axis=0) diff = y_pred[1:] - y_pred[:-1] weight = np.arange(1, num_samples) * np.arange(num_samples - 1, 0, -1) weight = np.expand_dims(weight, -1) per_obs_crps = absolute_error - np.sum(diff * weight, axis=0) / num_samples**2 return np.average(per_obs_crps, weights=sample_weight)
根據NRG形式[2]實現的CRPS函數。改編自pyroppl[6]
import numpy as np def crps(y_true, y_pred, sample_weight=None): num_samples = y_pred.shape[0] absolute_error = np.mean(np.abs(y_pred - y_true), axis=0) if num_samples == 1: return np.average(absolute_error, weights=sample_weight) y_pred = np.sort(y_pred, axis=0) b0 = y_pred.mean(axis=0) b1_values = y_pred * np.arange(num_samples).reshape((num_samples, 1)) b1 = b1_values.mean(axis=0) / num_samples per_obs_crps = absolute_error + b0 - 2 * b1 return np.average(per_obs_crps, weights=sample_weight)
上面程式碼是根據PWM形式[2]實作CRPS。
連續分級機率評分 (CRPS) 是一種評分函數,用於將單一真實值與其預測分佈進行比較。此屬性使其與貝葉斯機器學習相關,其中模型通常輸出分佈預測而不是逐點估計。它可以看作是眾所周知的 MAE 對分佈預測的推廣。
它具有用於參數預測的解析表達式,並且可以針對非參數預測進行簡單計算。 CRPS 可能會成為評估具有連續目標的貝葉斯機器學習模型性能的新標準方法。
以上是CRPS:貝葉斯機器學習模型的評分函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!