3

C# アプリを使用していくつかのデータを分析しようとしており、トレンド ラインを計算する必要があります。複数のタイプのトレンド ラインがあることは承知していますが、現時点では指数関数的成長を計算しようとしています。将来の価値を予測するために使用します。私が取り組んできた方程式は

x(t) = x(0) * ((1+r)^t)

そして、これはグラフを複製するために私が書いたコードです:

public void ExponentialBestFit(List<DateTime> xvalues, List<double> yvalues)

        {
            //Find the first value of y (The start value) and the first value of x (The start date)
            xzero = Convert.ToDouble(xvalues[0].ToOADate());
            yzero = yvalues[0];
            if (yzero == 0)
                yzero += 0.1;

            //For every value of x (exluding the 1st value) find the r value
            //
            //                       |   y   |          Where t = the time sinse the start time (time period)
            //Equation for r = t root|-------| - 1      Where y = the current y value
            //                       |  y[0] |          Where y[0] = the first y value  #IMPROVMENT - Average 1st y value in range
            //
            double r = 0;

            //c is a count of how many r values are added; it is not equal to the count of all the values
            int c = 0;
            for (int i = 1; i < xvalues.Count; i++)
            {
                r += Math.Pow(yvalues[i]/yzero, 1/(Convert.ToDouble(xvalues[i].ToOADate()) - xzero)) - 1;
                c++;
            }

            r = r / c;           
        }

私が渡しているデータは一定期間にわたっていますが、時間の増加の増分は同じではありません。Excelでグラフを作成すると、別の式が使用されます

x(t) = x(0)*(e^kt)

ただし、k値がどこから生成されているのかわかりません。私が渡している 2 つのリストは Date と Value で、各リストの各行は他のリストの同じ行に対応しています。問題は、方程式と変数を作成するためのより良い方法はありますか、また、取得している変数は自分のデータに対して最も正確であるかということです。

4

3 に答える 3

3

これは、提供されている JavaScript の c# バージョンです。

    IEnumerable<double> Growth(IList<double> knownY, IList<double> knownX, IList<double> newX, bool useConst)
    {
        // Credits: Ilmari Karonen

        // Default values for optional parameters:
        if (knownY == null) return null;
        if (knownX == null)
        {
            knownX = new List<double>();
            for (var i  = 0; i<=knownY.Count; i++)
                knownX.Add(i++);
        }
        if (newX == null)
        {
            newX = new List<double>();
            for (var i = 0; i <= knownY.Count; i++)
                newX.Add(i++);
        }

        int n = knownY.Count;
        double avg_x = 0.0;
        double avg_y = 0.0;
        double avg_xy = 0.0;
        double avg_xx = 0.0;
        double beta = 0.0;
        double alpha = 0.0;
        for (var i = 0; i < n; i++)
        {
            var x = knownX[i];
            var y = Math.Log(knownY[i]);
            avg_x += x;
            avg_y += y;
            avg_xy += x * y;
            avg_xx += x * x;
        }
        avg_x /= n;
        avg_y /= n;
        avg_xy /= n;
        avg_xx /= n;

        // Compute linear regression coefficients:
        if (useConst)
        {
            beta = (avg_xy - avg_x * avg_y) / (avg_xx - avg_x * avg_x);
            alpha = avg_y - beta * avg_x;
        }
        else
        {
            beta = avg_xy / avg_xx;
            alpha = 0.0;
        }

        // Compute and return result array:
        return newX.Select(t => Math.Exp(alpha + beta*t)).ToList();

    }
于 2013-01-25T15:54:27.567 に答える
1

次の JavaScript コードが役に立ちます。これを使用して、Excel のGROWTH関数を実装しました。JavaScript で書かれていますが、C# への移植は非常に簡単です。そのほとんどは他の誰かによって書かれたことに注意してください (コード内のクレジット)。

function GROWTH(known_y, known_x, new_x, use_const) {
  // Credits: Ilmari Karonen

  // Default values for optional parameters:
  if (typeof(known_x) == 'undefined') {
    known_x = [];
    for (var i = 1; i <= known_y.length; i++) known_x.push(i);
  }
  if (typeof(new_x) == 'undefined') {
    new_x = [];
    for (var i = 1; i <= known_y.length; i++) new_x.push(i);
  }
  if (typeof(use_const) == 'undefined') use_const = true;

  // Calculate sums over the data:
  var n = known_y.length;
  var avg_x = 0;
  var avg_y = 0;
  var avg_xy = 0;
  var avg_xx = 0; 
  for (var i = 0; i < n; i++) {
    var x = known_x[i];
    var y = Math.log(known_y[i]);
    avg_x += x;
    avg_y += y;
    avg_xy += x*y;
    avg_xx += x*x;
  }
  avg_x /= n;
  avg_y /= n;
  avg_xy /= n;
  avg_xx /= n;

  // Compute linear regression coefficients:
  if (use_const) {
    var beta = (avg_xy - avg_x*avg_y) / (avg_xx - avg_x*avg_x);
    var alpha = avg_y - beta*avg_x;
  } else {
    var beta = avg_xy / avg_xx;
    var alpha = 0;
  }

  // Compute and return result array:
  var new_y = [];
  for (var i = 0; i < new_x.length; i++) {
    new_y.push(Math.exp(alpha + beta * new_x[i]));
  }
  return new_y;
}
于 2013-01-25T14:13:05.497 に答える
0

であるためx(t)=x(0)*e^{kt}、対数を取って を得ることができますln x(t)=ln x(0) + kt。これは、 と を見つけるln x(0)ためkに、データに適合する最小二乗を見つけることができることを意味します{(t,ln x(t))}。これはあなたにそれを教えてln x(t) = b + atくれk=aますx(0)=e^b

于 2014-05-12T15:53:26.930 に答える