it-swarm.com.de

Funktion zur Berechnung von R2 (R-Quadrat) in R

Ich habe ein Datenfeld mit beobachteten und modellierten Daten, und ich möchte den R2-Wert berechnen. Ich habe erwartet, dass es eine Funktion gibt, die ich dafür aufrufen könnte, aber keine finden kann. Ich weiß, dass ich eigene schreiben und anwenden kann, aber fehlt mir etwas Offensichtliches? Ich will so etwas

obs <- 1:5
mod <- c(0.8,2.4,2,3,4.8)
df <- data.frame(obs, mod)

R2 <- rsq(df)
# 0.85
11
Esme_

Sie benötigen ein wenig statistisches Wissen, um dies zu sehen. R-Quadrat zwischen zwei Vektoren ist gerade das Quadrat ihrer Korrelation . So können Sie Ihre Funktion definieren als:

rsq <- function (x, y) cor(x, y) ^ 2

Sandipans Antwort gibt genau das gleiche Ergebnis zurück (siehe folgenden Beweis), aber so wie es aussieht, erscheint es lesbarer (aufgrund des offensichtlichen $r.squared).


Lass uns die Statistiken machen

Grundsätzlich passen wir eine lineare Regression von y über x an und berechnen das Verhältnis der Regressionssumme der Quadrate zur Gesamtsumme der Quadrate.

Lemma 1: Eine Regression y ~ x entspricht y - mean(y) ~ x - mean(x)

 lemma 1

Lemma 2: beta = cov (x, y)/var (x)

 lemma 2

Lemma 3: Rsquare = cor (x, y) ^ 2

 lemma 3


Warnung

R zwischen zwei willkürlichen Vektoren x und y (von gleicher Länge) ist nur ein Gütemaß ihrer linearen Beziehung. Denke nochmal nach!! Das Quadrat zwischen x + a und y + b ist für jede konstante Verschiebung a und b identisch. Es ist also ein schwacher oder sogar nutzloser Maßstab für "Güte der Vorhersage". Verwenden Sie stattdessen MSE oder RMSE:

Ich stimme dem Kommentar von 42 -s zu:

Das R-Quadrat wird von zusammenfassenden Funktionen gemeldet, die mit Regressionsfunktionen verknüpft sind. Aber nur, wenn eine solche Schätzung statistisch gerechtfertigt ist. 

R-Quadrat kann ein (aber nicht das beste) Maß für "Anpassungsgüte" sein. Es gibt jedoch keinen Grund, die Güte der Prognose außerhalb der Stichprobe zu messen. Wenn Sie Ihre Daten in Trainings- und Testteile aufteilen und ein Regressionsmodell für das Trainingsmodell verwenden, können Sie einen gültigen R-Quadratwert für den Trainingsteil erhalten, aber Sie können ein R-Quadrat für den Testteil nicht rechtmäßig berechnen. Einige Leute haben das getan , aber ich stimme dem nicht zu.

Hier ist ein extremes Beispiel:

preds <- 1:4/4
actual <- 1:4

Das R-Quadrat zwischen diesen beiden Vektoren ist 1. Ja, natürlich ist einer nur eine lineare Neuskalierung des anderen, so dass sie eine perfekte lineare Beziehung haben. Aber glauben Sie wirklich, dass preds eine gute Vorhersage für actual ist?


In Erwiderung auf Wörterfürheweis

Vielen Dank für Ihre Kommentare 1 , 2 und Ihre Antwort auf Details .

Sie haben das Verfahren wahrscheinlich falsch verstanden. Bei zwei Vektoren x und y passen wir zuerst eine Regressionslinie y ~ x an und berechnen dann die Regressionssumme der Quadrate und die Gesamtsumme der Quadrate. Es scheint, dass Sie diesen Regressionsschritt überspringen und direkt zur Summe der Quadratberechnung gehen. Das ist falsch, da die Aufteilung der Quadratsumme nicht gilt und Sie können R-Quadrate nicht konsistent berechnen.

