Skip to content

Instantly share code, notes, and snippets.

@excid3
Created May 21, 2014 01:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save excid3/57405c8259644ef68e5e to your computer and use it in GitHub Desktop.
Save excid3/57405c8259644ef68e5e to your computer and use it in GitHub Desktop.
require "linefit"
require "time"
class Forecast
attr_accessor :counts, :dates, :intercept, :slope
def initialize(counts, dates)
@counts = counts
@dates = dates
unix_format_dates!
line_fit.setData(dates, counts)
@intercept, @slope = line_fit.coefficients
end
def calculate(target_date)
date = unix_formatted_date target_date
line_fit.forecast date
end
def line_fit
@lf ||= LineFit.new
end
def unix_format_dates!
dates.map! { |date| unix_formatted_date(date) }
end
def unix_formatted_date(date)
DateTime.parse(date).to_time.to_i
end
def print_slope
p slope
end
end
counts = [2, 4]
dates = ["2014-05-16", "2014-05-17"]
# counts = Item.pluck(:unit_counts)
# dates = Item.pluck(:created_at)
forecast = Forecast.new(counts, dates)
# p forecast.line_fit
# p forecast.line_fit
# forecast.print_slope
# p forecast.counts
# p forecast.dates
p forecast.calculate("2014-05-18")
# p forecast.line_fit.coefficients
require 'rubygems'
require 'linefit'
require 'date'
dates = [
'2014-05-01',
'2014-05-02',
'2014-05-03',
'2014-05-04',
'2014-05-05',
'2014-05-06',
'2014-05-07',
'2014-05-08',
'2014-05-09',
'2014-05-10',
'2014-05-11',
'2014-05-12',
'2014-05-13',
'2014-05-14'
]
itemcounts = [
100,
55,
93,
86,
80,
100,
60,
58,
10,
49,
47,
15,
38,
34
]
def unix_formatted_date(date)
DateTime.parse(date).to_time.to_i
end
def unix_formatted(dates)
dates.map do |date|
unix_formatted_date date
end
end
def forecast_line_fit(unix_dates, itemcounts)
lf = LineFit.new
lf.setData(unix_dates, itemcounts)
end
def forecast_for(item_counts, dates, target_item_count=10)
unix_dates = unix_formatted(dates)
lf = forecast_line_fit
intercept, slope = lf.coefficients
y = target_item_count
# Calculate the date (x)
x = (y - intercept) / slope
# About how many items will I have left on 2014-05-16
target_date = '2014-05-16'
# Set x to the unix time for our target date
x = unix_formatted_date(target_date)
y = (slope * x) + intercept
# can also use the LineFit#forecast method
y = lf.forecast(x)
end
forecast_for(item_counts, dates)
# Convert dates array into array of Unix timestamps
# unix_dates = dates.collect do |date|
# DateTime.parse(date).to_time.to_i
# end
# lf = LineFit.new
# lf.setData(unix_dates, itemcounts)
#
# intercept, slope = lf.coefficients
# Linear regression equation (for finding y, or item count)
# y = ax + b
#
# a = slope
# b = intercept
#
# Linear regression equation for finding x (date)
#
# y - b
# x = -------
# a
# Trend a date for when the item count will be 10 (Time to buy more!)
# Set target item count to 10
target_item_count = 10
y = target_item_count
# Calculate the date (x)
x = (y - intercept) / slope
#puts "Date when it's time to buy more (#{target_item_count} items left) is #{Time.at(x).to_date.to_s}"
# About how many items will I have left on 2014-05-16
target_date = '2014-05-16'
# Set x to the unix time for our target date
x = Date.parse(target_date).to_time.to_i
y = (slope * x) + intercept
# can also use the LineFit#forecast method
y = lf.forecast(x)
#puts "Forecasted item count for #{target_date} is #{y.round}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment