1

ソースデータ:

    static double[] felix = new double[] { 0.003027523, 0.002012256, -0.001369238, -0.001737660, -0.001647287, 
        0.000275154, 0.002017238, 0.001372621, 0.000274148, -0.000913576, 0.001920263, 0.001186456, -0.000364631, 
        0.000638337, 0.000182266, -0.001275626, -0.000821093, 0.001186998, -0.000455996, -0.000547445, -0.000182582,
        -0.000547845, 0.001279006, 0.000456204, 0.000000000, -0.001550388, 0.001552795, 0.000729594, -0.000455664, 
        -0.002188184, 0.000639620, 0.000091316, 0.001552228, -0.001002826, 0.000182515, -0.000091241, -0.000821243,
        -0.002009132, 0.000000000, 0.000823572, 0.001920088, -0.001368863, 0.000000000, 0.002101800, 0.001094291, 
        0.001639643, 0.002637323, 0.000000000, -0.000172336, -0.000462665, -0.000136141 };

分散関数:

    public static double Variance(double[] x)
    {
        if (x.Length == 0)
            return 0;
        double sumX = 0;
        double sumXsquared = 0;
        double varianceX = 0;
        int dataLength = x.Length;


        for (int i = 0; i < dataLength; i++)
        {
            sumX += x[i];
            sumXsquared += x[i] * x[i];
        }

        varianceX = (sumXsquared / dataLength) - ((sumX / dataLength) * (sumX / dataLength));
        return varianceX;
    }

Excel と一部のオンライン計算機では、分散が 1.56562E-06 であると表示されますが、私の関数では 1.53492394804015E-06 が得られます。C#に精度の問題があるのか​​ 、それとも何なのか疑問に思い始めます。以前にこの種の問題を抱えている人はいますか?

4

2 に答える 2

13

表示されているのは、サンプル分散と母分散の違いであり、浮動小数点の精度やC#の浮動小数点実装の精度とは関係ありません。

母分散を計算しています。ExcelとそのWebサイトは、サンプルの分散を計算しています。

VarとVarPは別個の計算であり、どちらを使用するかについて注意する必要があります。(残念ながら、人々はそれらを交換可能であるのに交換可能であるかのように参照することがよくあります。同じことが標準偏差にも当てはまります)

データの標本分散は1.56562E-06、母分散は1.53492394804015E-06です。

しばらく前にcodeprojectに投稿されたいくつかのコードから:

サンプルの分散

public static double Variance(this IEnumerable<double> source)
{
    double avg = source.Average();
    double d = source.Aggregate(0.0, (total, next) => total += Math.Pow(next - avg, 2));
    return d / (source.Count() - 1);
}

母集団の分散

public static double VarianceP(this IEnumerable<double> source)
{
    double avg = source.Average();
    double d = source.Aggregate(0.0, (total, next) => total += Math.Pow(next - avg, 2));
    return d / source.Count();
}
于 2010-07-23T18:55:09.547 に答える
1

これは、数値的により良い動作をする場合がある別の実装です。

        mean = Average(data);
        double sum2 = 0.0, sumc = 0.0;


        for (int i = 0; i < data.Count; i++)
        {
           double dev = data[i] - mean;
           sum2 += dev * dev;
           sumc += dev;
        }

        return (sum2 - sumc * sumc / data.Count) / data.Count;
于 2011-04-20T21:10:29.883 に答える