2012-08-03 81 views
1

我正在爲我正在編寫的網站編寫一些分析模塊,我需要估計當前小時後的總視圖。我有每分鐘直至當前分鐘的數據,因此,如果時間是12:28,我將有一個數組,它看起來是這樣的:計算趨勢線並預測未來結果

0: "21410" 
1: "21886" 
2: "21837" 
3: "21895" 
4: "21564" 
5: "21714" 
6: "21571" 
7: "21324" 
8: "21310" 
9: "21390" 
10: "21764" 
11: "21598" 
12: "21493" 
13: "21352" 
14: "21478" 
15: "21058" 
16: "20942" 
17: "20825" 
18: "21321" 
19: "20950" 
20: "21039" 
21: "21117" 
22: "20733" 
23: "20773" 
24: "20929" 
25: "20900" 
26: "20687" 
27: "20999" 

目前我投射小時的值是這樣的:

(60/minsSoFar)*totalSoFar 

這工作相當好,但我寧願做更多的數學。我想計算一下最適合我迄今爲止的數據,並預測到第60分鐘的時間。這將考慮加速和減速。

用我目前使用的方法,我實際上假設趨勢是一條直線。我將如何計算多項式或功率趨勢的公式?

我在NodeJS上寫這個,所以JavaScript會很理想,但我也會採用僞代碼!

下面是情況下,更容易的格式陣列你想讓它:

[21410, 21886, 21837, 21895, 21564, 21714, 21571, 21324, 21310, 21390, 21764, 21598, 21493, 21352, 21478, 21058, 20942, 20825, 21321, 20950, 21039, 21117, 20733, 20773, 20929, 20900, 20687, 20999] 

感謝您的幫助!

+0

您可能要從這裏開始http://en.wikipedia.org/wiki/Curve_fitting – bigbenbt 2012-08-03 14:08:38

回答

6

你可以做一條線least-squares fit

function LineFitter() 
{ 
    this.count = 0; 
    this.sumX = 0; 
    this.sumX2 = 0; 
    this.sumXY = 0; 
    this.sumY = 0; 
} 

LineFitter.prototype = { 
    'add': function(x, y) 
    { 
     this.count++; 
     this.sumX += x; 
     this.sumX2 += x*x; 
     this.sumXY += x*y; 
     this.sumY += y; 
    }, 
    'project': function(x) 
    { 
     var det = this.count * this.sumX2 - this.sumX * this.sumX; 
     var offset = (this.sumX2 * this.sumY - this.sumX * this.sumXY)/det; 
     var scale = (this.count * this.sumXY - this.sumX * this.sumY)/det; 
     return offset + x * scale; 
    } 
}; 

function linearProject(data, x) 
{ 
    var fitter = new LineFitter(); 
    for (var i = 0; i < data.length; i++) 
    { 
     fitter.add(i, data[i]); 
    } 
    return fitter.project(x); 
} 

例子:

>>> linearProject([ 
     21410, 21886, 21837, 21895, 21564, 21714, 21571, 21324, 21310, 21390, 
     21764, 21598, 21493, 21352, 21478, 21058, 20942, 20825, 21321, 20950, 
     21039, 21117, 20733, 20773, 20929, 20900, 20687, 20999 
    ], 60); 
19489.614121510676 

做了二次多項式類似的東西是有點複雜:

function SquareFitter() 
{ 
    this.count = 0; 
    this.sumX = 0; 
    this.sumX2 = 0; 
    this.sumX3 = 0; 
    this.sumX4 = 0; 
    this.sumY = 0; 
    this.sumXY = 0; 
    this.sumX2Y = 0; 
} 

SquareFitter.prototype = { 
    'add': function(x, y) 
    { 
     this.count++; 
     this.sumX += x; 
     this.sumX2 += x*x; 
     this.sumX3 += x*x*x; 
     this.sumX4 += x*x*x*x; 
     this.sumY += y; 
     this.sumXY += x*y; 
     this.sumX2Y += x*x*y; 
    }, 
    'project': function(x) 
    { 
     var det = this.count*this.sumX2*this.sumX4 - this.count*this.sumX3*this.sumX3 - this.sumX*this.sumX*this.sumX4 + 2*this.sumX*this.sumX2*this.sumX3 - this.sumX2*this.sumX2*this.sumX2; 
     var offset = this.sumX*this.sumX2Y*this.sumX3 - this.sumX*this.sumX4*this.sumXY - this.sumX2*this.sumX2*this.sumX2Y + this.sumX2*this.sumX3*this.sumXY + this.sumX2*this.sumX4*this.sumY - this.sumX3*this.sumX3*this.sumY; 
     var scale = -this.count*this.sumX2Y*this.sumX3 + this.count*this.sumX4*this.sumXY + this.sumX*this.sumX2*this.sumX2Y - this.sumX*this.sumX4*this.sumY - this.sumX2*this.sumX2*this.sumXY + this.sumX2*this.sumX3*this.sumY; 
     var accel = this.sumY*this.sumX*this.sumX3 - this.sumY*this.sumX2*this.sumX2 - this.sumXY*this.count*this.sumX3 + this.sumXY*this.sumX2*this.sumX - this.sumX2Y*this.sumX*this.sumX + this.sumX2Y*this.count*this.sumX2; 
     return (offset + x*scale + x*x*accel)/det; 
    } 
}; 

function squareProject(data) 
{ 
    var fitter = new SquareFitter(); 
    for (var i = 0; i < data.length; i++) 
    { 
     fitter.add(i, data[i]); 
    } 
    return fitter.project(60); 
} 

例2:

>>> squareProject([ 
     21410, 21886, 21837, 21895, 21564, 21714, 21571, 21324, 21310, 21390, 
     21764, 21598, 21493, 21352, 21478, 21058, 20942, 20825, 21321, 20950, 
     21039, 21117, 20733, 20773, 20929, 20900, 20687, 20999 
    ], 60); 
19282.85862700518 

我可以做更高階的多項式,但表達式會變得更長。對於任意的程度,你將不得不看矩陣。

+2

我會認真地建議您在其他語言中找到曲線擬合庫,並將您需要的JavaScript翻譯成試圖直接實施教科書公式。問題在於教科書公式通常在數值上不穩定,也就是說他們對數字的浮點表示與實際數學數字之間的差異非常敏感。例如,如果兩個數字彼此接近,則任何可能涉及從另一個大數減去一個大數的計算可能被舍入誤差克服。 – ebohlman 2012-08-03 16:32:29