lib/blazer/result.rb in blazer-2.2.1 vs lib/blazer/result.rb in blazer-2.2.2
- old
+ new
@@ -83,14 +83,48 @@
def forecastable?
@forecastable ||= Blazer.forecasting && column_types == ["time", "numeric"] && @rows.size >= 10
end
+ # TODO cache it?
+ # don't want to put result data (even hashed version)
+ # into cache without developer opt-in
def forecast
- # TODO cache it?
- # don't want to put result data (even hashed version)
- # into cache without developer opt-in
- forecast = Trend.forecast(Hash[@rows], count: 30)
+ count = (@rows.size * 0.25).round.clamp(30, 365)
+
+ case Blazer.forecasting
+ when "prophet"
+ require "prophet"
+
+ df =
+ Daru::DataFrame.new(
+ "ds" => @rows.map { |r| r[0] },
+ "y" => @rows.map { |r| r[1] }
+ )
+
+ # TODO determine frequency
+ freq = "D"
+
+ m = Prophet.new
+ m.fit(df)
+ future = m.make_future_dataframe(periods: count, freq: freq, include_history: false)
+ fcst = m.predict(future)
+ ds = fcst["ds"]
+ if @rows[0][0].is_a?(Date)
+ ds = ds.map { |v| v.to_date }
+ end
+ forecast = ds.zip(fcst["yhat"]).to_h
+ else
+ require "trend"
+
+ forecast = Trend.forecast(Hash[@rows], count: count)
+ end
+
+ # round integers
+ if @rows[0][1].is_a?(Integer)
+ forecast = forecast.map { |k, v| [k, v.round] }.to_h
+ end
+
@rows.each do |row|
row[2] = nil
end
@rows.unshift(*forecast.map { |k, v| [k, nil, v] })
@columns << "forecast"