Der Brier-Wert ist ein effizientes und einfaches Maß zur Bewertung der Genauigkeit probabilistischer Vorhersagen. Durch die Kombination aus einfacher Berechnung und aussagekräftiger Analyse ist er ein weit verbreitetes Werkzeug in der Statistik und im maschinellen Lernen.
In der Praxis hilft er, die Qualität von Vorhersagen quantitativ zu bewerten und kann zur Verbesserung von Modellen und Algorithmen beitragen. Die Bezeichnung „Brier-Wert“ stammt von dem amerikanischen Meteorologen Glenn W. Brier, der das Maß (1950 – VERIFICATION OF FORECASTS EXPRESSED IN TERMS OF PROBABILITY) entwickelte und damit die Grundlage legte.
Der Brier-Wert wird häufig in Bereichen wie Meteorologie, Medizin, Finanzwesen, Wahlprognosen und maschinellem Lernen verwendet, um die Genauigkeit von Prognosen zu bewerten. Er ist besonders nützlich bei binären Klassifikationsproblemen, bei denen das Modell Wahrscheinlichkeiten für die Zugehörigkeit zu einer von zwei Klassen liefert (z. B. Regenwahrscheinlichkeit).
Wir erstellen zur Verdeutlichung mal ein JSon Datei mit ein paar Daten von der Reserve Bank of Australia, die bei ihren monatlichen Sitzungen Zinssätze beschließt. Die RBA lässt die Zinssätze im Allgemeinen unverändert, erhöht sie jedoch manchmal und senkt sie manchmal, je nach wirtschaftlicher Lage. Die Daten stammen aus diesem Artikel und wurden von mir in das JSon-Format überführt.
Wir erstellen nun die input.json Datei mit diesem Inhalt.
1 2 3 4 5 |
{ "comment": "Daten siehe https://timvangelder.com/2015/05/18/brier-score-composition-a-mini-tutorial/", "forecasts": [0.71, 0.71, 0.7, 0.68, 0.64, 0.65, 0.67], "outcomes": [1, 1, 1, 0, 1, 1, 0] } |
Nun brauchen wir noch ein Java-Programm das die Datei einliest und den Brier-Score berechnet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
package de.wenzlaff.mathe; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import org.json.JSONArray; import org.json.JSONObject; /** * Der Brier-Wert ist ein Maß zur Bewertung von Prognosen und * Wahrscheinlichkeiten. * * Der Brier-Wert (englisch "Brier Score") ist eine wichtige Metrik zur * Bewertung der Genauigkeit von Wahrscheinlichkeitsprognosen, insbesondere im * Bereich maschinellen Lernens, der Statistik und bei Vorhersagemodellen. Der * Brier-Wert hilft dabei, die Genauigkeit einer Vorhersage zu quantifizieren, * indem er die Differenz zwischen vorhergesagten Wahrscheinlichkeiten und den * tatsächlich eingetretenen Ergebnissen misst. Dieser BrierScoreCalculator * liest eine JSon Datei in der Form: * * <pre> { "forecasts": [0.8, 0.6, 0.2, 0.9, 0.1], "outcomes": [1, 1, 0, 1, 0] } * * </pre> * * ein und gibt das berechnete Ergebnis des Brier-Wert und die Inputwert in * einer Tabelle aus. z.B. * * <pre> Index Vorhersage Ergebnis (1=eingetreten, 0=nicht eingetreten) ------------------------------------- 1 0,80 1 2 0,60 1 3 0,20 0 4 0,90 1 5 0,10 0 ------------------------------------- Brier-Wert: 0,0520 * * </pre> * <p> * Der Brier-Wert wird wie folgt berechnet: * * <pre> * Brier-Wert = (1 / n) * Σ (forecastᵢ - outcomeᵢ)² * </pre> * * wobei: * <ul> * <li>n = Anzahl der Vorhersagen</li> * <li>forecastᵢ = Wahrscheinlichkeitsvorhersage für das Ereignis i</li> * <li>outcomeᵢ = tatsächliches Ergebnis des Ereignisses i (1 für eingetreten, 0 * für nicht eingetreten)</li> * </ul> * * @author Thomas Wenzlaff */ public class BrierScoreCalculator { public static void main(String[] args) { // Überprüfen, ob der Dateipfad als Argument übergeben wurde if (args.length != 1) { System.out.println("Bitte geben Sie den Pfad zur JSON-Datei als Argument an."); System.out.println("Beispiel: java BrierScoreCalculator input.json"); return; } // Dateipfad zur JSON-Datei String jsonFilePath = args[0]; try { // JSON-Datei laden und als String einlesen String content = new String(Files.readAllBytes(Paths.get(jsonFilePath))); // JSON-Objekt erstellen und Arrays extrahieren JSONObject jsonObject = new JSONObject(content); JSONArray forecastsArray = jsonObject.getJSONArray("forecasts"); JSONArray outcomesArray = jsonObject.getJSONArray("outcomes"); double[] forecasts = new double[forecastsArray.length()];// Vorhergesagte Wahrscheinlichkeiten int[] outcomes = new int[outcomesArray.length()]; // Tatsächliche Ergebnisse // (1 = Ereignis eingetreten, 0 = Ereignis nicht eingetreten for (int i = 0; i < forecastsArray.length(); i++) { forecasts[i] = forecastsArray.getDouble(i); outcomes[i] = outcomesArray.getInt(i); } double brierScore = berechneBrierScore(forecasts, outcomes); printResult(forecasts, outcomes, brierScore); } catch (IOException e) { System.out.println("Fehler beim Lesen der JSON-Datei: " + e.getMessage()); } catch (Exception e) { System.out.println("Fehler: " + e.getMessage()); } } /** * Methode zur Berechnung des Brier-Wertes. * * <p> * Der Brier-Wert wird wie folgt berechnet: * * <pre> * Brier-Wert = (1 / n) * Σ (forecastᵢ - outcomeᵢ)² * </pre> * * wobei: * <ul> * <li>n = Anzahl der Vorhersagen</li> * <li>forecastᵢ = Wahrscheinlichkeitsvorhersage für das Ereignis i</li> * <li>outcomeᵢ = tatsächliches Ergebnis des Ereignisses i (1 für eingetreten, 0 * für nicht eingetreten)</li> * </ul> * * @param forecasts Array von Wahrscheinlichkeitsvorhersagen * @param outcomes Array von tatsächlichen Ergebnissen (1 für Eintreten, 0 für * Nichteintreten) * @return Brier-Wert als double */ public static double berechneBrierScore(double[] forecasts, int[] outcomes) { if (forecasts.length != outcomes.length) { throw new IllegalArgumentException("Vorhersagen und Ergebnisse müssen die gleiche Länge haben."); } double totalError = 0.0; int n = forecasts.length; for (int i = 0; i < n; i++) { double error = forecasts[i] - outcomes[i]; totalError += error * error; } return totalError / n; // Durchschnittlicher quadratischer Fehler } /** * Methode zur Ausgabe der Vorhersagen und Ergebnisse als Tabelle * * @param forecasts Array mit Wahrscheinlichkeitsvorhersagen * @param outcomes Array mit tatsächlichen Ergebnissen (1 oder 0) * @param brierScore der berechnete Brier-Wert */ public static void printResult(double[] forecasts, int[] outcomes, double brierScore) { if (forecasts.length != outcomes.length) { System.err.println("Fehler: Die Arrays 'forecasts' und 'outcomes' müssen dieselbe Länge haben."); return; } System.out.printf("%-10s %-15s %-10s%n", "Index", "Vorhersage", "Ergebnis"); System.out.println("-------------------------------------"); // Durch die Arrays iterieren und die Daten ausgeben for (int i = 0; i < forecasts.length; i++) { System.out.printf("%-10d %-15.2f %-10d%n", i + 1, forecasts[i], outcomes[i]); } System.out.println("-------------------------------------"); System.out.printf("Brier-Wert: %.4f%n", brierScore); } } |
Für die pom.xml brauchen wir noch die JSon-Libs:
1 2 3 4 5 6 |
<dependency> <!-- Für den BrierScoreCalculator--> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20210307</version> </dependency> |
Wenn wir das Programm nun mit Java 21 starten, können wir die Java-Datei direkt auf der CMD aufrufen (oder in der IDE starten), dazu in der Verzeichnis mit der BrierScoreCalculator.java gehen und:
java -cp .m2/repository/org/json/json/20210307/json-20210307.jar BrierScoreCalculator.java /Users/pi/eclipse-workspace-2024/twmathe/input-brier-score-wetter.json
Wir erhalten dann als Ergebnis:
1 2 3 4 5 6 7 8 9 10 11 |
Index Vorhersage Ergebnis ------------------------------------- 1 0,71 1 2 0,71 1 3 0,70 1 4 0,68 0 5 0,64 1 6 0,65 1 7 0,67 0 ------------------------------------- Brier-Wert: 0,2031 |
Eine JUnit Testmethode könnte so aussehen:
1 2 3 4 5 6 7 |
@Test void berechneBrierScore() { double[] forecasts = { 0.71, 0.71, 0.7, 0.68, 0.64, 0.65, 0.67 }; int[] outcomes = { 1, 1, 1, 0, 1, 1, 0 }; assertEquals(0.2030857142857143, BrierScoreCalculator.berechneBrierScore(forecasts, outcomes)); } |
Das ganze Projekt gibt es auf meinem GitLab-Repo.