2016-09-21 85 views
1

我的代碼計算總體偏差,當我需要它來計算樣本偏差我已經比較了兩個公式,並試圖改變我的計算,但似乎沒有任何工作。感謝大家的幫助或提前輸入。什麼改變我的代碼來計算樣本標準偏差,而不是人口標準偏差?

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); 

} 
} 
+0

順便說一下,我的標準偏差類在底部 – swaguire

+0

只是爲了記錄:準確的命名:你有兩個靜態**方法**那裏,不是類。 – GhostCat

+0

謝謝對不起 – swaguire

回答

2

說真的,你的代碼在許多層面上都是「錯誤的」。因此,不是爲你調試所有這些,我會給你一些提示如何修復並簡化你的代碼 - 那麼你應該很容易修復/解決你的實際數學問題。

首先,你的代碼是這麼寫的一個混亂的風格,只是使它更難理解(因此調試)比它需要。

例子:

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

,對於循環沒有做任何事情。即使條件是其他情況,如i < someNumber;你仍然需要在那裏放置count = someNumber;而不是循環!

同樣在這裏:提供計數作爲您的計算方法的參數是什麼?然後只是增加它?所以,讓我們重寫:

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 

這是很奇怪的代碼中的另一件事是你如何設置你的方差變量;以及它如何在您的計算方法中使用。

長話短說:退一步,從您的代碼中刪除所有不需要的東西。

+0

謝謝你的建議和幫助對不起,這真是太糟糕了:( – swaguire

+0

不客氣,希望我的想法能讓你朝着正確的方向前進,並且足以最終解決你的問題。 – GhostCat

+0

是的,它再次感謝和抱歉,這是如此糟糕,我還在學習 – swaguire

0

像你這樣計算方差是一個壞主意。如果平均值較大,例如1000萬,並且噪聲較小,例如1左右,則雙精度的有限精度可能意味着您的計算方差爲負值,sd將爲毫微秒。

您應該計算它在兩次通過,例如

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); 
    } 

(它需要有點乏味代數以表明一個通方法使與兩次通過方法相同的答案)。