0 Daumen
282 Aufrufe

Aufgabe (Effizienz: Stichprobenvarianz):

Betrachten Sie die folgende Funktion zur Berechnung der Stichprobenvarianz für einen numerischen Vektor x:

myvar1 <- function(x) {
    erg <- NULL
    for(i in 1:length(x)) {
      erg <- c(erg, 1 / (length(x) - 1) * (x[i] - mean(x))^2)
    }
    erg <- sum(erg)
    return(erg)
  }

a) Die Funktion ist extrem ineffizient programmiert. Versuchen Sie die Funktion nun zu verbessern. Schreiben Sie eine Funktion myvar2. Zunächst soll dabei allerdings weiterhin eine for-Schleife verwendet werden.

b) Für eine weitere Verbesserung hinsichtlich der Effizienz schreiben Sie eine vektorisierte Variante myvar3 ohne die Verwendung der Funktion var aus R.

Avatar von

1 Antwort

0 Daumen

Antwort mit KI erzeugt

Teil a: Verbesserung mit for-Schleife

Zur Verbesserung der ursprünglichen Funktion myvar1 können wir den gleichen Algorithmus verwenden, aber den Mittelwert von x nur einmal berechnen, anstatt ihn in jeder Iteration der Schleife zu berechnen. Diese Optimierung reduziert die Anzahl der Operationen erheblich, insbesondere bei großen Datenmengen.

R
myvar2 <- function(x) {
  n <- length(x)
  mean_x <- mean(x)
  erg <- 0
  for(i in 1:n) {
    erg <- erg + ((x[i] - mean_x)^2) / (n - 1)
  }
  return(erg)
}


In dieser verbesserten Version berechnen wir zuerst den Mittelwert von x und verwenden diesen wiederholt in der Schleife. Dadurch wird die Effizienz im Vergleich zur ursprünglichen Implementierung verbessert.

Teil b: Vektorisierte Version

Die vektorisierte Variante, myvar3, macht von der Tatsache Gebrauch, dass Operationen auf ganzen Vektoren in R effizienter durchgeführt werden können als Schleifen über einzelne Elemente. Wir können die Formel für die Varianz direkt auf den gesamten Datensatz anwenden, ohne eine explizite Schleife zu verwenden.

R
myvar3 <- function(x) {
  n <- length(x)
  mean_x <- mean(x)
  erg <- sum((x - mean_x)^2) / (n - 1)
  return(erg)
}


In dieser Version wird zuerst der Mittelwert von x berechnet. Dann subtrahieren wir diesen Mittelwert von jedem Element in x, quadrieren die Differenzen, summieren diese und teilen schließlich durch \(n - 1\), wobei \(n\) die Länge von x ist. Diese Implementierung nutzt die vektorisierten Operationen von R und sollte wesentlich effizienter sein als die ursprüngliche Funktion oder die verbesserte Version mit for-Schleife.

Beide Verbesserungen nutzen Grundprinzipien der effizienten Programmierung in R: Vermeidung unnötiger Berechnungen innerhalb von Schleifen und, wo möglich, den Einsatz vektorisierter Operationen, die in R typischerweise deutlich schneller ausgeführt werden als explizite Schleifen über Elemente.
Avatar von 4,6 k

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community