当前位置:  开发笔记 > 编程语言 > 正文

如何计算图表的趋势线?

如何解决《如何计算图表的趋势线?》经验,为你挑选了4个好方法。

谷歌不是我的朋友 - 自从我在大学的统计课程已经很长时间了......我需要计算一个图表上趋势线的起点和终点 - 有一个简单的方法吗?(在C#中工作,但无论什么语言适合你)



1> matt..:

感谢所有人的帮助 - 我已经离开这个问题了几天而且刚刚回到它 - 能够将它拼凑在一起 - 不是最优雅的代码,但它适用于我的目的 - 我想分享如果其他人遇到这个问题:

public class Statistics
{
    public Trendline CalculateLinearRegression(int[] values)
    {
        var yAxisValues = new List();
        var xAxisValues = new List();

        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 xAxisValues;
    private readonly IList yAxisValues;
    private int count;
    private int xAxisValuesSum;
    private int xxSum;
    private int xySum;
    private int yAxisValuesSum;

    public Trendline(IList yAxisValues, IList 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;
    }
}


考虑Bedwyr Humphreys提出的解决方案

2> blank..:

好的,这是我最好的伪数学:

你的线的等式是:

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是点数


这个是真正的答案,虽然我更喜欢b*n/n去除n分数

3> Adam Davis..:

鉴于趋势线是直的,通过选择任意两个点并计算来找到斜率:

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

然后你需要找到该行的偏移量.该行由以下等式指定:

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

所以你需要解决偏移问题.选择线上的任何点,并求解偏移量:

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

现在,您可以将斜率和偏移量插入到线方程(B)中,并使用定义线的方程式.如果你的线路有噪声,你必须决定平均算法,或者使用某种曲线拟合.

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

此外,如果这是一次性,使用Excel.


我相当肯定这不会产生合适的趋势线; 在(A)中计算的斜率将根据您选择的"两个点"而显着不同.这不是一个合适的趋势线.
[我更喜欢我找到的这个](http://math.stackexchange.com/questions/204020/what-is-the-equation-used-to-calculate-a-linear-trendline/204021#204021)

4> Thymine..:

这是Bedwyr Humphreys答案的一个非常快速(和半肮脏)的实现.该接口也应该与@matt的答案兼容,但是使用更多的IEnumerable概念来decimal代替int并使用更多IEnumerable概念,以便更容易使用和阅读.

Slopeb,Intercepta

public class Trendline
{
    public Trendline(IList yAxisValues, IList xAxisValues)
        : this(yAxisValues.Select((t, i) => new Tuple(xAxisValues[i], t)))
    { }
    public Trendline(IEnumerable> 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;
    }
}

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有