2013-02-12 34 views
4

嘿,我很难搞清楚如何计算Java中数组的标准占卜数。正如你所看到的,我已经计算了平均值,而且我知道最后我将不得不除以样本量减去1(n-1)并平均该数值。我遇到的问题是如何获取每个数字并计算距离平均值有多远,然后计算该数字。我知道我可以分别从数据集中完成每个数字,但必须有一个更简单的方法。任何帮助将不胜感激,这是我的代码。任何大小数组的标准偏差java

public class CalculateArray 
{ 

    public static void main(String[] args) 
    { 
     int [] numbers = new int[]{1,2,3,4,5,6,7,8,9}; 

     int sum = 0; 
     int max = 0; 
     int min = numbers[0]; 
     double sd = 0; 

     for(int i=0; i<numbers.length; i++) 
     { 
      sum = sum + numbers[i]; 
     } 

     double average = sum/numbers.length; 

     System.out.println("Average value is : " + average); 

     for(int i=0; i<numbers.length; i++) 
     { 
      if(numbers[i] > max) 
      { 
       max = numbers[i]; 
      } 
     } 

     System.out.println("max number is : " + max); 

     for(int i=0; i<numbers.length; i++) 
     { 
      if(numbers[i] < min) 
      { 
       min = numbers[i]; 
      } 
     } 

     System.out.println("min number is : " + min); 

     for (int i=0; i<numbers.length;i++) 
     { 
      //this is where im having problems 
      sd = ??? 
     } 

     double standardDeviation = math.sqrt(sd/(numbers.length-1)); 

     System.out.println("The standard deviation is : " + standardDeviation); 
    } 
} 
+0

'std + = pow(average - numbers [i],2)''? – imreal 2013-02-12 18:20:11

回答

7

要计算一个数字与平均值的差距,请使用-运算符。为了计算平方,你可以使用Math.pow。因此,鉴于你已经计算早些时候在节目中average

for (int i=0; i<numbers.length;i++) 
{ 
    sd = sd + Math.pow(numbers[i] - average, 2); 
} 

顺便说一句,你计算平均值目前被打破的方式。您应该将sum定义为双倍,而不是int

+0

您应该使用'Math.abs(数字[i] - 平均数)',否则当'number [i] 2013-02-12 18:29:07

+0

@乔伊,你不需要计算绝对值。 a²= | a |²。 – Joni 2013-02-12 18:30:47

+0

最后,你会想将平方偏差的总和除以数据点的数量。我认为这是一个均方根;在上面的条款中,rms = sd/numbers.length – criticalfix 2013-02-12 18:32:00

1

除了别人描述的两遍算法(第一遍和第二遍都计算平均值)之外,请参见this link以获取如何在单遍中完成的示例。该算法如下:

double std_dev2(double a[], int n) { 
    if(n == 0) 
     return 0.0; 
    double sum = 0; 
    double sq_sum = 0; 
    for(int i = 0; i < n; ++i) { 
     sum += a[i]; 
     sq_sum += a[i] * a[i]; 
    } 
    double mean = sum/n; 
    double variance = sq_sum/n - mean * mean; 
    return sqrt(variance); 
} 

UPDATE
不要这样做。正如Joni在其下面的comment中解释的那样,在实现这个计算机程序时存在很高的错误风险。对于一个稳定的在线算法,Joni将我们引导至this维基百科文章,如上所述已经进行了彻底分析。

+2

一个可怕的算法,永远不要使用。为什么它不好,以及有什么替代方案,请参阅http://www.johndcook.com/blog/2008/09/26/comparing-three-methods-of-computing-standard-deviation/ – Joni 2013-02-13 06:56:54

+0

@Joni感谢您的输入。这基本上是一个溢出错误? – 2013-02-13 19:17:26

+0

问题主要在于'sq_sum/n - mean * mean':它计算两个大的几乎相等的数字的差值。数字的取消意味着相对误差上升 - 您甚至可能以负方差结束。维基百科有关这类数字问题的相当不错的页面:http://en.wikipedia.org/wiki/Loss_of_significance – Joni 2013-02-13 19:36:26

0
k + k = 2k 

以获得平均值,将2k除以您拥有的术语数。 所以术语的平均值是k。 :D