我正在尝试使用C#app分析一些数据,并需要计算趋势线。我知道有多种类型的趋势线,但现在我试图计算指数增长;我将用它来预测未来的价值观。我一直在努力的等式是
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值。我传入的两个列表是日期和值,每个列表中的每一行对应于另一个列表中的同一行。问题是 - 是否有更好的方法来创建方程和变量,并且我得到的变量是我的数据最准确的变量?
答案 0 :(得分: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();
}
答案 1 :(得分: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;
}
答案 2 :(得分: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
。