如何计算图表的趋势线?

Google不是我的朋友 – 从我在大学的统计课程开始已经很长时间了…我需要在图表上计算趋势线的开始点和结束点 – 是否有一个简单的方法可以做到这一点? (用C#工作,但是任何语言都适合你)

考虑到趋势线是直线,可以通过select任意两点来计算斜率:

(A)斜率=(y1-y2)/(x1-x2)

然后你需要find线的偏移量。 该行由以下等式指定:

(B)y =偏移+斜率* x

所以你需要解决抵消。 select线上的任何一点,并解决偏移:

(C)offset = y /(slope * x)

现在,您可以将斜率和偏移量插入线方程(B),并且具有定义线的方程式。 如果你的线路有噪声,你将不得不决定平均algorithm,或使用某种曲线拟合。

如果你的线不直,那么你需要看曲线拟合 ,或最小二乘拟合 – 非平凡,但可以。 如果你知道你喜欢什么样的适合,你会看到在最小二乘拟合网页(指数,多项式等)底部的各种types的曲线拟合。

另外,如果这是一次性的,请使用Excel。

-亚当

感谢所有的帮助 – 我已经closures了这个问题几天,刚回来 – 能够拼凑起来 – 不是最优雅的代码,但它适用于我的目的 – 以为我会分享如果其他人遇到这个问题:

public class Statistics { public Trendline CalculateLinearRegression(int[] values) { var yAxisValues = new List<int>(); var xAxisValues = new List<int>(); for (int i = 0; i < values.Length; i++) { yAxisValues.Add(values[i]); xAxisValues.Add(i + 1); } return new Trendline(yAxisValues, xAxisValues); } } public class Trendline { private readonly IList<int> xAxisValues; private readonly IList<int> yAxisValues; private int count; private int xAxisValuesSum; private int xxSum; private int xySum; private int yAxisValuesSum; public Trendline(IList<int> yAxisValues, IList<int> xAxisValues) { this.yAxisValues = yAxisValues; this.xAxisValues = xAxisValues; this.Initialize(); } public int Slope { get; private set; } public int Intercept { get; private set; } public int Start { get; private set; } public int End { get; private set; } private void Initialize() { this.count = this.yAxisValues.Count; this.yAxisValuesSum = this.yAxisValues.Sum(); this.xAxisValuesSum = this.xAxisValues.Sum(); this.xxSum = 0; this.xySum = 0; for (int i = 0; i < this.count; i++) { this.xySum += (this.xAxisValues[i]*this.yAxisValues[i]); this.xxSum += (this.xAxisValues[i]*this.xAxisValues[i]); } this.Slope = this.CalculateSlope(); this.Intercept = this.CalculateIntercept(); this.Start = this.CalculateStart(); this.End = this.CalculateEnd(); } private int CalculateSlope() { try { return ((this.count*this.xySum) - (this.xAxisValuesSum*this.yAxisValuesSum))/((this.count*this.xxSum) - (this.xAxisValuesSum*this.xAxisValuesSum)); } catch (DivideByZeroException) { return 0; } } private int CalculateIntercept() { return (this.yAxisValuesSum - (this.Slope*this.xAxisValuesSum))/this.count; } private int CalculateStart() { return (this.Slope*this.xAxisValues.First()) + this.Intercept; } private int CalculateEnd() { return (this.Slope*this.xAxisValues.Last()) + this.Intercept; } } 

好的,这是我最好的伪math:

你的线的公式是:

Y = a + bX

哪里:

(sum(x * y) – sum(x)sum(y)/ n)/(sum(x ^ 2) – sum(x)^ 2 / n)

a = sum(y)/ n – b(sum(x)/ n)

其中sum(xy)是所有x * y等的总和。不是特别清楚我承认,但是这是我没有sigma符号可以做的最好的:)

…现在添加了Sigma

b =(Σ(xy) – (ΣxΣy)/ n)/(Σ(x ^ 2) – (Σx)^ 2 / n)

