谷歌不是我的朋友 - 自从我在大学的统计课程已经很长时间了......我需要计算一个图表上趋势线的起点和终点 - 有一个简单的方法吗?(在C#中工作,但无论什么语言适合你)
mat*_*att 33
感谢所有人的帮助 - 我已经离开这个问题了几天而且刚刚回到它 - 能够将它拼凑在一起 - 不是最优雅的代码,但它适用于我的目的 - 我想分享如果其他人遇到这个问题:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
bla*_*ank 27
好的,这是我最好的伪数学:
你的线的等式是:
Y = a + bX
哪里:
b =(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是点数
Ada*_*vis 15
鉴于趋势线是直的,通过选择任意两个点并计算来找到斜率:
(A)斜率=(y1-y2)/(x1-x2)
然后你需要找到该行的偏移量.该行由以下等式指定:
(B)y =偏移+斜率*x
所以你需要解决偏移问题.选择线上的任何点,并求解偏移量:
(C)偏移= y - (斜率*x)
现在,您可以将斜率和偏移量插入到线方程(B)中,并使用定义线的方程式.如果你的线路有噪声,你必须决定平均算法,或者使用某种曲线拟合.
如果你的线不直,你需要看看曲线拟合,或最小二乘拟合 - 非平凡,但可以.如果你知道你喜欢什么样的拟合,你会在最小二乘拟合网页(指数,多项式等)的底部看到各种类型的曲线拟合.
此外,如果这是一次性,使用Excel.
Thy*_*ine 15
这是Bedwyr Humphreys答案的一个非常快速(和半肮脏)的实现.该接口也应该与@matt的答案兼容,但是使用更多的IEnumerable概念来decimal代替int并使用更多IEnumerable概念,以便更容易使用和阅读.
Slope是b,Intercept是a
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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
117428 次 |
| 最近记录: |