51 votes

Comment calculer une ligne de tendance pour un graphique ?

Google n'est pas mon ami - cela fait longtemps que je n'ai pas suivi de cours de statistiques à l'université... Je dois calculer les points de départ et d'arrivée d'une ligne de tendance sur un graphique - existe-t-il un moyen simple de le faire ? (je travaille en C# mais n'importe quel langage vous convient)

0 votes

L'ajustement par les moindres carrés est votre meilleure chance.

2voto

Mike Woodhouse Points 27748

Si vous avez accès à Excel, consultez la section "Fonctions statistiques" de la référence des fonctions dans l'aide. Pour la meilleure adéquation en ligne droite, vous avez besoin de SLOPE et INTERCEPT et les équations s'y trouvent.

Oh, attendez, ils sont également définis en ligne ici : http://office.microsoft.com/en-us/excel/HP052092641033.aspx pour SLOPE, et il y a un lien vers INTERCEPT. Bien sûr, cela suppose que MS ne déplace pas la page, auquel cas essayez de chercher sur Google quelque chose comme "SLOPE INTERCEPT EQUATION Excel site:microsoft.com" - le lien donné s'est avéré troisième à l'instant.

2voto

Gregg Reno Points 104

J'ai converti le code de Matt en Java pour pouvoir l'utiliser dans Android avec la bibliothèque MPAndroidChart. J'ai également utilisé des valeurs doubles au lieu de valeurs entières :

ArrayList<Entry> yValues2 = new ArrayList<>();

ArrayList<Double > xAxisValues = new ArrayList<Double>();
ArrayList<Double> yAxisValues = new ArrayList<Double>();

for (int i = 0; i < readings.size(); i++)
{
    r = readings.get(i);
    yAxisValues.add(r.value);
    xAxisValues.add((double)i + 1);
}

TrendLine tl = new TrendLine(yAxisValues, xAxisValues);

//Create the y values for the trend line
double currY = tl.Start;
for (int i = 0; i < readings.size(); ++ i) {
    yValues2.add(new Entry(i, (float) currY));
    currY = currY + tl.Slope;
}

...

public class TrendLine
{
    private ArrayList<Double> xAxisValues = new ArrayList<Double>();
    private ArrayList<Double> yAxisValues = new ArrayList<Double>();

    private int count;
    private double xAxisValuesSum;
    private double xxSum;
    private double xySum;
    private double yAxisValuesSum;

    public TrendLine(ArrayList<Double> yAxisValues, ArrayList<Double> xAxisValues)
    {
        this.yAxisValues = yAxisValues;
        this.xAxisValues = xAxisValues;

        this.Initialize();
    }

    public double Slope;
    public double Intercept;
    public double Start;
    public double End;

    private double getArraySum(ArrayList<Double> arr) {
        double sum = 0;
        for (int i = 0; i < arr.size(); ++i) {
            sum = sum + arr.get(i);
        }
        return sum;
    }
    private void Initialize()
    {
        this.count = this.yAxisValues.size();
        this.yAxisValuesSum = getArraySum(this.yAxisValues);
        this.xAxisValuesSum = getArraySum(this.xAxisValues);
        this.xxSum = 0;
        this.xySum = 0;

        for (int i = 0; i < this.count; i++)
        {
            this.xySum += (this.xAxisValues.get(i)*this.yAxisValues.get(i));
            this.xxSum += (this.xAxisValues.get(i)*this.xAxisValues.get(i));
        }

        this.Slope = this.CalculateSlope();
        this.Intercept = this.CalculateIntercept();
        this.Start = this.CalculateStart();
        this.End = this.CalculateEnd();
    }

    private double CalculateSlope()
    {
        try
        {
            return ((this.count*this.xySum) - (this.xAxisValuesSum*this.yAxisValuesSum))/((this.count*this.xxSum) - (this.xAxisValuesSum*this.xAxisValuesSum));
        }
        catch (Exception e)
        {
            return 0;
        }
    }

    private double CalculateIntercept()
    {
        return (this.yAxisValuesSum - (this.Slope*this.xAxisValuesSum))/this.count;
    }

    private double CalculateStart()
    {
        return (this.Slope*this.xAxisValues.get(0)) + this.Intercept;
    }

