Comment calculer une courbe de tendance pour un graphique?

Google n’est pas mon ami – il y a longtemps que je ne travaillais pas à l’université… Je dois calculer les points de départ et de fin d’une courbe de tendance sur un graphique – y a-t-il un moyen facile de le faire? (travailler en C # mais quelle que soit la langue qui vous convient)

Étant donné que la courbe de tendance est droite, trouvez la pente en choisissant deux points et en calculant:

(A) pente = (y1-y2) / (x1-x2)

Ensuite, vous devez trouver le décalage pour la ligne. La ligne est spécifiée par l’équation:

(B) y = décalage + pente * x

Donc, vous devez résoudre pour offset. Choisissez n’importe quel point sur la ligne et résolvez le décalage:

(C) offset = y – (pente * x)

Vous pouvez maintenant twigr la pente et l’offset dans l’équation de la ligne (B) et avoir l’équation qui définit votre ligne. Si votre ligne présente du bruit, vous devrez choisir un algorithme de calcul de la moyenne ou utiliser un ajustement de courbe quelconque.

Si votre ligne n’est pas droite, vous devrez vous pencher sur l’ ajustement de courbe ou l’ ajustement de moindres carrés – non sortingvial, mais réalisable. Vous verrez les différents types d’ajustement de la courbe au bas de la page Web d’adaptation des moindres carrés (exponentielle, polynomiale, etc.) si vous savez quel type d’ajustement vous souhaitez.

En outre, s’il s’agit d’une opération unique, utilisez Excel.

Merci à tous pour votre aide – j’étais en dehors de ce problème pendant quelques jours et je suis revenu à lui – était capable de bricoler cela – pas le code le plus élégant, mais cela fonctionne pour moi – pensais que je partagerais si quelqu’un d’autre rencontre ce problème:

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; } } 

OK, voici mes meilleurs pseudo-maths:

L’équation de votre ligne est la suivante:

Y = a + bX

Où:

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

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

Où sum (xy) est la sum de tous les x * y etc. Pas particulièrement clair je concède, mais c’est le mieux que je puisse faire sans symbole sigma 🙂

… et maintenant avec ajouté Sigma

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

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

Où Σ (xy) est la sum de tous les x * y etc. et n est le nombre de points

Voici une implémentation très rapide (et semi-sale) de la réponse de Bedwyr Humphreys . L’interface devrait également être compatible avec la réponse de @matt , mais utilise decimal au lieu de int et utilise plus de concepts IEnumerable pour en faciliter l’utilisation et la lecture.

Slope est b , l’ Intercept est a

 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; } } 

Concernant une réponse précédente

si (B) y = décalage + pente * x

alors (C) offset = y / (pente * x) est faux

(C) devrait être:

offset = y- (pente * x)

Voir: http://zedgraph.org/wiki/index.php?title=Trend

Si vous avez access à Excel, consultez la section “Fonctions statistiques” de la référence de fonction dans l’aide. Pour un meilleur ajustement en ligne droite, il vous faut SLOPE et INTERCEPT et les équations sont là.

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 bouge pas la page, auquel cas essayez Googling pour quelque chose comme “SLOPE INTERCEPT EQUATION Excel site: microsoft.com” – le lien donné est arrivé troisième en ce moment.

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 = (sum (x * y) – sum (x) sum (y) / n) / (sum (x ^ 2) – sum (x) ^ 2 / n)
b = sum (y) / n – b (sum (x) / n)
(attention mes a et b sont la solution b et a dans MUHD).

– fait 4 colonnes, par exemple:
NB: mes valeurs y sont en B3: B17, donc j’ai n = 15;
mes valeurs de x sont 1,2,3,4 … 15.
1. Colonne B: x connus
2. Colonne C: Y’s 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: x valeurs au carré
Je résume ensuite les colonnes B, C et E, les sums vont à la ligne 18 pour moi, donc j’ai B18 comme sum de X, C18 comme sum de Y, E18 comme sum de X * Y et F18 comme sum de carrés.
Pour calculer a, entrez la formule suivante dans n’importe quelle cellule (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)
Les valeurs de la colonne D, calculant la ligne de tendance en fonction de y = ax + b:
D3 = $ F $ 35 * B3 + $ F $ 36, D4 = $ F $ 35 * B4 + $ F $ 36 et ainsi de suite (jusqu’à 17 jours pour moi).

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

Voici comment j’ai calculé la pente: Source: http://classroom.synonym.com/calculate-trendline-2709.html

 class Program { public double CalculateTrendlineSlope(List 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; } 

Voici ce que j’ai fini par utiliser.

 public class DataPoint { 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> 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 dataset utilise un horodatage Unix pour l’axe des x et un décimal pour le y. Modifiez ces types de données pour répondre à vos besoins. Je fais tous les calculs de sum en une seule itération pour obtenir les meilleures performances possibles.