2017-05-07 18:41:31 +04:00
|
|
|
|
"""
|
|
|
|
|
First Order Traditional Fuzzy Time Series method by Song & Chissom (1993)
|
|
|
|
|
|
|
|
|
|
Q. Song and B. S. Chissom, “Fuzzy time series and its models,” Fuzzy Sets Syst., vol. 54, no. 3, pp. 269–277, 1993.
|
|
|
|
|
"""
|
|
|
|
|
|
2017-05-07 00:04:37 +04:00
|
|
|
|
import numpy as np
|
|
|
|
|
from pyFTS.common import FuzzySet, FLR
|
|
|
|
|
from pyFTS import fts
|
|
|
|
|
|
2017-05-07 18:41:31 +04:00
|
|
|
|
|
2017-05-07 00:04:37 +04:00
|
|
|
|
class ConventionalFTS(fts.FTS):
|
2017-05-07 18:41:31 +04:00
|
|
|
|
"""Traditional Fuzzy Time Series"""
|
2017-05-07 00:04:37 +04:00
|
|
|
|
def __init__(self, name, **kwargs):
|
2017-05-07 04:19:04 +04:00
|
|
|
|
super(ConventionalFTS, self).__init__(1, "FTS " + name)
|
|
|
|
|
self.name = "Traditional FTS"
|
2017-05-07 00:04:37 +04:00
|
|
|
|
self.detail = "Song & Chissom"
|
|
|
|
|
self.R = None
|
|
|
|
|
|
|
|
|
|
def flr_membership_matrix(self, flr):
|
|
|
|
|
lm = [flr.LHS.membership(k.centroid) for k in self.sets]
|
|
|
|
|
rm = [flr.RHS.membership(k.centroid) for k in self.sets]
|
|
|
|
|
|
|
|
|
|
r = np.zeros((len(self.sets), len(self.sets)))
|
|
|
|
|
for k in range(0,len(self.sets)):
|
|
|
|
|
for l in range(0, len(self.sets)):
|
|
|
|
|
r[k][l] = min(lm[k],rm[l])
|
|
|
|
|
|
|
|
|
|
return r
|
|
|
|
|
|
|
|
|
|
def operation_matrix(self, flrs):
|
|
|
|
|
r = np.zeros((len(self.sets),len(self.sets)))
|
|
|
|
|
for k in flrs:
|
|
|
|
|
mm = self.flr_membership_matrix(k)
|
|
|
|
|
for k in range(0, len(self.sets)):
|
|
|
|
|
for l in range(0, len(self.sets)):
|
|
|
|
|
r[k][l] = max(r[k][l], mm[k][l])
|
|
|
|
|
|
|
|
|
|
return r
|
|
|
|
|
|
|
|
|
|
def train(self, data, sets,order=1,parameters=None):
|
|
|
|
|
self.sets = sets
|
|
|
|
|
ndata = self.doTransformations(data)
|
|
|
|
|
tmpdata = FuzzySet.fuzzySeries(ndata, sets)
|
|
|
|
|
flrs = FLR.generateNonRecurrentFLRs(tmpdata)
|
|
|
|
|
self.R = self.operation_matrix(flrs)
|
|
|
|
|
|
|
|
|
|
def forecast(self, data, **kwargs):
|
|
|
|
|
|
|
|
|
|
ndata = np.array(self.doTransformations(data))
|
|
|
|
|
|
|
|
|
|
l = len(ndata)
|
|
|
|
|
npart = len(self.sets)
|
|
|
|
|
|
|
|
|
|
ret = []
|
|
|
|
|
|
|
|
|
|
for k in np.arange(0, l):
|
|
|
|
|
mv = FuzzySet.fuzzyInstance(ndata[k], self.sets)
|
|
|
|
|
|
|
|
|
|
r = [max([ min(self.R[i][j], mv[j]) for j in np.arange(0,npart) ]) for i in np.arange(0,npart)]
|
|
|
|
|
|
|
|
|
|
fs = np.ravel(np.argwhere(r == max(r)))
|
|
|
|
|
|
|
|
|
|
if len(fs) == 1:
|
|
|
|
|
ret.append(self.sets[fs[0]].centroid)
|
|
|
|
|
else:
|
|
|
|
|
mp = [self.sets[s].centroid for s in fs]
|
|
|
|
|
|
|
|
|
|
ret.append( sum(mp)/len(mp))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ret = self.doInverseTransformations(ret, params=[data[self.order - 1:]])
|
|
|
|
|
|
|
|
|
|
return ret
|