    private double CalculateEnd()
    {
        return (this.Slope*this.xAxisValues.get(this.xAxisValues.size()-1)) + this.Intercept;
    }
}

0 votes

J'ai cherché pendant des heures une solution et je suis finalement revenu à votre réponse et ça a marché ! Merci !

1voto

Magn3144 Points 11

C'est ainsi que j'ai calculé la pente : Source : http://classroom.synonym.com/calculate-trendline-2709.html

class Program
    {
        public double CalculateTrendlineSlope(List<Point> graph)
        {
            int n = graph.Count;
            double a = 0;
            double b = 0;
            double bx = 0;
            double by = 0;
            double c = 0;
            double d = 0;
            double slope = 0;

            foreach (Point point in graph)
            {
                a += point.x * point.y;
                bx = point.x;
                by = point.y;
                c += Math.Pow(point.x, 2);
                d += point.x;
            }
            a *= n;
            b = bx * by;
            c *= n;
            d = Math.Pow(d, 2);

            slope = (a - b) / (c - d);
            return slope;
        }
    }

    class Point
    {
        public double x;
        public double y;
    }

1voto

Todd Skelton Points 991

Voici ce que j'ai fini par utiliser.

public class DataPoint<T1,T2>
{
    public DataPoint(T1 x, T2 y)
    {
        X = x;
        Y = y;
    }

    [JsonProperty("x")]
    public T1 X { get; }

    [JsonProperty("y")]
    public T2 Y { get; }
}

public class Trendline
{
    public Trendline(IEnumerable<DataPoint<long, decimal>> dataPoints)
    {
        int count = 0;
        long sumX = 0;
        long sumX2 = 0;
        decimal sumY = 0;
        decimal sumXY = 0;

        foreach (var dataPoint in dataPoints)
        {
            count++;
            sumX += dataPoint.X;
            sumX2 += dataPoint.X * dataPoint.X;
            sumY += dataPoint.Y;
            sumXY += dataPoint.X * dataPoint.Y;
        }

        Slope = (sumXY - ((sumX * sumY) / count)) / (sumX2 - ((sumX * sumX) / count));
        Intercept = (sumY / count) - (Slope * (sumX / count));
    }

    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 Slope * xValue + Intercept;
    }
}

Mon jeu de données utilise un timestamp Unix pour l'axe des x et un décimal pour l'axe des y. Changez ces types de données pour répondre à vos besoins. Je fais tous les calculs de somme en une seule itération pour obtenir les meilleures performances possibles.

0voto

franchsesko Points 1

Merci beaucoup pour la solution, je me grattais la tête.
Voici comment j'ai appliqué la solution dans Excel.
J'ai utilisé avec succès les deux fonctions données par MUHD dans Excel :
a = (somme(x*y) - somme(x)somme(y)/n) / (somme(x^2) - somme(x)^2/n)
b = somme(y)/n - b(somme(x)/n)
(attention mes a et b sont les b et a de la solution de MUHD).

- Faites 4 colonnes, par exemple :
NB : mes valeurs y sont dans B3:B17, donc j'ai n=15 ;
mes valeurs x sont 1,2,3,4...15.
1. Colonne B : x connus
2. Colonne C : Y connus
3. Colonne D : La ligne de tendance calculée
4. Colonne E : valeurs B * valeurs C (E3=B3*C3, E4=B4*C4, ..., E17=B17*C17)
5. Colonne F : valeurs au carré de x
J'additionne ensuite les colonnes B, C et E, les sommes vont à la ligne 18 pour moi, j'ai donc B18 comme somme de X, C18 comme somme de Y, E18 comme somme de X*Y, et F18 comme somme de carrés.
Pour calculer a, entrez la formule suivante dans une cellule quelconque (F35 pour moi) :
F35=(E18-(B18*C18)/15)/(F18-(B18*B18)/15)
Pour calculer b (en F36 pour moi) :
F36=C18/15-F35*(B18/15)
Valeurs de la colonne D, calcul de la ligne de tendance selon la formule y = ax + b :
D3=$F$35*B3+$F$36, D4=$F$35*B4+$F$36 et ainsi de suite (jusqu'à D17 pour moi).

Sélectionnez les données de la colonne (C2:D17) pour réaliser le graphique.
HTH.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X