Frage

Ich habe nicht wirklich Varianzberechnung verwendet, die viel, und ich weiß nicht genau, was zu erwarten ist. Eigentlich bin ich nicht so gut mit Mathe überhaupt.

Ich habe eine eine Reihe von 1000000 Zufallszahlenwerten im Bereich von 0 bis 10.000.

Das Array könnte wachsen sogar noch größer, so dass ich für 64-Bit-Summe int verwenden.

Ich habe versucht, den Code zu finden, wie man berechnet Varianz, aber ich weiß nicht, ob ich eine korrekte Ausgabe zu bekommen.

Der Mittelwert ist 4692 und Median ist 4533. Ich erhalte Varianz 1483780,469308 mit dem folgenden Code:

// size is the element count, in this case 1000000
// value_sum is __int64

double p2 = pow( (double)(value_sum - (value_sum/size)), (double)2.0 );
double variance = sqrt( (double)(p2 / (size-1)) );

Bin ich einen vernünftigen Wert zu bekommen?

Ist etwas nicht in Ordnung mit der Berechnung?

War es hilfreich?

Lösung

. Hinweis: Es sieht nicht wie Sie die Varianz sind die Berechnung

Variance wird berechnet, indem der Mittelwert von jedem Element abgezogen und der gewichteten Summe dieser Differenzen zu berechnen.

Also, was Sie tun müssen, ist:

// Get mean
double mean = static_cast<double>(value_sum)/size;

// Calculate variance
double variance = 0;
for(int i = 0;i<size;++i) 
{
  variance += (MyArray[i]-mean)*(MyArray[i]-mean)/size;
}

// Display
cout<<variance;

Beachten Sie, dass dies die Stichprobenvarianz ist, und wird verwendet, wenn die zugrunde liegende Verteilung unbekannt ist (so dass wir eine gleichmäßige Verteilung übernehmen).

Auch nach den einige Graben um, fand ich, dass dies nicht ein unverzerrter Schätzer ist. Wolfram Alpha hat etwas dazu zu sagen, aber als Beispiel, wenn MATLAB berechnet die Varianz, es gibt den "Bias-korrigierte Stichprobenvarianz" .

Die Bias-korrigierte Varianz kann durch jedes Element durch size-1 durch Teilen erhalten werden, oder:

//Please check that size > 1
variance += (MyArray[i]-mean)*(MyArray[i]-mean)/(size-1); 

Auch zur Kenntnis, dass bleibt der Wert von mean gleich.

Andere Tipps

Vor allem, wenn Sie nur den Griff zu bekommen suchen, was ist eine „vernünftige“ Varianz im Auge behalten, dass die Varianz im Quadrat im Grunde Standardabweichung ist. Die Standardabweichung etwa misst den typischen Abstand von einem Datenpunkt zu seinem erwarteten Wert.

Also, wenn Ihre Daten Mittelwert 4692 haben, und Ihre berechnete Varianz zu 1.483.780 herauskommt, das heißt Ihre Standardabweichung etwa 1218 ist, was Ihre Zahlen würde vorschlagen, sind in der Regel irgendwo in der Nähe des Bereichs 3474 sein - 5910 So wenn die Reichweite Ihrer Zahlen zu mir, dass die Varianz scheint tatsächlich ein wenig niedrig 0 - 10000; aber es hängt natürlich von der Verbreitung Ihrer Daten.

Wie für die Berechnung selbst: Sie können die Varianz unter Verwendung einer laufenden Berechnung berechnen, wie Sie Ihre Daten das erste Mal, um das Lesen (Sie müssen nicht den Mittelwert im Voraus wissen) mit Welford-Methode :

  

Initialisieren M1 = x1 und S1 = 0 ist.

     

Für die Folge xs, verwenden Sie die Wiederholung   Formeln

     

Mk = Mk-1 + (xk - Mk-1) / k Sk = Sk-1 +   (Xk - Mk-1) * (xk - Mk).

     

2 ≤ k ≤ n, k-ten Schätzwert für die   Varianz s2 = Sk / (k - 1).

Just for fun, eine etwas andere Route zu dem gleichen Ergebnis, mit std :: valarray statt std :: vector und (verschiedene) Algorithmen:

template <class T>
T const variance(std::valarray<T> const &v) {
    if (v.size() == 0)
        return T(0.0);
    T average = v.sum() / v.size();
    std::valarray<T> diffs = v-average;
    diffs *= diffs;
    return diffs.sum()/diffs.size();
}

Als Jacob angedeutet, gibt es wirklich zwei mögliche Versionen eine Abweichungsermittlung. Wie es aussieht, dies setzt voraus, Ihre Eingaben das „Universum“ sind. Wenn Sie nur eine Probe des gesamten Universums genommen haben, sollte die letzte Zeile benutzen. (diffs.size()-1) statt diffs.size()

Verwenden Sie eine andere Formel vielleicht?

#include <functional>
#include <algorithm>
#include <iostream>
int main()
{
 using namespace std;

 vector<double> num( 3 );
 num[ 0 ] = 4000.9, num[ 1 ] = 11111.221, num[ 2 ] = -2;


 double mean = std::accumulate(num.begin(), num.end(), 0.0) / num.size();
 vector<double> diff(num.size());
 std::transform(num.begin(), num.end(), diff.begin(), 
                std::bind2nd(std::minus<double>(), mean));
 double variance = std::inner_product(diff.begin(), diff.end(), 
                                     diff.begin(), 0.0) / (num.size() - 1);
 cout << "mean = " << mean << endl
      << "variance = " << variance << endl;
}

Ausgänge:     mean = 5036,71     Varianz = 3.16806e + 07

Beispiel Abweichungsermittlung:

#include <math.h>
#include <vector>

double Variance(std::vector<double>);

int main()
{
     std::vector<double> samples;
     samples.push_back(2.0);
     samples.push_back(3.0);
     samples.push_back(4.0);
     samples.push_back(5.0);
     samples.push_back(6.0);
     samples.push_back(7.0);

     double variance = Variance(samples);
     return 0;
}

double Variance(std::vector<double> samples)
{
     int size = samples.size();

     double variance = 0;
     double t = samples[0];
     for (int i = 1; i < size; i++)
     {
          t += samples[i];
          double diff = ((i + 1) * samples[i]) - t;
          variance += (diff * diff) / ((i + 1.0) *i);
     }

     return variance / (size - 1);
}

Da Sie mit einer großen Anzahl arbeiten und dann tun Gleitkommaoperationen auf sie, könnte man alles im Doppel tun wollen; , Sie würden eine Menge Abgüsse speichern.

pow .. 2 Mit einem Platz zu berechnen scheint ein wenig umständlich. Sie könnten Ihre Zahl zuerst berechnen, dann multiplizieren sie von selbst einen Platz zu bekommen.

Wenn Sie Division tun und der Notwendigkeit, Guss fühlen, warf die Operanden (das heißt der Zähler und / oder Nenner) zu verdoppeln, anstatt das Ergebnis. Sie verlieren Genauigkeit, wenn Sie ganze Zahlen teilen.

Ich bin nicht sicher, ob Ihre Formel für die Varianz ist richtig. Sie können zum Beispiel in der Erklärung in Wikipedia, suchen. Aber ich bin keine Mathe-Experte entweder, so dass ich nicht sicher bin, haben Sie einen Fehler gemacht.

Da Varianz das Quadrat der Standardabweichung ist, sollten die Antworten auf SO 1.174.984 helfen. Die kurze Diagnose ist, dass man die Summe der Quadrate der Werte sowie die Summe der Werte berechnen muß, und Sie scheinen nicht das zu tun werden.

Da Sie 10 haben 6 Werte, und das Quadrat jeder Wert kann bis zu 10 sein bis 8 , könnte man mit einer Summe von Quadraten bis zu 10 am Ende < sup> 14 ; Ihr 64-Bit-Integer bis 10 speichern kann 18 , so dass Sie immer noch zehntausendmal umgehen können so viele Eingänge oder Werte zu einer Million statt nur zehntausend bis hin, ohne zu überläuft läuft. Es gibt keine dringende Notwendigkeit, also zur reinen Doppel Berechnungen zu bewegen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top