pyFTS/ensemble.py

159 lines
5.2 KiB
Python

#!/usr/bin/python
# -*- coding: utf8 -*-
import numpy as np
import pandas as pd
import math
from operator import itemgetter
from pyFTS.common import FLR, FuzzySet, SortedCollection
from pyFTS import fts, chen, cheng, hofts, hwang, ismailefendi, sadaei, song, yu
from pyFTS.benchmarks import arima, quantreg
from pyFTS.common import Transformations
class EnsembleFTS(fts.FTS):
def __init__(self, name, **kwargs):
super(EnsembleFTS, self).__init__("Ensemble FTS")
self.shortname = "Ensemble FTS " + name
self.name = "Ensemble FTS"
self.flrgs = {}
self.has_point_forecasting = True
self.has_interval_forecasting = True
self.has_probability_forecasting = True
self.is_high_order = True
self.models = []
self.parameters = []
def build(self, data, models, partitioners, partitions, max_order=3, transformation=None, indexer=None):
methods = [song.ConventionalFTS, chen.ConventionalFTS, yu.WeightedFTS, cheng.TrendWeightedFTS,
ismailefendi.ImprovedWeightedFTS, sadaei.ExponentialyWeightedFTS, hwang.HighOrderFTS,
hofts.HighOrderFTS, arima.ARIMA, quantreg.QuantileRegression]
transformations = [None, Transformations.Differential(1)]
for count, method in enumerate(methods, start=0):
mfts = method("")
if mfts.benchmark_only:
if transformation is not None:
mfts.appendTransformation(transformation)
mfts.train(data,None, order=1, parameters=None)
self.models.append(mfts)
else:
for partition in partitions:
for partitioner in partitioners:
data_train_fs = partitioner(data, partition, transformation=transformation)
mfts = method("")
mfts.partitioner = data_train_fs
if not mfts.is_high_order:
if transformation is not None:
mfts.appendTransformation(transformation)
mfts.train(data, data_train_fs.sets)
self.models.append(mfts)
else:
for order in np.arange(1, max_order + 1):
if order >= mfts.min_order:
mfts = method("")
mfts.partitioner = data_train_fs
if transformation is not None:
mfts.appendTransformation(transformation)
mfts.train(data, data_train_fs.sets, order=order)
self.models.append(mfts)
def train(self, data, sets, order=1,parameters=None):
#if self.models is None:
pass
def forecast(self, data, **kwargs):
method = kwargs.get('method','mean')
ndata = np.array(self.doTransformations(data))
l = len(ndata)
ret = []
for k in np.arange(0, l+1):
tmp = []
for model in self.models:
if k >= model.minOrder - 1:
sample = ndata[k - model.order : k]
tmp.append( model.forecast(sample) )
if method == 'mean':
ret.append( np.nanmean(tmp))
elif method == 'median':
ret.append(np.percentile(tmp,50))
ret = self.doInverseTransformations(ret, params=[data[self.order - 1:]])
return ret
def forecastInterval(self, data, **kwargs):
method = kwargs.get('method', 'extremum')
ndata = np.array(self.doTransformations(data))
l = len(ndata)
ret = []
for k in np.arange(0, l):
tmp = []
for model in self.models:
if k >= model.minOrder - 1:
sample = ndata[k - model.order : k]
tmp.append( model.forecast(sample) )
if method == 'extremum':
ret.append( [ min(tmp), max(tmp) ] )
elif method == 'quantile':
q = kwargs.get('q', [.05, .95])
ret.append(np.percentile(tmp,q=q*100))
return ret
def forecastAhead(self, data, steps, **kwargs):
pass
def forecastAheadInterval(self, data, steps, **kwargs):
pass
def getGridClean(self, resolution):
grid = {}
if len(self.transformations) == 0:
_min = self.sets[0].lower
_max = self.sets[-1].upper
else:
_min = self.original_min
_max = self.original_max
for sbin in np.arange(_min,_max, resolution):
grid[sbin] = 0
return grid
def gridCount(self, grid, resolution, index, interval):
#print(point_to_interval)
for k in index.inside(interval[0],interval[1]):
#print(k)
grid[k] += 1
return grid
def gridCountPoint(self, grid, resolution, index, point):
k = index.find_ge(point)
# print(k)
grid[k] += 1
return grid
def forecastAheadDistribution(self, data, steps, **kwargs):
pass