a =(Σy)/ n – b((Σx)/ n)

其中Σ(xy)是所有x * y等的总和,n是点的数量

这是Bedwyr Humphreys的答案的一个非常快(和半肮脏的)实现。 该接口应该与@matt的答案兼容,但是使用decimal而不是int并且使用更多的IEnumerable概念,希望能够更容易地使用和阅读。

SlopebIntercepta

 public class Trendline { public Trendline(IList<decimal> yAxisValues, IList<decimal> xAxisValues) : this(yAxisValues.Select((t, i) => new Tuple<decimal, decimal>(xAxisValues[i], t))) { } public Trendline(IEnumerable<Tuple<Decimal, Decimal>> data) { var cachedData = data.ToList(); var n = cachedData.Count; var sumX = cachedData.Sum(x => x.Item1); var sumX2 = cachedData.Sum(x => x.Item1 * x.Item1); var sumY = cachedData.Sum(x => x.Item2); var sumXY = cachedData.Sum(x => x.Item1 * x.Item2); //b = (sum(x*y) - sum(x)sum(y)/n) // / (sum(x^2) - sum(x)^2/n) Slope = (sumXY - ((sumX * sumY) / n)) / (sumX2 - (sumX * sumX / n)); //a = sum(y)/n - b(sum(x)/n) Intercept = (sumY / n) - (Slope * (sumX / n)); Start = GetYValue(cachedData.Min(a => a.Item1)); End = GetYValue(cachedData.Max(a => a.Item1)); } public decimal Slope { get; private set; } public decimal Intercept { get; private set; } public decimal Start { get; private set; } public decimal End { get; private set; } public decimal GetYValue(decimal xValue) { return Intercept + Slope * xValue; } } 

关于以前的答案

如果(B)y =偏移+斜率* x

那么(C)offset = y /(slope * x)是错误的

(C)应该是:

偏移量= y-(斜率* x)

请参阅:http: //zedgraph.org/wiki/index.php?title=趋势

如果您有权访问Excel,请查看“帮助”中“函数参考”的“统计函数”部分。 对于直线最佳拟合,您需要SLOPE和INTERCEPT,方程就在那里。

哦,等等,他们也在这里定义在线: http : //office.microsoft.com/en-us/excel/HP052092641033.aspx SLOPE,并有一个链接到INTERCEPT。 当然,假设MS不会移动页面,在这种情况下,尝试使用谷歌search“斜坡拦截公式Excel站点:microsoft.com” – 这个链接是刚刚发布的第三个。

非常感谢你的解决scheme,我正在挠头。
以下是我如何在Excel中应用解决scheme。
我成功地使用了MUHD在Excel中给出的两个函数:
(sum(x * y) – sum(x)sum(y)/ n)/(sum(x ^ 2) – sum(x)^ 2 / n)
b = sum(y)/ n – b(sum(x)/ n)
(小心我的a和b是MUHD解决scheme中的b和a)。

– 做了4列,例如:
注意:我的数值y值在B3:B17中,所以我有n = 15;
我的x值是1,2,3,4 … 15。
1.列B:已知的X的
2. C列:已知的
3. D栏:计算出的趋势线
4.列E:B值* C值(E3 = B3 * C3,E4 = B4 * C4,…,E17 = B17 * C17)
5. F栏:x平方值
然后我总结列B,C和E,总和在我的第18行,所以我有B18作为Xs的总和,C18作为Ys的总和,E18作为X * Y的总和,F18作为平方和。
要计算a,在任何单元格中input以下公式(F35为我):
F35 =(E18-(B18 * C18)/ 15)/(F18-(B18 * B18)/ 15)
为了计算b(在我的F36中):
F36 = C18 / 15-F35 *(B18 / 15)
D列值,根据y = ax + b计算趋势线:
D3 = $ F $ 35 * B3 + $ F $ 36,D4 = $ F $ 35 * B4 + $ F $ 36等等(直到D17为止)。

select列数据(C2:D17)来制作图表。
HTH。