regression.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package stats
  2. import "math"
  3. // Series is a container for a series of data
  4. type Series []Coordinate
  5. // Coordinate holds the data in a series
  6. type Coordinate struct {
  7. X, Y float64
  8. }
  9. // LinearRegression finds the least squares linear regression on data series
  10. func LinearRegression(s Series) (regressions Series, err error) {
  11. if len(s) == 0 {
  12. return nil, EmptyInput
  13. }
  14. // Placeholder for the math to be done
  15. var sum [5]float64
  16. // Loop over data keeping index in place
  17. i := 0
  18. for ; i < len(s); i++ {
  19. sum[0] += s[i].X
  20. sum[1] += s[i].Y
  21. sum[2] += s[i].X * s[i].X
  22. sum[3] += s[i].X * s[i].Y
  23. sum[4] += s[i].Y * s[i].Y
  24. }
  25. // Find gradient and intercept
  26. f := float64(i)
  27. gradient := (f*sum[3] - sum[0]*sum[1]) / (f*sum[2] - sum[0]*sum[0])
  28. intercept := (sum[1] / f) - (gradient * sum[0] / f)
  29. // Create the new regression series
  30. for j := 0; j < len(s); j++ {
  31. regressions = append(regressions, Coordinate{
  32. X: s[j].X,
  33. Y: s[j].X*gradient + intercept,
  34. })
  35. }
  36. return regressions, nil
  37. }
  38. // ExponentialRegression returns an exponential regression on data series
  39. func ExponentialRegression(s Series) (regressions Series, err error) {
  40. if len(s) == 0 {
  41. return nil, EmptyInput
  42. }
  43. var sum [6]float64
  44. for i := 0; i < len(s); i++ {
  45. sum[0] += s[i].X
  46. sum[1] += s[i].Y
  47. sum[2] += s[i].X * s[i].X * s[i].Y
  48. sum[3] += s[i].Y * math.Log(s[i].Y)
  49. sum[4] += s[i].X * s[i].Y * math.Log(s[i].Y)
  50. sum[5] += s[i].X * s[i].Y
  51. }
  52. denominator := (sum[1]*sum[2] - sum[5]*sum[5])
  53. a := math.Pow(math.E, (sum[2]*sum[3]-sum[5]*sum[4])/denominator)
  54. b := (sum[1]*sum[4] - sum[5]*sum[3]) / denominator
  55. for j := 0; j < len(s); j++ {
  56. regressions = append(regressions, Coordinate{
  57. X: s[j].X,
  58. Y: a * math.Exp(b*s[j].X),
  59. })
  60. }
  61. return regressions, nil
  62. }
  63. // LogarithmicRegression returns an logarithmic regression on data series
  64. func LogarithmicRegression(s Series) (regressions Series, err error) {
  65. if len(s) == 0 {
  66. return nil, EmptyInput
  67. }
  68. var sum [4]float64
  69. i := 0
  70. for ; i < len(s); i++ {
  71. sum[0] += math.Log(s[i].X)
  72. sum[1] += s[i].Y * math.Log(s[i].X)
  73. sum[2] += s[i].Y
  74. sum[3] += math.Pow(math.Log(s[i].X), 2)
  75. }
  76. f := float64(i)
  77. a := (f*sum[1] - sum[2]*sum[0]) / (f*sum[3] - sum[0]*sum[0])
  78. b := (sum[2] - a*sum[0]) / f
  79. for j := 0; j < len(s); j++ {
  80. regressions = append(regressions, Coordinate{
  81. X: s[j].X,
  82. Y: b + a*math.Log(s[j].X),
  83. })
  84. }
  85. return regressions, nil
  86. }