簡體   English   中英

我的代碼中要更改什么以計算樣本標准偏差而不是總體標准偏差?

[英]What to change in my code to calculate sample Standard deviation instead of population standard deviaiton?

我的代碼在需要計算總體偏差時計算總體偏差,我已經比較了兩個公式並嘗試更改我的計算,但似乎沒有任何效果。 感謝大家的幫助或提前輸入。

public class MeanAndStandardDeviation {
public static void main (String argv []) throws IOException {
    BufferedReader stdin =
            new BufferedReader (new InputStreamReader (System.in));
    NumberFormat nf = new DecimalFormat ("0.00");
    nf.setMinimumFractionDigits (2);//Sets Min digits
    nf.setMaximumFractionDigits (2);//Sets Max digits
    String inputValue;
    int count = 0;
    //For Loop for count
    for(int i = 0; i < count; i++){
        count++;
    }
    double varianceFinal = 0;
    List<String> input = new ArrayList<String>();//String ArrayList
    List<Double> numbers = new ArrayList<Double>();//Double ArrayList

  //While loop that takes in all my input and assigns it to the ArrayLists
  //Parameters set for when null is entered and total numbers go over 500
    while((inputValue = stdin.readLine()) != null && !inputValue.equals("") && input.size()<500){//Parameters set for when null is entered and total numbers go over 500
        input.add(inputValue);
        numbers.add (Double.parseDouble(inputValue));  
    }

System.out.println ("Standard Deviation: " +(nf.format(calcStdDev (numbers, count, varianceFinal))));//Prints the Standard Deviation
}

//StandardDeviation Class
static double calcStdDev (List<Double> numbers, int count, double variance){
    variance = 0;
    double sum = 0;
    for(int i = 0; i < numbers.size(); i++){
        sum += numbers.get(i);
        variance += numbers.get(i) * numbers.get(i);
        count++;
    }
    double varianceFinal = ((variance/count)-(sum*sum)/(count*count));
return Math.sqrt(varianceFinal);

}
} 

嚴重的是,您的代碼在許多級別上都是“錯誤的”。 因此,除了為您調試所有代碼外,我還將為您提供一些有關如何修復和簡化代碼的提示-然后,您應該很容易修復/解決實際的數學問題。

首先,您的代碼以一種令人困惑的樣式編寫,這使得理解(並因此調試 )的難度大大超過了需要。

例:

int count = 0;
//For Loop for count
for(int i = 0; i < count; i++){
    count++;
}

那個for循環什么也沒做。 即使條件可能是其他情況,例如i < someNumber 您仍然只需要在此處放置count = someNumber 而不是循環!

同樣在這里:將count作為參數提供給calc方法有什么意義? 然后增加它? 因此,讓我們重寫一下:

public static double calcStdDev (List<Double> numbers, double variance) {
  double sumOfNumbers = 0;
  double sumOfSquares = 0;
  for(double number : numbers) {
    sumOfNumbers += number;
    sumOfSquares += number * number;
}
... and instead of calculating count, you simply have
int numberOfNumbers = numbers.size();
... and now, do your math

代碼中真正奇怪的另一件事是如何設置方差變量。 以及在calc方法中如何使用它。

長話短說:退后一步,從代碼中刪除不需要的所有內容。

像您那樣計算方差是一個壞主意。 如果平均值較大,例如1000萬,而噪聲較小,例如1,則double的有限精度很可能意味着您計算出的方差為負,而sd將為nan。

您應該分兩步進行計算,例如

double mean = 0.0;
   for( i=0; i<n; ++i)
   {  mean += x[i];
   }
   mean /= n;
double var = 0.0;
   for( i=0; i<n; ++i)
   {   
   double d = x[i] - mean;
       var += d*d;
   }
   var /= n;

或一次通過,例如

double mean = 0.0;
double var = 0.0;
  for( i=0; i<n; ++i)
  {  
  double f = 1.0/(i+1);
  double d = x[i]-mean;
      mean += d*f;
      var = (1.0-f)*(var + f*d*d);
  }

(這需要一些乏味的代數才能證明一遍方法給出的答案與二遍方法相同)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM