Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C# ja keskihajonta

Wusakko [28.10.2011 10:47:46]

#

Hei!

Voiko keskihajonnan laskea seuraavalla koodinpätkällä C#:ssa?

private double getStandardDeviation(List<double> doubleList)
{
 double average = doubleList.Average();
 double sumOfDerivation = 0;
 foreach (double value in doubleList)
 {
  sumOfDerivation += (value) * (value);
 }
 double sumOfDerivationAverage = sumOfDerivation / doubleList.Count;
 return Math.Sqrt(sumOfDerivationAverage - (average*average));
}

Mod. lisäsi kooditagit!

Grez [28.10.2011 11:02:52]

#

Voi sen laskea. Tulos vaan taitaa olla väärin, kun laskukaava näyttäisi olevan väärin.

Mielestäni hieman hassu kysymys. Eikö asia olisi selvinnyt kokeilemalla?

AkeMake [28.10.2011 22:11:55]

#

En C#:ssaa osaa yhtään, mutta sen verran tuosta tajuan, ettet tieten ole täysin ymmärtänyt miten keskihajonta lasketaan. Näyttäisi siltä, että lasket äärellisen joukon keskihajontaa.

Foreach silmukassa sinun ei kuuluisi lisätä SumOfDerivation:iin value:n neliötä vaan value:n ja doubleList:n keskiarvon erotuksen neliö. Lisäksi sinun kuuluisi palauttaa pelkkä etäisyyksien keskiarvon (sumDerivationAverage) neliöjuuri eikä etäisyyksien keskiarvon sekä doubleList:n lukujen keskiarvon neliön erotuksen neliöjuurta. Oho.. Olipa hankalasti selitetty.

Jos nyt pätkän vertaa osaan muokata tuota annettua koodia, niin keskihajonta pitäisi tulla seuraavasta koodinpätkästä:

private double getStandardDeviation(List<double> doubleList)
{
 double average = doubleList.Average();
 double sumOfDerivation = 0;
 foreach (double value in doubleList)
 {
  sumOfDerivation += (value - average) * (value - average);
 }
 double sumOfDerivationAverage = sumOfDerivation / doubleList.Count;
 return Math.Sqrt(sumOfDerivationAverage);
}

Keskihajonta on varianssin neliöjuuri. Varianssi taas voidaan laskea niin kuin edellä tehtiin eli tutkitaan mikä on xi-havaintojen keskimääräinen neliöity etäisyys omasta aritmeettisesta keskiarvostaan. Lasketaan siis kaikkien xi-havaintojen ja oman aritmeettisen keskiarvonsa erotuksen neliöity summa.

Toinen ehkä helpompi vaihtoehto varianssin laskemiseksi on laskea havaintojen xi neliöiden summa. Vähentää saadusta luvusta havaintojen xi summan neliö, joka on jaettu havaintojen lukumäärällä ja tästä erotuksesta saatu luku jaetaan havaintojen lukumäärällä.

Kannattaa huomioida, että perusjoukosta otetun otoksen varianssi (otosvarianssi) lasketaan hiukan eri tavalla kuin koko perusjoukosta laskettava varianssi. Kun perusjoukosta laskettu varianssi saadaan jakamalla havaintojen ja keskiarvon neliösumma havaintojen lukumäärällä n, saadaan otosvarianssi jakamalla kyseinen neliösumma "ännän" sijaan vapausasteluvulla, joka tässä tapauksessa on n-1.

private double getStandardDeviation(List<double> doubleList, bool sample)
{
 double average = doubleList.Average();
 double sumOfVariables = 0;
 double sumOfSquares = 0;
 foreach (double value in doubleList)
 {
  sumOfVariables += value;
  sumOfSquares += (value) * (value);
 }
 double sumOfDeviation = sumOfSquares - (sumOfVaribles * sumOfVariables / doubleList.Count);
 if(sample == true) {
  if(doubleList.Count == 1) {
   return int 0;
  }
  int degreeOfFreedom = doubleList.Count - 1;
 }
 else {
  int degreeOfFreedom = doubleList.Count;
 }
 return Math.Sqrt(sumOfDerivation / degreeOfFreedom);
}

Tässä jälkimmäisessä koodissa kannattaa edelleen huomioida, etten osaa koodata C#:llä, joten se saattaa sisältää virheitä. Lisäsin getStandardDeviation:iin toisen parametrin sample, joka boolean arvolla true kertoo, että kyseessä on otos ja näin keskihajonta lasketaan otosvarianssilla. Koska otosvarianssissa jaetaan luvulla n-1, havaintojen määrä ei saa olla 1. Siinä erikoistapauksessa, että havaintojen määrä on 1 palautetaan 0, koska yhdellä havainnolla ei ole vaihtelua eli hajonta on 0.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta