4

IEnumerable<double>データサンプルがあります。信号/データの 90% 信頼区間を計算したいと考えています。MathNET ライブラリを自由に使用できますが、ライブラリを正しく操作する方法について混乱しています。私のデータを考えると、アイデアは、元の信号の信頼区間を含む 2 つの追加のデータ配列を返すことです

using MathNet.Numerics.Statistics;
using MathNet.Numerics.Distributions;

public static List<double[]> ConfidenceIntervals(IEnumerable<double> sample, double interval)
{
    Contract.Requires(interval > 0 && interval < 1.0);
    int sampleSize = sample.Count();
    double alpha = 1.0 - interval;
    double mean = sample.Mean();
    double sd = sample.StandardDeviation();

    double t, mu;
    double[] upper = new double[sampleSize];
    double[] lower = new double[sampleSize];
    StudentT studentT = new StudentT(mean, alpha, sampleSize - 1);
    int index = 0;
    foreach (double d in sample)
    {
        t = studentT.CumulativeDistribution(d);
        double tmp = t * (sd / Math.Sqrt(sampleSize));
        mu = mean - tmp;
        upper[index] = d + mu;
        lower[index] = d - mu;
    }
    return new List<double[]>() { upper, lower };
}

これは数学的には複雑ではありません。MathNET ライブラリで利用できる関数/メソッドを正しく使用する方法について混乱しています。

4

2 に答える 2

7

信号の信頼区間が信号の各サンプルに適用されることになっている方法を完全には理解していませんが、次のようにサンプル セットの信頼区間を計算できます。

public static Tuple<double, double> A(double[] samples, double interval)
{
    double theta = (interval + 1.0)/2;
    double mean = samples.Mean();
    double sd = samples.StandardDeviation();
    double T = StudentT.InvCDF(0,1,samples.Length-1,theta);
    double t = T * (sd / Math.Sqrt(samples.Length));
    return Tuple.Create(mean-t, mean+t);
}

StudentT.InvCDF残念ながら、現在の Math.NET Numericsにはまだないため、T を計算する行はコンパイルされません。ただし、当面の回避策として数値的に評価することはできます。

var student = new StudentT(0,1,samples.Length-1);
double T = FindRoots.OfFunction(x => student.CumulativeDistribution(x)-theta,-800,800);

たとえば、サンプル数が 16 でアルファ値が 0.05 の場合、予想どおり 2.131 になります。サンプル数が 60 ~ 100 を超える場合は、正規分布で近似することもできます。

double T = Nomal.InvCDF(0,1,theta);

つまり、全体として:

public static Tuple<double, double> B(double[] samples, double interval)
{
    double theta = (interval + 1.0)/2;
    double T = FindRoots.OfFunction(x => StudentT.CDF(0,1,samples.Length-1,x)-theta,-800,800);

    double mean = samples.Mean();
    double sd = samples.StandardDeviation();
    double t = T * (sd / Math.Sqrt(samples.Length));
    return Tuple.Create(mean-t, mean+t);
}

これはまだ完全な答えではありませんが、信頼区間を各サンプルに何らかの方法で適用したいと考えていましたが、そこにたどり着くまでに役立つことを願っています.

PS: Math.NET Numerics v3.0.0-alpha7 の使用

于 2013-12-30T17:48:46.957 に答える
1

foreachループでインデックス値を増やしていないことに気付きました。これにより、インデックス 0 の値が次の計算に置き換えられます (値を設定しようとするupper[index]lower[index])。

だから、これが間違った結果を得た理由だと思います。

もしそうなら、あなたのコードは

using MathNet.Numerics.Statistics;
using MathNet.Numerics.Distributions;

public static List<double[]> ConfidenceIntervals(IEnumerable<double> sample, double interval)
{
    Contract.Requires(interval > 0 && interval < 1.0);
    int sampleSize = sample.Count();
    double alpha = 1.0 - interval;
    double mean = sample.Mean();
    double sd = sample.StandardDeviation();

    double t, mu;
    double[] upper = new double[sampleSize];
    double[] lower = new double[sampleSize];
    StudentT studentT = new StudentT(mean, alpha, sampleSize - 1);
    int index = 0;
    foreach (double d in sample)
    {
        t = studentT.CumulativeDistribution(d);
        double tmp = t * (sd / Math.Sqrt(sampleSize));
        mu = mean - tmp;
        upper[index] = d + mu;
        lower[index] = d - mu;
        index++;
    }
    return new List<double[]>() { upper, lower };
}
于 2013-12-30T14:26:10.887 に答える