linear_regression_trend 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 05074c1f4e06c89e698f4d9d99d439aee11fc26c
4
+ data.tar.gz: ac2f212b84fe4de2532f014ce870b2f27af37e88
5
+ SHA512:
6
+ metadata.gz: 30d2501dbec0fa7a943d1ad71fcf282c6809b5b27636f5cacc7dcf7b31f44425e57bcd6ae6c98ac987dd5721fc5168b0a2f4150980095e44fefe73cb28bcc45e
7
+ data.tar.gz: f03e63443411825fbe0a49d233b19fe340395ca5081e451edef1e0fe5ef47c9dbcb17659e49cd12acff3a9d234833234059b0f29dcba4217661b1f6d46b34884
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in linear_regression_trend.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,40 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # RSpec files
32
+ rspec = dsl.rspec
33
+ watch(rspec.spec_helper) { rspec.spec_dir }
34
+ watch(rspec.spec_support) { rspec.spec_dir }
35
+ watch(rspec.spec_files)
36
+
37
+ # Ruby files
38
+ ruby = dsl.ruby
39
+ dsl.watch_spec_files_for(ruby.lib_files)
40
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Gabriel Fortuna
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Linear Regression Trend Calculator [![Build Status](https://travis-ci.org/zero-one-software/linear_regression_trend.svg)](https://travis-ci.org/zero-one-software/linear_regression_trend)
2
+
3
+ This is a simple gem to help calculate linear regression trendlines for a given list of samples.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'linear_regression_trend'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install linear_regression_trend
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ my_array_of_samples = [10, 14, 18, 22, 26]
25
+ trender = LinearRegressionTrend::Calculator.new(my_array_of_samples)
26
+
27
+ trended_samples = trender.trend # => [array of trend points]
28
+ trend_slope = trender.slope # => 4
29
+ trend_intercept = trender.intercept # => 6
30
+ ```
31
+
32
+ ## Development
33
+
34
+ Check out the tests in the /spec dir, and also install iRuby notebook, and take a look at the live documentation in /doc.
35
+
36
+ ## Contributing
37
+
38
+ 1. Fork it ( https://github.com/zero-one-software/linear_regression_trend/fork )
39
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
40
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
41
+ 4. Push to the branch (`git push origin my-new-feature`)
42
+ 5. Add some tests
43
+ 6. Create a new Pull Request
44
+ 7. Do a happy dance
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "linear_regression_trend"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,212 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Linear regression trendline calculator\n",
8
+ "\n",
9
+ "Require the gem as per below. We'll require a few more for the notebook"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "code",
14
+ "execution_count": 29,
15
+ "metadata": {
16
+ "collapsed": false
17
+ },
18
+ "outputs": [
19
+ {
20
+ "data": {
21
+ "text/plain": [
22
+ "false"
23
+ ]
24
+ },
25
+ "execution_count": 29,
26
+ "metadata": {},
27
+ "output_type": "execute_result"
28
+ }
29
+ ],
30
+ "source": [
31
+ "require 'pry'\n",
32
+ "require 'awesome_print'\n",
33
+ "require 'nyaplot'\n",
34
+ "\n",
35
+ "require 'linear_regression_trend'"
36
+ ]
37
+ },
38
+ {
39
+ "cell_type": "markdown",
40
+ "metadata": {},
41
+ "source": [
42
+ "# Usage\n",
43
+ "\n",
44
+ "Have an array of samples handy, create a trend object like so:\n",
45
+ "\n",
46
+ "```ruby\n",
47
+ "trender = LinearRegressionTrend::Calculator.new(my_array_of_samples)\n",
48
+ "\n",
49
+ "trended_samples = trender.trend\n",
50
+ "trend_slope = trender.slope\n",
51
+ "trend_intercept = trender.intercept\n",
52
+ "```\n",
53
+ "\n",
54
+ "See the below example for more examples, and a visualisation."
55
+ ]
56
+ },
57
+ {
58
+ "cell_type": "code",
59
+ "execution_count": 30,
60
+ "metadata": {
61
+ "collapsed": false,
62
+ "scrolled": true
63
+ },
64
+ "outputs": [
65
+ {
66
+ "data": {
67
+ "text/html": [
68
+ "<table><tr><td>Slope</td><td>Intercept</td></tr><tr><td>-0.06384615384615384</td><td>10.31</td></tr></table>"
69
+ ],
70
+ "text/plain": [
71
+ "\"<table><tr><td>Slope</td><td>Intercept</td></tr><tr><td>-0.06384615384615384</td><td>10.31</td></tr></table>\""
72
+ ]
73
+ },
74
+ "metadata": {},
75
+ "output_type": "display_data"
76
+ }
77
+ ],
78
+ "source": [
79
+ "y = [1,2,3,6,10,11,12,12,12,12,15,18,18,16,16,15,14,11,9,9,7,4,2,1,1]\n",
80
+ "x = (1..y.size).to_a.map { |n| n.to_s }\n",
81
+ "\n",
82
+ "t = LinearRegressionTrend::Calculator.new(y)\n",
83
+ "\n",
84
+ "IRuby.display IRuby.table([['Slope', 'Intercept'], [t.slope, t.intercept]])"
85
+ ]
86
+ },
87
+ {
88
+ "cell_type": "markdown",
89
+ "metadata": {},
90
+ "source": [
91
+ "## Given a known set of samples"
92
+ ]
93
+ },
94
+ {
95
+ "cell_type": "code",
96
+ "execution_count": 31,
97
+ "metadata": {
98
+ "collapsed": false,
99
+ "scrolled": true
100
+ },
101
+ "outputs": [
102
+ {
103
+ "data": {
104
+ "text/html": [
105
+ "<div id='vis-ad2457ed-3897-43b1-9419-3b479887e90f'></div>\n",
106
+ "<script>\n",
107
+ "(function(){\n",
108
+ " var render = function(){\n",
109
+ " var model = {\"panes\":[{\"diagrams\":[{\"type\":\"bar\",\"options\":{\"x\":\"data0\",\"y\":\"data1\"},\"data\":\"edffbbde-4dfd-4ec1-9632-fb0b34ab51ed\"}],\"options\":{\"width\":700,\"xrange\":[\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"25\"],\"yrange\":[0,18]}}],\"data\":{\"edffbbde-4dfd-4ec1-9632-fb0b34ab51ed\":[{\"data0\":\"1\",\"data1\":1},{\"data0\":\"2\",\"data1\":2},{\"data0\":\"3\",\"data1\":3},{\"data0\":\"4\",\"data1\":6},{\"data0\":\"5\",\"data1\":10},{\"data0\":\"6\",\"data1\":11},{\"data0\":\"7\",\"data1\":12},{\"data0\":\"8\",\"data1\":12},{\"data0\":\"9\",\"data1\":12},{\"data0\":\"10\",\"data1\":12},{\"data0\":\"11\",\"data1\":15},{\"data0\":\"12\",\"data1\":18},{\"data0\":\"13\",\"data1\":18},{\"data0\":\"14\",\"data1\":16},{\"data0\":\"15\",\"data1\":16},{\"data0\":\"16\",\"data1\":15},{\"data0\":\"17\",\"data1\":14},{\"data0\":\"18\",\"data1\":11},{\"data0\":\"19\",\"data1\":9},{\"data0\":\"20\",\"data1\":9},{\"data0\":\"21\",\"data1\":7},{\"data0\":\"22\",\"data1\":4},{\"data0\":\"23\",\"data1\":2},{\"data0\":\"24\",\"data1\":1},{\"data0\":\"25\",\"data1\":1}]},\"extension\":[]}\n",
110
+ " var id_name = '#vis-ad2457ed-3897-43b1-9419-3b479887e90f';\n",
111
+ " Nyaplot.core.parse(model, id_name);\n",
112
+ "\n",
113
+ " require(['downloadable'], function(downloadable){\n",
114
+ " var svg = d3.select(id_name).select(\"svg\");\n",
115
+ "\t if(!svg.empty())\n",
116
+ "\t svg.call(downloadable().filename('fig'));\n",
117
+ "\t});\n",
118
+ " };\n",
119
+ " if(window['Nyaplot']==undefined){\n",
120
+ " window.addEventListener('load_nyaplot', render, false);\n",
121
+ "\treturn;\n",
122
+ " } else {\n",
123
+ " render();\n",
124
+ " }\n",
125
+ "})();\n",
126
+ "</script>\n"
127
+ ],
128
+ "text/plain": [
129
+ "#<Nyaplot::Frame:0x007fd5a1c5e030 @properties={:panes=>[#<Nyaplot::Plot:0x007fd5a1c6f600 @properties={:diagrams=>[#<Nyaplot::Diagram:0x007fd5a1c5f7f0 @properties={:type=>:bar, :options=>{:x=>\"data0\", :y=>\"data1\"}, :data=>\"edffbbde-4dfd-4ec1-9632-fb0b34ab51ed\"}, @xrange=[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"18\", \"19\", \"20\", \"21\", \"22\", \"23\", \"24\", \"25\"], @yrange=[0, 18]>], :options=>{:width=>700, :xrange=>[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"18\", \"19\", \"20\", \"21\", \"22\", \"23\", \"24\", \"25\"], :yrange=>[0, 18]}}>], :data=>{\"edffbbde-4dfd-4ec1-9632-fb0b34ab51ed\"=>#<Nyaplot::DataFrame:0x007fd5a1c6e548 @name=\"edffbbde-4dfd-4ec1-9632-fb0b34ab51ed\", @rows=[{:data0=>\"1\", :data1=>1}, {:data0=>\"2\", :data1=>2}, {:data0=>\"3\", :data1=>3}, {:data0=>\"4\", :data1=>6}, {:data0=>\"5\", :data1=>10}, {:data0=>\"6\", :data1=>11}, {:data0=>\"7\", :data1=>12}, {:data0=>\"8\", :data1=>12}, {:data0=>\"9\", :data1=>12}, {:data0=>\"10\", :data1=>12}, {:data0=>\"11\", :data1=>15}, {:data0=>\"12\", :data1=>18}, {:data0=>\"13\", :data1=>18}, {:data0=>\"14\", :data1=>16}, {:data0=>\"15\", :data1=>16}, {:data0=>\"16\", :data1=>15}, {:data0=>\"17\", :data1=>14}, {:data0=>\"18\", :data1=>11}, {:data0=>\"19\", :data1=>9}, {:data0=>\"20\", :data1=>9}, {:data0=>\"21\", :data1=>7}, {:data0=>\"22\", :data1=>4}, {:data0=>\"23\", :data1=>2}, {:data0=>\"24\", :data1=>1}, {:data0=>\"25\", :data1=>1}]>}, :extension=>[]}>"
130
+ ]
131
+ },
132
+ "metadata": {},
133
+ "output_type": "display_data"
134
+ }
135
+ ],
136
+ "source": [
137
+ "chart = Nyaplot::Plot.new \n",
138
+ "chart.add(:bar, x, y)\n",
139
+ "chart.show"
140
+ ]
141
+ },
142
+ {
143
+ "cell_type": "markdown",
144
+ "metadata": {},
145
+ "source": [
146
+ "## The trendline for that sample set should be a descending trend"
147
+ ]
148
+ },
149
+ {
150
+ "cell_type": "code",
151
+ "execution_count": 32,
152
+ "metadata": {
153
+ "collapsed": false
154
+ },
155
+ "outputs": [
156
+ {
157
+ "data": {
158
+ "text/html": [
159
+ "<div id='vis-c1b75112-253e-4559-942a-d373c3195b44'></div>\n",
160
+ "<script>\n",
161
+ "(function(){\n",
162
+ " var render = function(){\n",
163
+ " var model = {\"panes\":[{\"diagrams\":[{\"type\":\"bar\",\"options\":{\"x\":\"data0\",\"y\":\"data1\"},\"data\":\"f941170d-a90d-443e-917d-24e50bb8a8c3\"}],\"options\":{\"width\":700,\"xrange\":[\"1\",\"2\",\"3\",\"4\",\"5\",\"6\",\"7\",\"8\",\"9\",\"10\",\"11\",\"12\",\"13\",\"14\",\"15\",\"16\",\"17\",\"18\",\"19\",\"20\",\"21\",\"22\",\"23\",\"24\",\"25\"],\"yrange\":[0,10.246153846153847]}}],\"data\":{\"f941170d-a90d-443e-917d-24e50bb8a8c3\":[{\"data0\":\"1\",\"data1\":10.246153846153847},{\"data0\":\"2\",\"data1\":10.182307692307694},{\"data0\":\"3\",\"data1\":10.118461538461538},{\"data0\":\"4\",\"data1\":10.054615384615385},{\"data0\":\"5\",\"data1\":9.990769230769232},{\"data0\":\"6\",\"data1\":9.926923076923078},{\"data0\":\"7\",\"data1\":9.863076923076923},{\"data0\":\"8\",\"data1\":9.79923076923077},{\"data0\":\"9\",\"data1\":9.735384615384616},{\"data0\":\"10\",\"data1\":9.671538461538463},{\"data0\":\"11\",\"data1\":9.607692307692307},{\"data0\":\"12\",\"data1\":9.543846153846154},{\"data0\":\"13\",\"data1\":9.48},{\"data0\":\"14\",\"data1\":9.416153846153847},{\"data0\":\"15\",\"data1\":9.352307692307694},{\"data0\":\"16\",\"data1\":9.288461538461538},{\"data0\":\"17\",\"data1\":9.224615384615385},{\"data0\":\"18\",\"data1\":9.160769230769231},{\"data0\":\"19\",\"data1\":9.096923076923078},{\"data0\":\"20\",\"data1\":9.033076923076923},{\"data0\":\"21\",\"data1\":8.96923076923077},{\"data0\":\"22\",\"data1\":8.905384615384616},{\"data0\":\"23\",\"data1\":8.841538461538462},{\"data0\":\"24\",\"data1\":8.777692307692309},{\"data0\":\"25\",\"data1\":8.713846153846154}]},\"extension\":[]}\n",
164
+ " var id_name = '#vis-c1b75112-253e-4559-942a-d373c3195b44';\n",
165
+ " Nyaplot.core.parse(model, id_name);\n",
166
+ "\n",
167
+ " require(['downloadable'], function(downloadable){\n",
168
+ " var svg = d3.select(id_name).select(\"svg\");\n",
169
+ "\t if(!svg.empty())\n",
170
+ "\t svg.call(downloadable().filename('fig'));\n",
171
+ "\t});\n",
172
+ " };\n",
173
+ " if(window['Nyaplot']==undefined){\n",
174
+ " window.addEventListener('load_nyaplot', render, false);\n",
175
+ "\treturn;\n",
176
+ " } else {\n",
177
+ " render();\n",
178
+ " }\n",
179
+ "})();\n",
180
+ "</script>\n"
181
+ ],
182
+ "text/plain": [
183
+ "#<Nyaplot::Frame:0x007fd5a1b251c8 @properties={:panes=>[#<Nyaplot::Plot:0x007fd5a1b2c8d8 @properties={:diagrams=>[#<Nyaplot::Diagram:0x007fd5a1b25a10 @properties={:type=>:bar, :options=>{:x=>\"data0\", :y=>\"data1\"}, :data=>\"f941170d-a90d-443e-917d-24e50bb8a8c3\"}, @xrange=[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"18\", \"19\", \"20\", \"21\", \"22\", \"23\", \"24\", \"25\"], @yrange=[0, 10.246153846153847]>], :options=>{:width=>700, :xrange=>[\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"10\", \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"18\", \"19\", \"20\", \"21\", \"22\", \"23\", \"24\", \"25\"], :yrange=>[0, 10.246153846153847]}}>], :data=>{\"f941170d-a90d-443e-917d-24e50bb8a8c3\"=>#<Nyaplot::DataFrame:0x007fd5a1b2c220 @name=\"f941170d-a90d-443e-917d-24e50bb8a8c3\", @rows=[{:data0=>\"1\", :data1=>10.246153846153847}, {:data0=>\"2\", :data1=>10.182307692307694}, {:data0=>\"3\", :data1=>10.118461538461538}, {:data0=>\"4\", :data1=>10.054615384615385}, {:data0=>\"5\", :data1=>9.990769230769232}, {:data0=>\"6\", :data1=>9.926923076923078}, {:data0=>\"7\", :data1=>9.863076923076923}, {:data0=>\"8\", :data1=>9.79923076923077}, {:data0=>\"9\", :data1=>9.735384615384616}, {:data0=>\"10\", :data1=>9.671538461538463}, {:data0=>\"11\", :data1=>9.607692307692307}, {:data0=>\"12\", :data1=>9.543846153846154}, {:data0=>\"13\", :data1=>9.48}, {:data0=>\"14\", :data1=>9.416153846153847}, {:data0=>\"15\", :data1=>9.352307692307694}, {:data0=>\"16\", :data1=>9.288461538461538}, {:data0=>\"17\", :data1=>9.224615384615385}, {:data0=>\"18\", :data1=>9.160769230769231}, {:data0=>\"19\", :data1=>9.096923076923078}, {:data0=>\"20\", :data1=>9.033076923076923}, {:data0=>\"21\", :data1=>8.96923076923077}, {:data0=>\"22\", :data1=>8.905384615384616}, {:data0=>\"23\", :data1=>8.841538461538462}, {:data0=>\"24\", :data1=>8.777692307692309}, {:data0=>\"25\", :data1=>8.713846153846154}]>}, :extension=>[]}>"
184
+ ]
185
+ },
186
+ "metadata": {},
187
+ "output_type": "display_data"
188
+ }
189
+ ],
190
+ "source": [
191
+ "chart = Nyaplot::Plot.new \n",
192
+ "chart.add(:bar, x, t.trend)\n",
193
+ "chart.show"
194
+ ]
195
+ }
196
+ ],
197
+ "metadata": {
198
+ "kernelspec": {
199
+ "display_name": "Ruby 2.1.2",
200
+ "language": "ruby",
201
+ "name": "ruby"
202
+ },
203
+ "language_info": {
204
+ "file_extension": "rb",
205
+ "mimetype": "application/x-ruby",
206
+ "name": "ruby",
207
+ "version": "2.1.2"
208
+ }
209
+ },
210
+ "nbformat": 4,
211
+ "nbformat_minor": 0
212
+ }
@@ -0,0 +1,93 @@
1
+ require "linear_regression_trend/version"
2
+
3
+ # Adapted from a C# example here:
4
+ # http://stackoverflow.com/questions/43224/how-do-i-calculate-a-trendline-for-a-graph
5
+
6
+ # And thanks to John Esser for helping figure out how to
7
+ # calculate the targets to stabilize a negative slope!
8
+
9
+ module LinearRegressionTrend
10
+ class Calculator
11
+ attr_accessor :slope, :intercept
12
+
13
+ # Pass in an array of values to get the regression on
14
+ def initialize y_values
15
+ @y_values = y_values
16
+ @size = @y_values.size
17
+ @x_values = (1..@size).to_a
18
+
19
+ #initialize everything to 0
20
+ sum_x = 0
21
+ sum_y = 0
22
+ sum_xx = 0
23
+ sum_xy = 0
24
+
25
+ # calculate the sums
26
+ @y_values.zip(@x_values).each do |y, x|
27
+ sum_xy += x*y
28
+ sum_xx += x*x
29
+ sum_x += x
30
+ sum_y += y
31
+ end
32
+
33
+ # calculate the slope
34
+ @slope = 1.0 * ((@size * sum_xy) - (sum_x * sum_y)) / ((@size * sum_xx) - (sum_x * sum_x))
35
+ @intercept = 1.0 * (sum_y - (@slope * sum_x)) / @size
36
+ end
37
+
38
+ # Get the y-axis values of the trend line
39
+ def trend
40
+ @x_values.map { |x| predict(x) }
41
+ end
42
+
43
+ # Get the Y value for any given X value
44
+ # from y = mx + b, or
45
+ # y = slope * x + intercept
46
+ def predict( x )
47
+ @slope * x + @intercept
48
+ end
49
+
50
+ # Get the "next" value if the sequence
51
+ # was continued one more element
52
+ def next
53
+ predict (@size + 1)
54
+ end
55
+
56
+ # Determine the target needed to stabilize
57
+ # the slope back to 0, assuming slope is
58
+ # negative. The target returned will be
59
+ # the number needed to have stabilized slope
60
+ # inclusive of all values in the set
61
+ def stabilize_over_all
62
+ stabilize @y_values
63
+ end
64
+
65
+ # Determine the target needed to stabilize
66
+ # the slope back to 0, assuming slope is
67
+ # negative. The target returned will be
68
+ # the number needed to have stabilized slope
69
+ # over a set of values of size n (including
70
+ # the target value
71
+ def stabilize_over_n_values(n)
72
+ values = []
73
+ values = @y_values.last(n-1) if n - 1 >= 0
74
+
75
+ stabilize values
76
+ end
77
+
78
+ private
79
+
80
+ def stabilize(values)
81
+ n = values.length
82
+ sum = 0
83
+ target = 0
84
+
85
+ values.each_with_index do |value, i|
86
+ sum += (n - (2 * i)) * value
87
+ end
88
+
89
+ target = 1.0 * sum / n if n > 0
90
+ target
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,3 @@
1
+ module LinearRegressionTrend
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'linear_regression_trend/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "linear_regression_trend"
8
+ spec.version = LinearRegressionTrend::VERSION
9
+ spec.authors = ["Gabriel Fortuna"]
10
+ spec.email = ["gee.forr@gmail.com"]
11
+
12
+ spec.summary = 'A library for calculating linear trend regressions against a time series data set'
13
+ spec.description = 'A simple library for calculating linear trend regressions against a time series data set. See README for more info'
14
+ spec.homepage = "https://github.com/zero-one-software/linear_regression_trend"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.9"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "pry", "~> 0.10.1"
24
+ spec.add_development_dependency "rspec", "~> 3.3"
25
+ spec.add_development_dependency "guard-rspec", "~> 4.6"
26
+ spec.add_development_dependency "iruby", "~> 0.2.7"
27
+ spec.add_development_dependency "nyaplot", "~> 0.1.5"
28
+ spec.add_development_dependency "awesome_print", "~> 1.2"
29
+ end
metadata ADDED
@@ -0,0 +1,172 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: linear_regression_trend
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Gabriel Fortuna
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.10.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.10.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.6'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: iruby
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.2.7
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.2.7
97
+ - !ruby/object:Gem::Dependency
98
+ name: nyaplot
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.1.5
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.1.5
111
+ - !ruby/object:Gem::Dependency
112
+ name: awesome_print
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.2'
125
+ description: A simple library for calculating linear trend regressions against a time
126
+ series data set. See README for more info
127
+ email:
128
+ - gee.forr@gmail.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - ".rspec"
135
+ - ".travis.yml"
136
+ - Gemfile
137
+ - Guardfile
138
+ - LICENSE.txt
139
+ - README.md
140
+ - Rakefile
141
+ - bin/console
142
+ - bin/setup
143
+ - doc/Linear regression playground.ipynb
144
+ - lib/linear_regression_trend.rb
145
+ - lib/linear_regression_trend/version.rb
146
+ - linear_regression_trend.gemspec
147
+ homepage: https://github.com/zero-one-software/linear_regression_trend
148
+ licenses:
149
+ - MIT
150
+ metadata: {}
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ requirements: []
166
+ rubyforge_project:
167
+ rubygems_version: 2.4.5
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: A library for calculating linear trend regressions against a time series
171
+ data set
172
+ test_files: []