diff --git a/benchmarks/benchmarks.py b/benchmarks/benchmarks.py index 49d8265..a37c80a 100644 --- a/benchmarks/benchmarks.py +++ b/benchmarks/benchmarks.py @@ -7,6 +7,7 @@ from mpl_toolkits.mplot3d import Axes3D from sklearn.cross_validation import KFold import Measures from pyFTS.partitioners import Grid +from pyFTS.common import Membership,FuzzySet,FLR,Transformations def Teste(par): x = np.arange(1,par) @@ -211,7 +212,7 @@ def SelecaoKFold_MenorRMSE(original,parameters,modelo): min_rmse_fold = 100000.0 bestd = None fc = 0 - diff = common.differential(original) + diff = Transformations.differential(original) kf = KFold(len(original), n_folds=nfolds) for train_ix, test_ix in kf: train = diff[train_ix] @@ -299,7 +300,7 @@ def SelecaoSimples_MenorRMSE(original,parameters,modelo): ret.append(forecasted_best) # Modelo diferencial print("\nSérie Diferencial") - difffts = common.differential(original) + difffts = Transformations.differential(original) errors = [] forecastedd_best = [] ax2 = fig.add_axes([0, 0, 0.65, 0.45]) #left, bottom, width, height @@ -465,7 +466,7 @@ def HOSelecaoSimples_MenorRMSE(original,parameters,orders): for p in parameters: oc = 0 for o in orders: - sets = Grid.GridPartitionerTrimf(common.differential(original),p) + sets = Grid.GridPartitionerTrimf(Transformations.differential(original),p) fts = hwang.HighOrderFTS(o,"k = " + str(p)+ " w = " + str(o)) fts.train(original,sets) forecasted = [fts.forecastDiff(original, xx) for xx in range(o,len(original))] diff --git a/chen.py b/chen.py index 6af19b2..6b7877a 100644 --- a/chen.py +++ b/chen.py @@ -1,70 +1,69 @@ import numpy as np -from pyFTS import * +from pyFTS.common import FuzzySet, FLR +import fts + class ConventionalFLRG: - def __init__(self,LHS): - self.LHS = LHS - self.RHS = set() - - def append(self,c): - self.RHS.add(c) + def __init__(self, LHS): + self.LHS = LHS + self.RHS = set() - def __str__(self): - tmp = self.LHS.name + " -> " - tmp2 = "" - for c in sorted(self.RHS, key=lambda s: s.name): - if len(tmp2) > 0: - tmp2 = tmp2 + "," - tmp2 = tmp2 + c.name - return tmp + tmp2 + def append(self, c): + self.RHS.add(c) + + def __str__(self): + tmp = self.LHS.name + " -> " + tmp2 = "" + for c in sorted(self.RHS, key=lambda s: s.name): + if len(tmp2) > 0: + tmp2 = tmp2 + "," + tmp2 = tmp2 + c.name + return tmp + tmp2 class ConventionalFTS(fts.FTS): - def __init__(self,name): - super(ConventionalFTS, self).__init__(1,"CFTS") - self.name = "Conventional FTS" - self.detail = "Chen" - self.flrgs = {} - - def generateFLRG(self, flrs): - flrgs = {} - for flr in flrs: - if flr.LHS.name in flrgs: - flrgs[flr.LHS.name].append(flr.RHS) - else: - flrgs[flr.LHS.name] = ConventionalFLRG(flr.LHS); - flrgs[flr.LHS.name].append(flr.RHS) - return (flrgs) + def __init__(self, name): + super(ConventionalFTS, self).__init__(1, "CFTS") + self.name = "Conventional FTS" + self.detail = "Chen" + self.flrgs = {} - def train(self, data, sets): - self.sets = sets - tmpdata = common.fuzzySeries(data,sets) - flrs = common.generateNonRecurrentFLRs(tmpdata) - self.flrgs = self.generateFLRG(flrs) - - def forecast(self,data): - - ndata = np.array(data) - - l = len(ndata) - - ret = [] - - for k in np.arange(0,l): - - mv = common.fuzzyInstance(ndata[k], self.sets) - - actual = self.sets[ np.argwhere( mv == max(mv) )[0,0] ] - - if actual.name not in self.flrgs: - ret.append(actual.centroid) - else: - flrg = self.flrgs[actual.name] - mp = self.getMidpoints(flrg) - - ret.append(sum(mp)/len(mp)) - - return ret - - - + def generateFLRG(self, flrs): + flrgs = {} + for flr in flrs: + if flr.LHS.name in flrgs: + flrgs[flr.LHS.name].append(flr.RHS) + else: + flrgs[flr.LHS.name] = ConventionalFLRG(flr.LHS); + flrgs[flr.LHS.name].append(flr.RHS) + return (flrgs) + + def train(self, data, sets): + self.sets = sets + tmpdata = FuzzySet.fuzzySeries(data, sets) + flrs = FLR.generateNonRecurrentFLRs(tmpdata) + self.flrgs = self.generateFLRG(flrs) + + def forecast(self, data): + + ndata = np.array(data) + + l = len(ndata) + + ret = [] + + for k in np.arange(0, l): + + mv = FuzzySet.fuzzyInstance(ndata[k], self.sets) + + actual = self.sets[np.argwhere(mv == max(mv))[0, 0]] + + if actual.name not in self.flrgs: + ret.append(actual.centroid) + else: + flrg = self.flrgs[actual.name] + mp = self.getMidpoints(flrg) + + ret.append(sum(mp) / len(mp)) + + return ret diff --git a/fts.py b/fts.py index e1cb1ff..877add9 100644 --- a/fts.py +++ b/fts.py @@ -1,41 +1,42 @@ import numpy as np from pyFTS import * + class FTS: - def __init__(self,order,name): - self.sets = {} - self.flrgs = {} - self.order = order - self.shortname = name - self.name = name - self.detail = name - self.isSeasonal = False - self.isInterval = False - self.isDensity = False - - def fuzzy(self,data): - best = {"fuzzyset":"", "membership":0.0} + def __init__(self, order, name): + self.sets = {} + self.flrgs = {} + self.order = order + self.shortname = name + self.name = name + self.detail = name + self.isSeasonal = False + self.isInterval = False + self.isDensity = False - for f in self.sets: - fset = self.sets[f] - if best["membership"] <= fset.membership(data): - best["fuzzyset"] = fset.name - best["membership"] = fset.membership(data) + def fuzzy(self, data): + best = {"fuzzyset": "", "membership": 0.0} - return best + for f in self.sets: + fset = self.sets[f] + if best["membership"] <= fset.membership(data): + best["fuzzyset"] = fset.name + best["membership"] = fset.membership(data) - def forecast(self,data): - pass + return best - def train(self, data, sets): - pass - - def getMidpoints(self,flrg): - ret = np.array([s.centroid for s in flrg.RHS]) - return ret + def forecast(self, data): + pass - def __str__(self): - tmp = self.name + ":\n" - for r in sorted(self.flrgs): - tmp = tmp + str(self.flrgs[r]) + "\n" - return tmp + def train(self, data, sets): + pass + + def getMidpoints(self, flrg): + ret = np.array([s.centroid for s in flrg.RHS]) + return ret + + def __str__(self): + tmp = self.name + ":\n" + for r in sorted(self.flrgs): + tmp = tmp + str(self.flrgs[r]) + "\n" + return tmp diff --git a/hofts.py b/hofts.py index 0d059c8..b3db5d5 100644 --- a/hofts.py +++ b/hofts.py @@ -1,94 +1,96 @@ import numpy as np -from pyFTS import * +from pyFTS.common import FuzzySet,FLR +import fts + class HighOrderFLRG: - def __init__(self,order): - self.LHS = [] - self.RHS = {} - self.order = order - self.strlhs = "" + def __init__(self, order): + self.LHS = [] + self.RHS = {} + self.order = order + self.strlhs = "" + + def appendRHS(self, c): + if c.name not in self.RHS: + self.RHS[c.name] = c + + def strLHS(self): + if len(self.strlhs) == 0: + for c in self.LHS: + if len(self.strlhs) > 0: + self.strlhs = self.strlhs + ", " + self.strlhs = self.strlhs + c.name + return self.strlhs + + def appendLHS(self, c): + self.LHS.append(c) + + def __str__(self): + tmp = "" + for c in sorted(self.RHS): + if len(tmp) > 0: + tmp = tmp + "," + tmp = tmp + c + return self.strLHS() + " -> " + tmp - def appendRHS(self,c): - if c.name not in self.RHS: - self.RHS[c.name] = c - - def strLHS(self): - if len(self.strlhs) == 0: - for c in self.LHS: - if len(self.strlhs) > 0: - self.strlhs = self.strlhs + ", " - self.strlhs = self.strlhs + c.name - return self.strlhs - - def appendLHS(self,c): - self.LHS.append(c) - def __str__(self): - tmp = "" - for c in sorted(self.RHS): - if len(tmp) > 0: - tmp = tmp + "," - tmp = tmp + c - return self.strLHS() + " -> " + tmp - class HighOrderFTS(fts.FTS): - def __init__(self,name): - super(HighOrderFTS, self).__init__(1,"HOFTS" + name) - self.name = "High Order FTS" - self.detail = "Chen" - self.order = 1 - self.setsDict = {} - - def generateFLRG(self, flrs): - flrgs = {} - l = len(flrs) - for k in np.arange(self.order +1, l): - flrg = HighOrderFLRG(self.order) - - for kk in np.arange(k - self.order, k): - flrg.appendLHS( flrs[kk].LHS ) - - if flrg.strLHS() in flrgs: - flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) - else: - flrgs[flrg.strLHS()] = flrg; - flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) - return (flrgs) + def __init__(self, name): + super(HighOrderFTS, self).__init__(1, "HOFTS" + name) + self.name = "High Order FTS" + self.detail = "Chen" + self.order = 1 + self.setsDict = {} - def train(self, data, sets, order): - self.order = order - self.sets = sets - for s in self.sets: self.setsDict[s.name] = s - tmpdata = common.fuzzySeries(data,sets) - flrs = common.generateRecurrentFLRs(tmpdata) - self.flrgs = self.generateFLRG(flrs) - - def getMidpoints(self,flrg): - ret = np.array([self.setsDict[s].centroid for s in flrg.RHS]) - return ret - - def forecast(self,data): - - ret = [] - - l = len(data) - - if l <= self.order: - return data - - for k in np.arange(self.order, l): - tmpdata = common.fuzzySeries(data[k-self.order : k],self.sets) - tmpflrg = HighOrderFLRG(self.order) - - for s in tmpdata: tmpflrg.appendLHS(s) - - if tmpflrg.strLHS() not in self.flrgs: - ret.append(tmpdata[-1].centroid) - else: - flrg = self.flrgs[tmpflrg.strLHS()] - mp = self.getMidpoints(flrg) - - ret.append(sum(mp)/len(mp)) - - return ret - + def generateFLRG(self, flrs): + flrgs = {} + l = len(flrs) + for k in np.arange(self.order + 1, l): + flrg = HighOrderFLRG(self.order) + + for kk in np.arange(k - self.order, k): + flrg.appendLHS(flrs[kk].LHS) + + if flrg.strLHS() in flrgs: + flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) + else: + flrgs[flrg.strLHS()] = flrg; + flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) + return (flrgs) + + def train(self, data, sets, order): + self.order = order + self.sets = sets + for s in self.sets: self.setsDict[s.name] = s + tmpdata = FuzzySet.fuzzySeries(data, sets) + flrs = FuzzySet.generateRecurrentFLRs(tmpdata) + self.flrgs = self.generateFLRG(flrs) + + def getMidpoints(self, flrg): + ret = np.array([self.setsDict[s].centroid for s in flrg.RHS]) + return ret + + def forecast(self, data): + + ret = [] + + l = len(data) + + if l <= self.order: + return data + + for k in np.arange(self.order, l): + tmpdata = FuzzySet.fuzzySeries(data[k - self.order: k], self.sets) + tmpflrg = HighOrderFLRG(self.order) + + for s in tmpdata: tmpflrg.appendLHS(s) + + if tmpflrg.strLHS() not in self.flrgs: + ret.append(tmpdata[-1].centroid) + else: + flrg = self.flrgs[tmpflrg.strLHS()] + mp = self.getMidpoints(flrg) + + ret.append(sum(mp) / len(mp)) + + return ret diff --git a/hwang.py b/hwang.py index 42dcfea..81e660b 100644 --- a/hwang.py +++ b/hwang.py @@ -1,37 +1,38 @@ import numpy as np -from pyFTS import * +from pyFTS.common import FuzzySet,FLR,Transformations +import fts + class HighOrderFTS(fts.FTS): - def __init__(self,order,name): - super(HighOrderFTS, self).__init__(order,name) - - def forecast(self,data,t): - cn = np.array([0.0 for k in range(len(self.sets))]) - ow = np.array([[0.0 for k in range(len(self.sets))] for z in range(self.order-1)]) - rn = np.array([[0.0 for k in range(len(self.sets))] for z in range(self.order-1)]) - ft = np.array([0.0 for k in range(len(self.sets))]) + def __init__(self, order, name): + super(HighOrderFTS, self).__init__(order, name) - for s in range(len(self.sets)): - cn[s] = self.sets[s].membership(data[t]) - for w in range(self.order-1): - ow[w,s] = self.sets[s].membership(data[t-w]) - rn[w,s] = ow[w,s] * cn[s] - ft[s] = max(ft[s],rn[w,s]) - mft = max(ft) - out = 0.0 - count = 0.0 - for s in range(len(self.sets)): - if ft[s] == mft: - out = out + self.sets[s].centroid - count = count + 1.0 - return out / count + def forecast(self, data, t): + cn = np.array([0.0 for k in range(len(self.sets))]) + ow = np.array([[0.0 for k in range(len(self.sets))] for z in range(self.order - 1)]) + rn = np.array([[0.0 for k in range(len(self.sets))] for z in range(self.order - 1)]) + ft = np.array([0.0 for k in range(len(self.sets))]) + for s in range(len(self.sets)): + cn[s] = self.sets[s].membership(data[t]) + for w in range(self.order - 1): + ow[w, s] = self.sets[s].membership(data[t - w]) + rn[w, s] = ow[w, s] * cn[s] + ft[s] = max(ft[s], rn[w, s]) + mft = max(ft) + out = 0.0 + count = 0.0 + for s in range(len(self.sets)): + if ft[s] == mft: + out = out + self.sets[s].centroid + count = count + 1.0 + return out / count - def train(self, data, sets): - self.sets = sets - - def predict(self,data,t): - return self.forecast(data,t) + def train(self, data, sets): + self.sets = sets - def predictDiff(self,data,t): - return data[t] + self.forecast(common.differential(data),t) + def predict(self, data, t): + return self.forecast(data, t) + + def predictDiff(self, data, t): + return data[t] + self.forecast(Transformations.differential(data), t) diff --git a/ifts.py b/ifts.py index ca90e4b..0bd7dfe 100644 --- a/ifts.py +++ b/ifts.py @@ -1,111 +1,113 @@ import numpy as np -from pyFTS import * +from pyFTS.common import FuzzySet,FLR +import hofts, fts, tree + class IntervalFTS(hofts.HighOrderFTS): - def __init__(self,name): - super(IntervalFTS, self).__init__("IFTS " + name) - self.shortname = "IFTS " + name - self.name = "Interval FTS" - self.detail = "Silva, P.; Guimarães, F.; Sadaei, H." - self.flrgs = {} - self.isInterval = True - - def getUpper(self,flrg): - if flrg.strLHS() in self.flrgs: - tmp = self.flrgs[ flrg.strLHS() ] - ret = max(np.array([self.setsDict[s].upper for s in tmp.RHS])) - else: - ret = flrg.LHS[-1].upper - return ret - - def getLower(self,flrg): - if flrg.strLHS() in self.flrgs: - tmp = self.flrgs[ flrg.strLHS() ] - ret = min(np.array([self.setsDict[s].lower for s in tmp.RHS])) - else: - ret = flrg.LHS[-1].lower - return ret - - def getSequenceMembership(self, data, fuzzySets): - mb = [ fuzzySets[k].membership( data[k] ) for k in np.arange(0,len(data)) ] - return mb - - def buildTree(self,node, lags, level): - if level >= self.order: - return - - for s in lags[level]: - node.appendChild(tree.FLRGTreeNode(s)) - - for child in node.getChildren(): - self.buildTree(child,lags,level+1) - - def forecast(self,data): - - ndata = np.array(data) - - l = len(ndata) - - ret = [] - - for k in np.arange(self.order-1,l): - - affected_flrgs = [] - affected_flrgs_memberships = [] - - up = [] - lo = [] - - # Achar os conjuntos que tem pert > 0 para cada lag - count = 0 - lags = {} - if self.order > 1: - subset = ndata[k-(self.order-1) : k+1 ] - - for instance in subset: - mb = common.fuzzyInstance(instance, self.sets) - tmp = np.argwhere( mb ) - idx = np.ravel(tmp) #flat the array - lags[count] = idx - count = count + 1 - - # Constrói uma árvore com todos os caminhos possíveis - - root = tree.FLRGTreeNode(None) - - self.buildTree(root,lags,0) - - # Traça os possíveis caminhos e costrói as HOFLRG's - - for p in root.paths(): - path = list(reversed(list(filter(None.__ne__, p)))) - flrg = hofts.HighOrderFLRG(self.order) - for kk in path: flrg.appendLHS(self.sets[ kk ]) - - affected_flrgs.append(flrg) - - # Acha a pertinência geral de cada FLRG - affected_flrgs_memberships.append(min(self.getSequenceMembership(subset, flrg.LHS))) - else: - - mv = common.fuzzyInstance(ndata[k],self.sets) - tmp = np.argwhere( mv ) - idx = np.ravel(tmp) - for kk in idx: - flrg = hofts.HighOrderFLRG(self.order) - flrg.appendLHS(self.sets[ kk ]) - affected_flrgs.append(flrg) - affected_flrgs_memberships.append(mv[kk]) - - count = 0 - for flrg in affected_flrgs: - # achar o os bounds de cada FLRG, ponderados pela pertinência - up.append( affected_flrgs_memberships[count] * self.getUpper(flrg) ) - lo.append( affected_flrgs_memberships[count] * self.getLower(flrg) ) - count = count + 1 - - # gerar o intervalo - norm = sum(affected_flrgs_memberships) - ret.append( [ sum(lo)/norm, sum(up)/norm ] ) - - return ret + def __init__(self, name): + super(IntervalFTS, self).__init__("IFTS " + name) + self.shortname = "IFTS " + name + self.name = "Interval FTS" + self.detail = "Silva, P.; Guimarães, F.; Sadaei, H. (2016)" + self.flrgs = {} + self.isInterval = True + + def getUpper(self, flrg): + if flrg.strLHS() in self.flrgs: + tmp = self.flrgs[flrg.strLHS()] + ret = max(np.array([self.setsDict[s].upper for s in tmp.RHS])) + else: + ret = flrg.LHS[-1].upper + return ret + + def getLower(self, flrg): + if flrg.strLHS() in self.flrgs: + tmp = self.flrgs[flrg.strLHS()] + ret = min(np.array([self.setsDict[s].lower for s in tmp.RHS])) + else: + ret = flrg.LHS[-1].lower + return ret + + def getSequenceMembership(self, data, fuzzySets): + mb = [fuzzySets[k].membership(data[k]) for k in np.arange(0, len(data))] + return mb + + def buildTree(self, node, lags, level): + if level >= self.order: + return + + for s in lags[level]: + node.appendChild(tree.FLRGTreeNode(s)) + + for child in node.getChildren(): + self.buildTree(child, lags, level + 1) + + def forecast(self, data): + + ndata = np.array(data) + + l = len(ndata) + + ret = [] + + for k in np.arange(self.order - 1, l): + + affected_flrgs = [] + affected_flrgs_memberships = [] + + up = [] + lo = [] + + # Achar os conjuntos que tem pert > 0 para cada lag + count = 0 + lags = {} + if self.order > 1: + subset = ndata[k - (self.order - 1): k + 1] + + for instance in subset: + mb = FuzzySet.fuzzyInstance(instance, self.sets) + tmp = np.argwhere(mb) + idx = np.ravel(tmp) # flat the array + lags[count] = idx + count = count + 1 + + # Constrói uma árvore com todos os caminhos possíveis + + root = tree.FLRGTreeNode(None) + + self.buildTree(root, lags, 0) + + # Traça os possíveis caminhos e costrói as HOFLRG's + + for p in root.paths(): + path = list(reversed(list(filter(None.__ne__, p)))) + flrg = hofts.HighOrderFLRG(self.order) + for kk in path: flrg.appendLHS(self.sets[kk]) + + affected_flrgs.append(flrg) + + # Acha a pertinência geral de cada FLRG + affected_flrgs_memberships.append(min(self.getSequenceMembership(subset, flrg.LHS))) + else: + + mv = FuzzySet.fuzzyInstance(ndata[k], self.sets) + tmp = np.argwhere(mv) + idx = np.ravel(tmp) + for kk in idx: + flrg = hofts.HighOrderFLRG(self.order) + flrg.appendLHS(self.sets[kk]) + affected_flrgs.append(flrg) + affected_flrgs_memberships.append(mv[kk]) + + count = 0 + for flrg in affected_flrgs: + # achar o os bounds de cada FLRG, ponderados pela pertinência + up.append(affected_flrgs_memberships[count] * self.getUpper(flrg)) + lo.append(affected_flrgs_memberships[count] * self.getLower(flrg)) + count = count + 1 + + # gerar o intervalo + norm = sum(affected_flrgs_memberships) + ret.append([sum(lo) / norm, sum(up) / norm]) + + return ret diff --git a/ismailefendi.py b/ismailefendi.py index 594cd7b..01ebb60 100644 --- a/ismailefendi.py +++ b/ismailefendi.py @@ -1,83 +1,85 @@ import numpy as np -from pyFTS import * +from pyFTS.common import FuzzySet,FLR +import fts + class ImprovedWeightedFLRG: - def __init__(self,LHS): - self.LHS = LHS - self.RHS = {} - self.count = 0.0 + def __init__(self, LHS): + self.LHS = LHS + self.RHS = {} + self.count = 0.0 - def append(self,c): - if c.name not in self.RHS: - self.RHS[c.name] = 1.0 - else: - self.RHS[c.name] = self.RHS[c.name] + 1.0 - self.count = self.count + 1.0 + def append(self, c): + if c.name not in self.RHS: + self.RHS[c.name] = 1.0 + else: + self.RHS[c.name] = self.RHS[c.name] + 1.0 + self.count = self.count + 1.0 + + def weights(self): + return np.array([self.RHS[c] / self.count for c in self.RHS.keys()]) + + def __str__(self): + tmp = self.LHS.name + " -> " + tmp2 = "" + for c in sorted(self.RHS): + if len(tmp2) > 0: + tmp2 = tmp2 + "," + tmp2 = tmp2 + c + "(" + str(round(self.RHS[c] / self.count, 3)) + ")" + return tmp + tmp2 - def weights(self): - return np.array([ self.RHS[c]/self.count for c in self.RHS.keys() ]) - - def __str__(self): - tmp = self.LHS.name + " -> " - tmp2 = "" - for c in sorted(self.RHS): - if len(tmp2) > 0: - tmp2 = tmp2 + "," - tmp2 = tmp2 + c + "(" + str(round(self.RHS[c]/self.count,3)) + ")" - return tmp + tmp2 - class ImprovedWeightedFTS(fts.FTS): - def __init__(self,name): - super(ImprovedWeightedFTS, self).__init__(1,"IWFTS") - self.name = "Improved Weighted FTS" - self.detail = "Ismail & Efendi" - self.setsDict = {} - - def generateFLRG(self, flrs): - flrgs = {} - for flr in flrs: - if flr.LHS.name in flrgs: - flrgs[flr.LHS.name].append(flr.RHS) - else: - flrgs[flr.LHS.name] = ImprovedWeightedFLRG(flr.LHS); - flrgs[flr.LHS.name].append(flr.RHS) - return (flrgs) + def __init__(self, name): + super(ImprovedWeightedFTS, self).__init__(1, "IWFTS") + self.name = "Improved Weighted FTS" + self.detail = "Ismail & Efendi" + self.setsDict = {} - def train(self, data, sets): - self.sets = sets - - for s in self.sets: self.setsDict[s.name] = s - - tmpdata = common.fuzzySeries(data,self.sets) - flrs = common.generateRecurrentFLRs(tmpdata) - self.flrgs = self.generateFLRG(flrs) - - def getMidpoints(self,flrg): - ret = np.array([self.setsDict[s].centroid for s in flrg.RHS]) - return ret - - def forecast(self,data): - l = 1 - - ndata = np.array(data) - - l = len(ndata) - - ret = [] - - for k in np.arange(0,l): - - mv = common.fuzzyInstance(ndata[k], self.sets) - - actual = self.sets[ np.argwhere( mv == max(mv) )[0,0] ] - - if actual.name not in self.flrgs: - ret.append(actual.centroid) - else: - flrg = self.flrgs[actual.name] - mp = self.getMidpoints(flrg) - - ret.append( mp.dot( flrg.weights() )) - - return ret + def generateFLRG(self, flrs): + flrgs = {} + for flr in flrs: + if flr.LHS.name in flrgs: + flrgs[flr.LHS.name].append(flr.RHS) + else: + flrgs[flr.LHS.name] = ImprovedWeightedFLRG(flr.LHS); + flrgs[flr.LHS.name].append(flr.RHS) + return (flrgs) + + def train(self, data, sets): + self.sets = sets + + for s in self.sets: self.setsDict[s.name] = s + + tmpdata = FuzzySet.fuzzySeries(data, self.sets) + flrs = FLR.generateRecurrentFLRs(tmpdata) + self.flrgs = self.generateFLRG(flrs) + + def getMidpoints(self, flrg): + ret = np.array([self.setsDict[s].centroid for s in flrg.RHS]) + return ret + + def forecast(self, data): + l = 1 + + ndata = np.array(data) + + l = len(ndata) + + ret = [] + + for k in np.arange(0, l): + + mv = FuzzySet.fuzzyInstance(ndata[k], self.sets) + + actual = self.sets[np.argwhere(mv == max(mv))[0, 0]] + + if actual.name not in self.flrgs: + ret.append(actual.centroid) + else: + flrg = self.flrgs[actual.name] + mp = self.getMidpoints(flrg) + + ret.append(mp.dot(flrg.weights())) + + return ret diff --git a/partitioners/CMeans.py b/partitioners/CMeans.py index 94aec96..59e98f6 100644 --- a/partitioners/CMeans.py +++ b/partitioners/CMeans.py @@ -2,7 +2,7 @@ import numpy as np import math import random as rnd import functools,operator -from pyFTS import * +from pyFTS.common import FuzzySet,Membership def distancia(x,y): if isinstance(x, list): @@ -86,6 +86,6 @@ def CMeansPartitionerTrimf(data,npart,names = None,prefix = "A"): centroides = list(set(centroides)) centroides.sort() for c in np.arange(1,len(centroides)-1): - sets.append(common.FuzzySet(prefix+str(c),common.trimf,[round(centroides[c-1],3), round(centroides[c],3), round(centroides[c+1],3)], round(centroides[c],3) ) ) + sets.append(FuzzySet(prefix+str(c),Membership.trimf,[round(centroides[c-1],3), round(centroides[c],3), round(centroides[c+1],3)], round(centroides[c],3) ) ) return sets diff --git a/partitioners/FCM.py b/partitioners/FCM.py index 1f98551..a13a338 100644 --- a/partitioners/FCM.py +++ b/partitioners/FCM.py @@ -2,7 +2,7 @@ import numpy as np import math import random as rnd import functools,operator -from pyFTS import * +from pyFTS.common import FuzzySet,Membership #import CMeans @@ -108,6 +108,6 @@ def FCMPartitionerTrimf(data,npart,names = None,prefix = "A"): centroides = list(set(centroides)) centroides.sort() for c in np.arange(1,len(centroides)-1): - sets.append(common.FuzzySet(prefix+str(c),common.trimf,[round(centroides[c-1],3), round(centroides[c],3), round(centroides[c+1],3)], round(centroides[c],3) ) ) + sets.append(FuzzySet(prefix+str(c),Membership.trimf,[round(centroides[c-1],3), round(centroides[c],3), round(centroides[c+1],3)], round(centroides[c],3) ) ) return sets \ No newline at end of file diff --git a/partitioners/Grid.py b/partitioners/Grid.py index 4e4db27..7830b42 100644 --- a/partitioners/Grid.py +++ b/partitioners/Grid.py @@ -2,7 +2,7 @@ import numpy as np import math import random as rnd import functools,operator -from pyFTS import * +from pyFTS.common import FuzzySet,Membership #print(common.__dict__) @@ -16,7 +16,7 @@ def GridPartitionerTrimf(data,npart,names = None,prefix = "A"): partlen = math.ceil(dlen / npart) partition = math.ceil(dmin) for c in range(npart): - sets.append(common.FuzzySet(prefix+str(c),common.trimf,[round(partition-partlen,3), partition, partition+partlen], partition ) ) + sets.append(FuzzySet(prefix+str(c),Membership.trimf,[round(partition-partlen,3), partition, partition+partlen], partition ) ) partition = partition + partlen return sets diff --git a/pifts.py b/pifts.py index d137f66..e57894b 100644 --- a/pifts.py +++ b/pifts.py @@ -1,291 +1,297 @@ import numpy as np import pandas as pd import math -from pyFTS import * +from pyFTS.common import FuzzySet,FLR +import hofts, ifts, tree + class ProbabilisticFLRG(hofts.HighOrderFLRG): - def __init__(self,order): - super(ProbabilisticFLRG, self).__init__(order) - self.RHS = {} - self.frequencyCount = 0 - - def appendRHS(self,c): - self.frequencyCount = self.frequencyCount + 1 - if c.name in self.RHS: - self.RHS[c.name] = self.RHS[c.name] + 1 - else: - self.RHS[c.name] = 1 - - def getProbability(self,c): - return self.RHS[c] / self.frequencyCount - - def __str__(self): - tmp2 = "" - for c in sorted(self.RHS): - if len(tmp2) > 0: - tmp2 = tmp2 + ", " - tmp2 = tmp2 + c + "(" + str(round(self.RHS[c]/self.frequencyCount,3)) + ")" - return self.strLHS() + " -> " + tmp2 + def __init__(self, order): + super(ProbabilisticFLRG, self).__init__(order) + self.RHS = {} + self.frequencyCount = 0 + + def appendRHS(self, c): + self.frequencyCount = self.frequencyCount + 1 + if c.name in self.RHS: + self.RHS[c.name] = self.RHS[c.name] + 1 + else: + self.RHS[c.name] = 1 + + def getProbability(self, c): + return self.RHS[c] / self.frequencyCount + + def __str__(self): + tmp2 = "" + for c in sorted(self.RHS): + if len(tmp2) > 0: + tmp2 = tmp2 + ", " + tmp2 = tmp2 + c + "(" + str(round(self.RHS[c] / self.frequencyCount, 3)) + ")" + return self.strLHS() + " -> " + tmp2 + class ProbabilisticIntervalFTS(ifts.IntervalFTS): - def __init__(self,name): - super(ProbabilisticIntervalFTS, self).__init__("PIFTS") - self.shortname = "PIFTS " + name - self.name = "Probabilistic Interval FTS" - self.detail = "Silva, P.; Guimarães, F.; Sadaei, H." - self.flrgs = {} - self.globalFrequency = 0 - self.isInterval = True - self.isDensity = True - - def generateFLRG(self, flrs): - flrgs = {} - l = len(flrs) - for k in np.arange(self.order +1, l): - flrg = ProbabilisticFLRG(self.order) - - for kk in np.arange(k - self.order, k): - flrg.appendLHS( flrs[kk].LHS ) - - if flrg.strLHS() in flrgs: - flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) - else: - flrgs[flrg.strLHS()] = flrg; - flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) - - self.globalFrequency = self.globalFrequency + 1 - return (flrgs) - - def getProbability(self, flrg): - if flrg.strLHS() in self.flrgs: - return self.flrgs[ flrg.strLHS() ].frequencyCount / self.globalFrequency - else: - return 1.0 / self.globalFrequency - - def getUpper(self,flrg): - if flrg.strLHS() in self.flrgs: - tmp = self.flrgs[ flrg.strLHS() ] - ret = sum(np.array([ tmp.getProbability(s) * self.setsDict[s].upper for s in tmp.RHS])) - else: - ret = sum(np.array([ 0.33 * s.upper for s in flrg.LHS])) - return ret - - def getLower(self,flrg): - if flrg.strLHS() in self.flrgs: - tmp = self.flrgs[ flrg.strLHS() ] - ret = sum(np.array([ tmp.getProbability(s) * self.setsDict[s].lower for s in tmp.RHS])) - else: - ret = sum(np.array([ 0.33 * s.lower for s in flrg.LHS])) - return ret - - def forecast(self,data): - - ndata = np.array(data) + def __init__(self, name): + super(ProbabilisticIntervalFTS, self).__init__("PIFTS") + self.shortname = "PIFTS " + name + self.name = "Probabilistic Interval FTS" + self.detail = "Silva, P.; Guimarães, F.; Sadaei, H." + self.flrgs = {} + self.globalFrequency = 0 + self.isInterval = True + self.isDensity = True - l = len(ndata) - - ret = [] - - for k in np.arange(self.order-1,l): - - #print(k) - - affected_flrgs = [] - affected_flrgs_memberships = [] - norms = [] - - up = [] - lo = [] - - # Find the sets which membership > 0 for each lag - count = 0 - lags = {} - if self.order > 1: - subset = ndata[k-(self.order-1) : k+1 ] - - for instance in subset: - mb = common.fuzzyInstance(instance, self.sets) - tmp = np.argwhere( mb ) - idx = np.ravel(tmp) #flatten the array - - if idx.size == 0: # the element is out of the bounds of the Universe of Discourse - if math.ceil(instance) <= self.sets[0].lower: - idx = [0] - elif math.ceil(instance) >= self.sets[-1].upper: - idx = [len(self.sets)-1] - else: - raise Exception( instance ) + def generateFLRG(self, flrs): + flrgs = {} + l = len(flrs) + for k in np.arange(self.order + 1, l): + flrg = ProbabilisticFLRG(self.order) - lags[count] = idx - count = count + 1 - - # Build the tree with all possible paths - - root = tree.FLRGTreeNode(None) - - self.buildTree(root,lags,0) - - # Trace the possible paths and build the PFLRG's - - for p in root.paths(): - path = list(reversed(list(filter(None.__ne__, p)))) - flrg = hofts.HighOrderFLRG(self.order) - for kk in path: flrg.appendLHS(self.sets[ kk ]) - - assert len(flrg.LHS) == subset.size, str(subset) + " -> " + str([s.name for s in flrg.LHS]) - - ## - affected_flrgs.append( flrg ) - - # Find the general membership of FLRG - affected_flrgs_memberships.append(min(self.getSequenceMembership(subset, flrg.LHS))) + for kk in np.arange(k - self.order, k): + flrg.appendLHS(flrs[kk].LHS) - else: - - mv = common.fuzzyInstance(ndata[k],self.sets) # get all membership values - tmp = np.argwhere( mv ) # get the indices of values > 0 - idx = np.ravel(tmp) # flatten the array - - if idx.size == 0: # the element is out of the bounds of the Universe of Discourse - if math.ceil(ndata[k]) <= self.sets[0].lower: - idx = [0] - elif math.ceil(ndata[k]) >= self.sets[-1].upper: - idx = [len(self.sets)-1] - else: - raise Exception( ndata[k] ) + if flrg.strLHS() in flrgs: + flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) + else: + flrgs[flrg.strLHS()] = flrg; + flrgs[flrg.strLHS()].appendRHS(flrs[k].RHS) - for kk in idx: - flrg = hofts.HighOrderFLRG(self.order) - flrg.appendLHS(self.sets[ kk ]) - affected_flrgs.append( flrg ) - affected_flrgs_memberships.append(mv[kk]) - - count = 0 - for flrg in affected_flrgs: - # achar o os bounds de cada FLRG, ponderados pela probabilidade e pertinência - norm = self.getProbability(flrg) * affected_flrgs_memberships[count] - if norm == 0: - norm = self.getProbability(flrg) # * 0.001 - up.append( norm * self.getUpper(flrg) ) - lo.append( norm * self.getLower(flrg) ) - norms.append(norm) - count = count + 1 - - # gerar o intervalo - norm = sum(norms) - if norm == 0: - ret.append( [ 0, 0 ] ) - else: - ret.append( [ sum(lo)/norm, sum(up)/norm ] ) - - return ret - - def forecastAhead(self,data,steps): - ret = [[data[k],data[k]] for k in np.arange(len(data)-self.order,len(data))] + self.globalFrequency = self.globalFrequency + 1 + return (flrgs) - for k in np.arange(self.order-1,steps): - - if ret[-1][0] <= self.sets[0].lower and ret[-1][1] >= self.sets[-1].upper: - ret.append(ret[-1]) - else: - lower = self.forecast( [ret[x][0] for x in np.arange(k-self.order,k)] ) - upper = self.forecast( [ret[x][1] for x in np.arange(k-self.order,k)] ) - - ret.append([np.min(lower),np.max(upper)]) - - return ret - - def getGridClean(self,resolution): - grid = {} - for sbin in np.arange(self.sets[0].lower,self.sets[-1].upper,resolution): - grid[sbin] = 0 - - return grid - - def gridCount(self, grid, resolution, interval): - for sbin in sorted(grid): - if sbin >= interval[0] and (sbin + resolution) <= interval[1]: - grid[sbin] = grid[sbin] + 1 - return grid - - def forecastDistributionAhead2(self,data,steps,resolution): - - ret = [] - - intervals = self.forecastAhead(data,steps) - - for k in np.arange(self.order,steps): - - grid = self.getGridClean(resolution) - grid = self.gridCount(grid,resolution, intervals[k]) - - lags = {} - - cc = 0 - for x in np.arange(k-self.order,k): - tmp = [] - for qt in np.arange(0,100,5): - tmp.append(intervals[x][0] + qt*(intervals[x][1]-intervals[x][0])/100) - tmp.append(intervals[x][1] - qt*(intervals[x][1]-intervals[x][0])/100) - tmp.append(intervals[x][0] + (intervals[x][1]-intervals[x][0])/2) - - lags[cc] = tmp - - cc = cc + 1 - # Build the tree with all possible paths - - root = tree.FLRGTreeNode(None) - - self.buildTree(root,lags,0) - - # Trace the possible paths and build the PFLRG's - - for p in root.paths(): - path = list(reversed(list(filter(None.__ne__, p)))) - - subset = [kk for kk in path] - - qtle = self.forecast(subset) - grid = self.gridCount(grid,resolution, np.ravel(qtle)) - - tmp = np.array([ grid[k] for k in sorted(grid) ]) - ret.append( tmp/sum(tmp) ) - - grid = self.getGridClean(resolution) - df = pd.DataFrame(ret, columns=sorted(grid)) - return df - - def forecastDistributionAhead(self,data,steps,resolution): - - ret = [] - - intervals = self.forecastAhead(data,steps) - - for k in np.arange(self.order,steps): - - grid = self.getGridClean(resolution) - grid = self.gridCount(grid,resolution, intervals[k]) - - for qt in np.arange(1,50,2): - #print(qt) - qtle_lower = self.forecast([intervals[x][0] + qt*(intervals[x][1]-intervals[x][0])/100 for x in np.arange(k-self.order,k)] ) - grid = self.gridCount(grid,resolution, np.ravel(qtle_lower)) - qtle_upper = self.forecast([intervals[x][1] - qt*(intervals[x][1]-intervals[x][0])/100 for x in np.arange(k-self.order,k)] ) - grid = self.gridCount(grid,resolution, np.ravel(qtle_upper)) - qtle_mid = self.forecast([intervals[x][0] + (intervals[x][1]-intervals[x][0])/2 for x in np.arange(k-self.order,k)] ) - grid = self.gridCount(grid,resolution, np.ravel(qtle_mid)) - - tmp = np.array([ grid[k] for k in sorted(grid) ]) - - ret.append( tmp/sum(tmp) ) - - grid = self.getGridClean(resolution) - df = pd.DataFrame(ret, columns=sorted(grid)) - return df - - def __str__(self): - tmp = self.name + ":\n" - for r in sorted(self.flrgs): - p = round(self.flrgs[r].frequencyCount / self.globalFrequency,3) - tmp = tmp + "(" + str(p) + ") " + str(self.flrgs[r]) + "\n" - return tmp + def getProbability(self, flrg): + if flrg.strLHS() in self.flrgs: + return self.flrgs[flrg.strLHS()].frequencyCount / self.globalFrequency + else: + return 1.0 / self.globalFrequency + + def getUpper(self, flrg): + if flrg.strLHS() in self.flrgs: + tmp = self.flrgs[flrg.strLHS()] + ret = sum(np.array([tmp.getProbability(s) * self.setsDict[s].upper for s in tmp.RHS])) + else: + ret = sum(np.array([0.33 * s.upper for s in flrg.LHS])) + return ret + + def getLower(self, flrg): + if flrg.strLHS() in self.flrgs: + tmp = self.flrgs[flrg.strLHS()] + ret = sum(np.array([tmp.getProbability(s) * self.setsDict[s].lower for s in tmp.RHS])) + else: + ret = sum(np.array([0.33 * s.lower for s in flrg.LHS])) + return ret + + def forecast(self, data): + + ndata = np.array(data) + + l = len(ndata) + + ret = [] + + for k in np.arange(self.order - 1, l): + + # print(k) + + affected_flrgs = [] + affected_flrgs_memberships = [] + norms = [] + + up = [] + lo = [] + + # Find the sets which membership > 0 for each lag + count = 0 + lags = {} + if self.order > 1: + subset = ndata[k - (self.order - 1): k + 1] + + for instance in subset: + mb = FuzzySet.fuzzyInstance(instance, self.sets) + tmp = np.argwhere(mb) + idx = np.ravel(tmp) # flatten the array + + if idx.size == 0: # the element is out of the bounds of the Universe of Discourse + if math.ceil(instance) <= self.sets[0].lower: + idx = [0] + elif math.ceil(instance) >= self.sets[-1].upper: + idx = [len(self.sets) - 1] + else: + raise Exception(instance) + + lags[count] = idx + count = count + 1 + + # Build the tree with all possible paths + + root = tree.FLRGTreeNode(None) + + self.buildTree(root, lags, 0) + + # Trace the possible paths and build the PFLRG's + + for p in root.paths(): + path = list(reversed(list(filter(None.__ne__, p)))) + flrg = hofts.HighOrderFLRG(self.order) + for kk in path: flrg.appendLHS(self.sets[kk]) + + assert len(flrg.LHS) == subset.size, str(subset) + " -> " + str([s.name for s in flrg.LHS]) + + ## + affected_flrgs.append(flrg) + + # Find the general membership of FLRG + affected_flrgs_memberships.append(min(self.getSequenceMembership(subset, flrg.LHS))) + + else: + + mv = FuzzySet.fuzzyInstance(ndata[k], self.sets) # get all membership values + tmp = np.argwhere(mv) # get the indices of values > 0 + idx = np.ravel(tmp) # flatten the array + + if idx.size == 0: # the element is out of the bounds of the Universe of Discourse + if math.ceil(ndata[k]) <= self.sets[0].lower: + idx = [0] + elif math.ceil(ndata[k]) >= self.sets[-1].upper: + idx = [len(self.sets) - 1] + else: + raise Exception(ndata[k]) + + for kk in idx: + flrg = hofts.HighOrderFLRG(self.order) + flrg.appendLHS(self.sets[kk]) + affected_flrgs.append(flrg) + affected_flrgs_memberships.append(mv[kk]) + + count = 0 + for flrg in affected_flrgs: + # achar o os bounds de cada FLRG, ponderados pela probabilidade e pertinência + norm = self.getProbability(flrg) * affected_flrgs_memberships[count] + if norm == 0: + norm = self.getProbability(flrg) # * 0.001 + up.append(norm * self.getUpper(flrg)) + lo.append(norm * self.getLower(flrg)) + norms.append(norm) + count = count + 1 + + # gerar o intervalo + norm = sum(norms) + if norm == 0: + ret.append([0, 0]) + else: + ret.append([sum(lo) / norm, sum(up) / norm]) + + return ret + + def forecastAhead(self, data, steps): + ret = [[data[k], data[k]] for k in np.arange(len(data) - self.order, len(data))] + + for k in np.arange(self.order - 1, steps): + + if ret[-1][0] <= self.sets[0].lower and ret[-1][1] >= self.sets[-1].upper: + ret.append(ret[-1]) + else: + lower = self.forecast([ret[x][0] for x in np.arange(k - self.order, k)]) + upper = self.forecast([ret[x][1] for x in np.arange(k - self.order, k)]) + + ret.append([np.min(lower), np.max(upper)]) + + return ret + + def getGridClean(self, resolution): + grid = {} + for sbin in np.arange(self.sets[0].lower, self.sets[-1].upper, resolution): + grid[sbin] = 0 + + return grid + + def gridCount(self, grid, resolution, interval): + for sbin in sorted(grid): + if sbin >= interval[0] and (sbin + resolution) <= interval[1]: + grid[sbin] = grid[sbin] + 1 + return grid + + def forecastDistributionAhead2(self, data, steps, resolution): + + ret = [] + + intervals = self.forecastAhead(data, steps) + + for k in np.arange(self.order, steps): + + grid = self.getGridClean(resolution) + grid = self.gridCount(grid, resolution, intervals[k]) + + lags = {} + + cc = 0 + for x in np.arange(k - self.order, k): + tmp = [] + for qt in np.arange(0, 100, 5): + tmp.append(intervals[x][0] + qt * (intervals[x][1] - intervals[x][0]) / 100) + tmp.append(intervals[x][1] - qt * (intervals[x][1] - intervals[x][0]) / 100) + tmp.append(intervals[x][0] + (intervals[x][1] - intervals[x][0]) / 2) + + lags[cc] = tmp + + cc = cc + 1 + # Build the tree with all possible paths + + root = tree.FLRGTreeNode(None) + + self.buildTree(root, lags, 0) + + # Trace the possible paths and build the PFLRG's + + for p in root.paths(): + path = list(reversed(list(filter(None.__ne__, p)))) + + subset = [kk for kk in path] + + qtle = self.forecast(subset) + grid = self.gridCount(grid, resolution, np.ravel(qtle)) + + tmp = np.array([grid[k] for k in sorted(grid)]) + ret.append(tmp / sum(tmp)) + + grid = self.getGridClean(resolution) + df = pd.DataFrame(ret, columns=sorted(grid)) + return df + + def forecastDistributionAhead(self, data, steps, resolution): + + ret = [] + + intervals = self.forecastAhead(data, steps) + + for k in np.arange(self.order, steps): + + grid = self.getGridClean(resolution) + grid = self.gridCount(grid, resolution, intervals[k]) + + for qt in np.arange(1, 50, 2): + # print(qt) + qtle_lower = self.forecast([intervals[x][0] + qt * (intervals[x][1] - intervals[x][0]) / 100 for x in + np.arange(k - self.order, k)]) + grid = self.gridCount(grid, resolution, np.ravel(qtle_lower)) + qtle_upper = self.forecast([intervals[x][1] - qt * (intervals[x][1] - intervals[x][0]) / 100 for x in + np.arange(k - self.order, k)]) + grid = self.gridCount(grid, resolution, np.ravel(qtle_upper)) + qtle_mid = self.forecast( + [intervals[x][0] + (intervals[x][1] - intervals[x][0]) / 2 for x in np.arange(k - self.order, k)]) + grid = self.gridCount(grid, resolution, np.ravel(qtle_mid)) + + tmp = np.array([grid[k] for k in sorted(grid)]) + + ret.append(tmp / sum(tmp)) + + grid = self.getGridClean(resolution) + df = pd.DataFrame(ret, columns=sorted(grid)) + return df + + def __str__(self): + tmp = self.name + ":\n" + for r in sorted(self.flrgs): + p = round(self.flrgs[r].frequencyCount / self.globalFrequency, 3) + tmp = tmp + "(" + str(p) + ") " + str(self.flrgs[r]) + "\n" + return tmp diff --git a/sadaei.py b/sadaei.py index 00288f0..0fb02f4 100644 --- a/sadaei.py +++ b/sadaei.py @@ -1,81 +1,82 @@ import numpy as np -from pyFTS import * +from pyFTS.common import FuzzySet,FLR +import fts class ExponentialyWeightedFLRG: - def __init__(self,LHS,c): - self.LHS = LHS - self.RHS = [] - self.count = 0.0 - self.c = c + def __init__(self, LHS, c): + self.LHS = LHS + self.RHS = [] + self.count = 0.0 + self.c = c + + def append(self, c): + self.RHS.append(c) + self.count = self.count + 1.0 + + def weights(self): + wei = [self.c ** k for k in np.arange(0.0, self.count, 1.0)] + tot = sum(wei) + return np.iarray([k / tot for k in wei]) + + def __str__(self): + tmp = self.LHS.name + " -> " + tmp2 = "" + cc = 0 + wei = [self.c ** k for k in np.arange(0.0, self.count, 1.0)] + tot = sum(wei) + for c in sorted(self.RHS, key=lambda s: s.name): + if len(tmp2) > 0: + tmp2 = tmp2 + "," + tmp2 = tmp2 + c.name + "(" + str(wei[cc] / tot) + ")" + cc = cc + 1 + return tmp + tmp2 - def append(self,c): - self.RHS.append(c) - self.count = self.count + 1.0 - def weights(self): - wei = [ self.c**k for k in np.arange(0.0,self.count,1.0)] - tot = sum( wei ) - return np.array([ k/tot for k in wei ]) - - def __str__(self): - tmp = self.LHS.name + " -> " - tmp2 = "" - cc = 0 - wei = [ self.c**k for k in np.arange(0.0,self.count,1.0)] - tot = sum( wei ) - for c in sorted(self.RHS, key=lambda s: s.name): - if len(tmp2) > 0: - tmp2 = tmp2 + "," - tmp2 = tmp2 + c.name + "(" + str(wei[cc]/tot) + ")" - cc = cc + 1 - return tmp + tmp2 - class ExponentialyWeightedFTS(fts.FTS): - def __init__(self,name): - super(ExponentialyWeightedFTS, self).__init__(1,"EWFTS") - self.name = "Exponentialy Weighted FTS" - self.detail = "Sadaei" - self.c = 1 - - def generateFLRG(self, flrs, c): - flrgs = {} - for flr in flrs: - if flr.LHS.name in flrgs: - flrgs[flr.LHS.name].append(flr.RHS) - else: - flrgs[flr.LHS.name] = ExponentialyWeightedFLRG(flr.LHS, c); - flrgs[flr.LHS.name].append(flr.RHS) - return (flrgs) + def __init__(self, name): + super(ExponentialyWeightedFTS, self).__init__(1, "EWFTS") + self.name = "Exponentialy Weighted FTS" + self.detail = "Sadaei" + self.c = 1 - def train(self, data, sets, c): - self.c = c - self.sets = sets - tmpdata = common.fuzzySeries(data,sets) - flrs = common.generateRecurrentFLRs(tmpdata) - self.flrgs = self.generateFLRG(flrs,c) - - def forecast(self,data): - l = 1 - - ndata = np.array(data) - - l = len(ndata) - - ret = [] - - for k in np.arange(0,l): - - mv = common.fuzzyInstance(ndata[k], self.sets) - - actual = self.sets[ np.argwhere( mv == max(mv) )[0,0] ] - - if actual.name not in self.flrgs: - ret.append(actual.centroid) - else: - flrg = self.flrgs[actual.name] - mp = self.getMidpoints(flrg) - - ret.append( mp.dot( flrg.weights() )) - - return ret - + def generateFLRG(self, flrs, c): + flrgs = {} + for flr in flrs: + if flr.LHS.name in flrgs: + flrgs[flr.LHS.name].append(flr.RHS) + else: + flrgs[flr.LHS.name] = ExponentialyWeightedFLRG(flr.LHS, c); + flrgs[flr.LHS.name].append(flr.RHS) + return (flrgs) + + def train(self, data, sets, c): + self.c = c + self.sets = sets + tmpdata = FuzzySet.fuzzySeries(data, sets) + flrs = FLR.generateRecurrentFLRs(tmpdata) + self.flrgs = self.generateFLRG(flrs, c) + + def forecast(self, data): + l = 1 + + ndata = np.array(data) + + l = len(ndata) + + ret = [] + + for k in np.arange(0, l): + + mv = FuzzySet.fuzzyInstance(ndata[k], self.sets) + + actual = self.sets[np.argwhere(mv == max(mv))[0, 0]] + + if actual.name not in self.flrgs: + ret.append(actual.centroid) + else: + flrg = self.flrgs[actual.name] + mp = self.getMidpoints(flrg) + + ret.append(mp.dot(flrg.weights())) + + return ret diff --git a/sfts.py b/sfts.py index d14cd4c..2d38ddd 100644 --- a/sfts.py +++ b/sfts.py @@ -1,68 +1,69 @@ import numpy as np -from pyFTS import * +from pyFTS.common import FuzzySet,FLR +import fts + class SeasonalFLRG(fts.FTS): - def __init__(self,seasonality): - self.LHS = seasonality - self.RHS = [] + def __init__(self, seasonality): + self.LHS = seasonality + self.RHS = [] - def append(self,c): - self.RHS.append(c) + def append(self, c): + self.RHS.append(c) + + def __str__(self): + tmp = str(self.LHS) + " -> " + tmp2 = "" + for c in sorted(self.RHS, key=lambda s: s.name): + if len(tmp2) > 0: + tmp2 = tmp2 + "," + tmp2 = tmp2 + c.name + return tmp + tmp2 - def __str__(self): - tmp = str(self.LHS) + " -> " - tmp2 = "" - for c in sorted(self.RHS, key=lambda s: s.name): - if len(tmp2) > 0: - tmp2 = tmp2 + "," - tmp2 = tmp2 + c.name - return tmp + tmp2 - class SeasonalFTS(fts.FTS): - def __init__(self,name): - super(SeasonalFTS, self).__init__(1,"SFTS") - self.name = "Seasonal FTS" - self.detail = "Chen" - self.seasonality = 1 - self.isSeasonal = True - - - def generateFLRG(self, flrs): - flrgs = [] - season = 1 - for flr in flrs: - if len(flrgs) < self.seasonality: - flrgs.append(SeasonalFLRG(season)) - - flrgs[season].append(flr.RHS) - - season = (season + 1) % (self.seasonality + 1) - - if season == 0: season = 1 - - return (flrgs) - - def train(self, data, sets, seasonality): - self.sets = sets - self.seasonality = seasonality - tmpdata = common.fuzzySeries(data,sets) - flrs = common.generateRecurrentFLRs(tmpdata) - self.flrgs = self.generateFLRG(flrs) - - def forecast(self,data): - - ndata = np.array(data) - - l = len(ndata) - - ret = [] - - for k in np.arange(1,l): - flrg = self.flrgs[ data[k] ] - - mp = self.getMidpoints(flrg) - - ret.append(sum(mp)/len(mp)) - - return ret + def __init__(self, name): + super(SeasonalFTS, self).__init__(1, "SFTS") + self.name = "Seasonal FTS" + self.detail = "Chen" + self.seasonality = 1 + self.isSeasonal = True + + def generateFLRG(self, flrs): + flrgs = [] + season = 1 + for flr in flrs: + if len(flrgs) < self.seasonality: + flrgs.append(SeasonalFLRG(season)) + + flrgs[season].append(flr.RHS) + + season = (season + 1) % (self.seasonality + 1) + + if season == 0: season = 1 + + return (flrgs) + + def train(self, data, sets, seasonality): + self.sets = sets + self.seasonality = seasonality + tmpdata = FuzzySet.fuzzySeries(data, sets) + flrs = FLR.generateRecurrentFLRs(tmpdata) + self.flrgs = self.generateFLRG(flrs) + + def forecast(self, data): + + ndata = np.array(data) + + l = len(ndata) + + ret = [] + + for k in np.arange(1, l): + flrg = self.flrgs[data[k]] + + mp = self.getMidpoints(flrg) + + ret.append(sum(mp) / len(mp)) + + return ret diff --git a/tree.py b/tree.py index 4e7d77a..903651b 100644 --- a/tree.py +++ b/tree.py @@ -4,48 +4,49 @@ import numpy as np class FLRGTreeNode: - - def __init__(self,value): - self.isRoot = False - self.children = [] - self.value = value - - def appendChild(self,child): - self.children.append(child) - - def getChildren(self): - for child in self.children: - yield child - - def paths(self, acc=[]): - if len(self.children) == 0: - yield [self.value]+acc + def __init__(self, value): + self.isRoot = False + self.children = [] + self.value = value + + def appendChild(self, child): + self.children.append(child) + + def getChildren(self): + for child in self.children: + yield child + + def paths(self, acc=[]): + if len(self.children) == 0: + yield [self.value] + acc + + for child in self.children: + for leaf_path in child.paths([self.value] + acc): # these two + yield leaf_path + + def getStr(self, k): + if self.isRoot: + tmp = str(self.value) + else: + tmp = "\\" + ("-" * k) + str(self.value) + for child in self.getChildren(): + tmp = tmp + "\n" + child.getStr(k + 1) + return tmp + + def __str__(self): + return self.getStr(0) - for child in self.children: - for leaf_path in child.paths([self.value]+acc): # these two - yield leaf_path - - def getStr(self,k): - if self.isRoot: - tmp = str(self.value) - else: - tmp = "\\" + ("-" * k) + str(self.value) - for child in self.getChildren(): - tmp = tmp + "\n" + child.getStr(k + 1) - return tmp - - def __str__(self): - return self.getStr(0) class FLRGTree: - def __init__(self): - self.root = FLRGTreeNode(None) + def __init__(self): + self.root = FLRGTreeNode(None) + def flat(dados): - for inst in dados: - if isinstance(inst, (list, tuple)): - x = flat(inst) - for k in x: - yield k - else: - yield inst + for inst in dados: + if isinstance(inst, (list, tuple)): + x = flat(inst) + for k in x: + yield k + else: + yield inst diff --git a/yu.py b/yu.py index 4f40005..6a11a11 100644 --- a/yu.py +++ b/yu.py @@ -1,77 +1,78 @@ import numpy as np -from pyFTS import * +from pyFTS.common import FuzzySet,FLR +import fts + class WeightedFLRG(fts.FTS): - def __init__(self,LHS): - self.LHS = LHS - self.RHS = [] - self.count = 1.0 + def __init__(self, LHS): + self.LHS = LHS + self.RHS = [] + self.count = 1.0 - def append(self,c): - self.RHS.append(c) - self.count = self.count + 1.0 + def append(self, c): + self.RHS.append(c) + self.count = self.count + 1.0 + + def weights(self): + tot = sum(np.arange(1.0, self.count, 1.0)) + return np.array([k / tot for k in np.arange(1.0, self.count, 1.0)]) + + def __str__(self): + tmp = self.LHS.name + " -> " + tmp2 = "" + cc = 1.0 + tot = sum(np.arange(1.0, self.count, 1.0)) + for c in sorted(self.RHS, key=lambda s: s.name): + if len(tmp2) > 0: + tmp2 = tmp2 + "," + tmp2 = tmp2 + c.name + "(" + str(round(cc / tot, 3)) + ")" + cc = cc + 1.0 + return tmp + tmp2 - def weights(self): - tot = sum( np.arange(1.0,self.count,1.0) ) - return np.array([ k/tot for k in np.arange(1.0,self.count,1.0) ]) - - def __str__(self): - tmp = self.LHS.name + " -> " - tmp2 = "" - cc = 1.0 - tot = sum( np.arange(1.0,self.count,1.0) ) - for c in sorted(self.RHS, key=lambda s: s.name): - if len(tmp2) > 0: - tmp2 = tmp2 + "," - tmp2 = tmp2 + c.name + "(" + str(round(cc/tot,3)) + ")" - cc = cc + 1.0 - return tmp + tmp2 - class WeightedFTS(fts.FTS): - def __init__(self,name): - super(WeightedFTS, self).__init__(1,"WFTS") - self.name = "Weighted FTS" - self.detail = "Yu" + def __init__(self, name): + super(WeightedFTS, self).__init__(1, "WFTS") + self.name = "Weighted FTS" + self.detail = "Yu" - - def generateFLRG(self, flrs): - flrgs = {} - for flr in flrs: - if flr.LHS.name in flrgs: - flrgs[flr.LHS.name].append(flr.RHS) - else: - flrgs[flr.LHS.name] = WeightedFLRG(flr.LHS); - flrgs[flr.LHS.name].append(flr.RHS) - return (flrgs) + def generateFLRG(self, flrs): + flrgs = {} + for flr in flrs: + if flr.LHS.name in flrgs: + flrgs[flr.LHS.name].append(flr.RHS) + else: + flrgs[flr.LHS.name] = WeightedFLRG(flr.LHS); + flrgs[flr.LHS.name].append(flr.RHS) + return (flrgs) - def train(self, data, sets): - self.sets = sets - tmpdata = common.fuzzySeries(data,sets) - flrs = common.generateRecurrentFLRs(tmpdata) - self.flrgs = self.generateFLRG(flrs) - - def forecast(self,data): - l = 1 - - ndata = np.array(data) - - l = len(ndata) - - ret = [] - - for k in np.arange(0,l): - - mv = common.fuzzyInstance(ndata[k], self.sets) - - actual = self.sets[ np.argwhere( mv == max(mv) )[0,0] ] - - if actual.name not in self.flrgs: - ret.append(actual.centroid) - else: - flrg = self.flrgs[actual.name] - mp = self.getMidpoints(flrg) - - ret.append( mp.dot( flrg.weights() )) - - return ret + def train(self, data, sets): + self.sets = sets + tmpdata = FuzzySet.fuzzySeries(data, sets) + flrs = FLR.generateRecurrentFLRs(tmpdata) + self.flrgs = self.generateFLRG(flrs) + + def forecast(self, data): + l = 1 + + ndata = np.array(data) + + l = len(ndata) + + ret = [] + + for k in np.arange(0, l): + + mv = FuzzySet.fuzzyInstance(ndata[k], self.sets) + + actual = self.sets[np.argwhere(mv == max(mv))[0, 0]] + + if actual.name not in self.flrgs: + ret.append(actual.centroid) + else: + flrg = self.flrgs[actual.name] + mp = self.getMidpoints(flrg) + + ret.append(mp.dot(flrg.weights())) + + return ret