Wie Sie gezeigt haben, ist dies nur ein Weg zum Berechnen von R-Quadrat:

preds <- c(1, 2, 3)
actual <- c(2, 2, 4)
rss <- sum((preds - actual) ^ 2)  ## residual sum of squares
tss <- sum((actual - mean(actual)) ^ 2)  ## total sum of squares
rsq <- 1 - rss/tss
#[1] 0.25

Aber es gibt noch einen anderen:

regss <- sum((preds - mean(preds)) ^ 2) ## regression sum of squares
regss / tss
#[1] 0.75

Außerdem kann Ihre Formel einen negativen Wert angeben (der richtige Wert sollte 1 sein, wie oben im Abschnitt Warning erwähnt).

preds <- 1:4 / 4
actual <- 1:4
rss <- sum((preds - actual) ^ 2)  ## residual sum of squares
tss <- sum((actual - mean(actual)) ^ 2)  ## total sum of squares
rsq <- 1 - rss/tss
#[1] -2.375

Schlussbemerkung

Ich hatte nie erwartet, dass diese Antwort irgendwann so lange dauern würde, als ich vor 2 Jahren meine erste Antwort veröffentlichte. Angesichts der hohen Ansichten dieses Threads fühle ich mich jedoch gezwungen, weitere statistische Details und Diskussionen hinzuzufügen. Ich möchte die Leute nicht irreführen, nur weil sie ein R-Quadrat so leicht berechnen können, können sie das R-Quadrat überall verwenden.

19
李哲源

Warum nicht das:

rsq <- function(x, y) summary(lm(y~x))$r.squared
rsq(obs, mod)
#[1] 0.8560185
9
Sandipan Dey

Es ist nicht offensichtlich, aber das caret-Paket hat eine Funktion postResample(), die "einen Vektor von Leistungsschätzungen" gemäß der Dokumentation berechnet. Die "Leistungsschätzungen" sind 

  • RMSE
  • Rsquared
  • mittlerer absoluter Fehler (MAE)

und müssen wie folgt aus dem Vektor abgerufen werden

library(caret)
vect1 <- c(1, 2, 3)
vect2 <- c(3, 2, 2)
res <- caret::postResample(vect1, vect2)
rsq <- res[2]

Hierbei wird jedoch die Korrelationsquadratnäherung für r-Quadrat verwendet, wie in einer anderen Antwort erwähnt. Warum sie nicht einfach das herkömmliche 1-SSE/SST verwendet haben, ist mir unverständlich.

Die Implementierung der Normal Bestimmungskoeffizientengleichung lautet:

preds <- c(1, 2, 3)
actual <- c(2, 2, 4)
rss <- sum((preds - actual) ^ 2)
tss <- sum((actual - mean(actual)) ^ 2)
rsq <- 1 - rss/tss

Natürlich nicht schlecht, um von Hand zu programmieren, aber warum gibt es dafür nicht eine Funktion in einer Sprache, die hauptsächlich für Statistiken gedacht ist? Ich denke, mir fehlt noch irgendwo die Implementierung von R ^ 2.

5
wordsforthewise

Sie können die Zusammenfassung auch für lineare Modelle verwenden:

summary(lm(obs ~ mod, data=df))$r.squared 
3
Maria

Hier ist die einfachste Lösung basierend auf [ https://de.wikipedia.org/wiki/Coefficient_of_determination]

# 1. 'Actual' and 'Predicted' data
df <- data.frame(
  y_actual = c(1:5),
  y_predicted  = c(0.8, 2.4, 2, 3, 4.8))

# 2. R2 Score components

# 2.1. Average of actual data
avr_y_actual <- mean(df$y_actual)

# 2.2. Total sum of squares
ss_total <- sum((df$y_actual - avr_y_actual)^2)

# 2.3. Regression sum of squares
ss_regression <- sum((df$y_predicted - avr_y_actual)^2)

# 2.4. Residual sum of squares
ss_residuals <- sum((df$y_actual - df$y_predicted)^2)

# 3. R2 Score
r2 <- 1 - ss_residuals / ss_total
0
andrii