Fuzzyfy optimization with binary search. Several minor parameter refactorings
This commit is contained in:
parent
9b3efeef36
commit
bb983b53dd
@ -63,134 +63,192 @@ class FuzzySet(object):
|
|||||||
return self.name + ": " + str(self.mf.__name__) + "(" + str(self.parameters) + ")"
|
return self.name + ": " + str(self.mf.__name__) + "(" + str(self.parameters) + ")"
|
||||||
|
|
||||||
|
|
||||||
def set_ordered(fuzzySets):
|
def __binary_search(x, fuzzy_sets, ordered_sets):
|
||||||
"""Order a fuzzy set list by their centroids"""
|
"""
|
||||||
if len(fuzzySets) > 0:
|
Search for elegible fuzzy sets to fuzzyfy x
|
||||||
tmp1 = [fuzzySets[k] for k in fuzzySets.keys()]
|
|
||||||
|
:param x: input value to be fuzzyfied
|
||||||
|
:param fuzzy_sets: a dictionary where the key is the fuzzy set name and the value is the fuzzy set object.
|
||||||
|
:param ordered_sets: a list with the fuzzy sets names ordered by their centroids.
|
||||||
|
:return: A list with the best fuzzy sets that may contain x
|
||||||
|
"""
|
||||||
|
max_len = len(fuzzy_sets)
|
||||||
|
first = 0
|
||||||
|
last = max_len
|
||||||
|
|
||||||
|
while first <= last:
|
||||||
|
midpoint = (first + last) // 2
|
||||||
|
fs = ordered_sets[midpoint]
|
||||||
|
fs1 = ordered_sets[midpoint - 1] if midpoint > 0 else ordered_sets[0]
|
||||||
|
fs2 = ordered_sets[midpoint + 1] if midpoint < max_len else ordered_sets[max_len]
|
||||||
|
if fuzzy_sets[fs1].centroid <= x <= fuzzy_sets[fs2].centroid:
|
||||||
|
return (midpoint-1, midpoint, midpoint+1)
|
||||||
|
else:
|
||||||
|
if x < fuzzy_sets[fs].centroid:
|
||||||
|
last = midpoint - 1
|
||||||
|
else:
|
||||||
|
first = midpoint + 1
|
||||||
|
|
||||||
|
|
||||||
|
def fuzzyfy(data, partitioner, **kwargs):
|
||||||
|
alpha_cut = kwargs.get('alpha_cut', 0.)
|
||||||
|
mode = kwargs.get('mode', 'sets')
|
||||||
|
method = kwargs.get('method', 'fuzzy')
|
||||||
|
if isinstance(data, (list, np.ndarray)):
|
||||||
|
if mode == 'vector':
|
||||||
|
return fuzzyfy_instances(data, partitioner.sets, partitioner.ordered_sets)
|
||||||
|
else:
|
||||||
|
return fuzzyfy_series(data, partitioner.sets, method, alpha_cut, partitioner.ordered_sets)
|
||||||
|
else:
|
||||||
|
if mode == 'vector':
|
||||||
|
return fuzzyfy_instance(data, partitioner.sets, partitioner.ordered_sets)
|
||||||
|
else:
|
||||||
|
return get_fuzzysets(data, partitioner.sets, partitioner.ordered_sets, alpha_cut)
|
||||||
|
|
||||||
|
|
||||||
|
def set_ordered(fuzzy_sets):
|
||||||
|
"""
|
||||||
|
Order a fuzzy set list by their centroids
|
||||||
|
|
||||||
|
:param fuzzy_sets: a dictionary where the key is the fuzzy set name and the value is the fuzzy set object.
|
||||||
|
:return: a list with the fuzzy sets names ordered by their centroids.
|
||||||
|
"""
|
||||||
|
if len(fuzzy_sets) > 0:
|
||||||
|
tmp1 = [fuzzy_sets[k] for k in fuzzy_sets.keys()]
|
||||||
return [k.name for k in sorted(tmp1, key=lambda x: x.centroid)]
|
return [k.name for k in sorted(tmp1, key=lambda x: x.centroid)]
|
||||||
|
|
||||||
|
|
||||||
def fuzzyfy_instance(inst, fuzzySets, ordered_sets=None):
|
def fuzzyfy_instance(inst, fuzzy_sets, ordered_sets=None):
|
||||||
"""
|
"""
|
||||||
Calculate the membership values for a data point given fuzzy sets
|
Calculate the membership values for a data point given fuzzy sets
|
||||||
|
|
||||||
:param inst: data point
|
:param inst: data point
|
||||||
:param fuzzySets: dict of fuzzy sets
|
:param fuzzy_sets: a dictionary where the key is the fuzzy set name and the value is the fuzzy set object.
|
||||||
|
:param ordered_sets: a list with the fuzzy sets names ordered by their centroids.
|
||||||
:return: array of membership values
|
:return: array of membership values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if ordered_sets is None:
|
if ordered_sets is None:
|
||||||
ordered_sets = set_ordered(fuzzySets)
|
ordered_sets = set_ordered(fuzzy_sets)
|
||||||
|
|
||||||
mv = []
|
mv = np.zeros(len(fuzzy_sets))
|
||||||
for key in ordered_sets:
|
|
||||||
mv.append( fuzzySets[key].membership(inst))
|
for ix in __binary_search(inst, fuzzy_sets, ordered_sets):
|
||||||
return np.array(mv)
|
mv[ix] = fuzzy_sets[ordered_sets[ix]].membership(inst)
|
||||||
|
|
||||||
|
return mv
|
||||||
|
|
||||||
|
|
||||||
def fuzzyfy_instances(data, fuzzySets, ordered_sets=None):
|
def fuzzyfy_instances(data, fuzzy_sets, ordered_sets=None):
|
||||||
"""
|
"""
|
||||||
Calculate the membership values for a data point given fuzzy sets
|
Calculate the membership values for a data point given fuzzy sets
|
||||||
|
|
||||||
:param inst: data point
|
:param inst: data point
|
||||||
:param fuzzySets: dict of fuzzy sets
|
:param fuzzy_sets: a dictionary where the key is the fuzzy set name and the value is the fuzzy set object.
|
||||||
|
:param ordered_sets: a list with the fuzzy sets names ordered by their centroids.
|
||||||
:return: array of membership values
|
:return: array of membership values
|
||||||
"""
|
"""
|
||||||
ret = []
|
ret = []
|
||||||
if ordered_sets is None:
|
if ordered_sets is None:
|
||||||
ordered_sets = set_ordered(fuzzySets)
|
ordered_sets = set_ordered(fuzzy_sets)
|
||||||
for inst in data:
|
for inst in data:
|
||||||
mv = np.array([fuzzySets[key].membership(inst) for key in ordered_sets])
|
mv = fuzzyfy_instance(inst, fuzzy_sets, ordered_sets)
|
||||||
ret.append(mv)
|
ret.append(mv)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def get_fuzzysets(inst, fuzzySets, ordered_sets=None, alpha_cut=0.0):
|
def get_fuzzysets(inst, fuzzy_sets, ordered_sets=None, alpha_cut=0.0):
|
||||||
"""
|
"""
|
||||||
Return the fuzzy sets which membership value for a inst is greater than the alpha_cut
|
Return the fuzzy sets which membership value for a inst is greater than the alpha_cut
|
||||||
|
|
||||||
:param inst: data point
|
:param inst: data point
|
||||||
:param fuzzySets: dict of fuzzy sets
|
:param fuzzy_sets: a dictionary where the key is the fuzzy set name and the value is the fuzzy set object.
|
||||||
|
:param ordered_sets: a list with the fuzzy sets names ordered by their centroids.
|
||||||
:param alpha_cut: Minimal membership to be considered on fuzzyfication process
|
:param alpha_cut: Minimal membership to be considered on fuzzyfication process
|
||||||
:return: array of membership values
|
:return: array of membership values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if ordered_sets is None:
|
if ordered_sets is None:
|
||||||
ordered_sets = set_ordered(fuzzySets)
|
ordered_sets = set_ordered(fuzzy_sets)
|
||||||
|
|
||||||
fs = [key for key in ordered_sets if fuzzySets[key].membership(inst) > alpha_cut]
|
fs = [ordered_sets[ix]
|
||||||
|
for ix in __binary_search(inst, fuzzy_sets, ordered_sets)
|
||||||
|
if fuzzy_sets[ordered_sets[ix]].membership(inst) > alpha_cut]
|
||||||
return fs
|
return fs
|
||||||
|
|
||||||
def get_maximum_membership_fuzzyset(inst, fuzzySets, ordered_sets=None):
|
|
||||||
|
def get_maximum_membership_fuzzyset(inst, fuzzy_sets, ordered_sets=None):
|
||||||
"""
|
"""
|
||||||
Fuzzify a data point, returning the fuzzy set with maximum membership value
|
Fuzzify a data point, returning the fuzzy set with maximum membership value
|
||||||
|
|
||||||
:param inst: data point
|
:param inst: data point
|
||||||
:param fuzzySets: dict of fuzzy sets
|
:param fuzzy_sets: a dictionary where the key is the fuzzy set name and the value is the fuzzy set object.
|
||||||
|
:param ordered_sets: a list with the fuzzy sets names ordered by their centroids.
|
||||||
:return: fuzzy set with maximum membership
|
:return: fuzzy set with maximum membership
|
||||||
"""
|
"""
|
||||||
if ordered_sets is None:
|
if ordered_sets is None:
|
||||||
ordered_sets = set_ordered(fuzzySets)
|
ordered_sets = set_ordered(fuzzy_sets)
|
||||||
mv = np.array([fuzzySets[key].membership(inst) for key in ordered_sets])
|
mv = np.array([fuzzy_sets[key].membership(inst) for key in ordered_sets])
|
||||||
key = ordered_sets[np.argwhere(mv == max(mv))[0, 0]]
|
key = ordered_sets[np.argwhere(mv == max(mv))[0, 0]]
|
||||||
return fuzzySets[key]
|
return fuzzy_sets[key]
|
||||||
|
|
||||||
|
|
||||||
def get_maximum_membership_fuzzyset_index(inst, fuzzySets):
|
def get_maximum_membership_fuzzyset_index(inst, fuzzy_sets):
|
||||||
"""
|
"""
|
||||||
Fuzzify a data point, returning the fuzzy set with maximum membership value
|
Fuzzify a data point, returning the fuzzy set with maximum membership value
|
||||||
|
|
||||||
:param inst: data point
|
:param inst: data point
|
||||||
:param fuzzySets: dict of fuzzy sets
|
:param fuzzy_sets: dict of fuzzy sets
|
||||||
:return: fuzzy set with maximum membership
|
:return: fuzzy set with maximum membership
|
||||||
"""
|
"""
|
||||||
mv = fuzzyfy_instance(inst, fuzzySets)
|
mv = fuzzyfy_instance(inst, fuzzy_sets)
|
||||||
return np.argwhere(mv == max(mv))[0, 0]
|
return np.argwhere(mv == max(mv))[0, 0]
|
||||||
|
|
||||||
|
|
||||||
def fuzzyfy_series_old(data, fuzzySets, method='maximum'):
|
def fuzzyfy_series_old(data, fuzzy_sets, method='maximum'):
|
||||||
fts = []
|
fts = []
|
||||||
for item in data:
|
for item in data:
|
||||||
fts.append(get_maximum_membership_fuzzyset(item, fuzzySets).name)
|
fts.append(get_maximum_membership_fuzzyset(item, fuzzy_sets).name)
|
||||||
return fts
|
return fts
|
||||||
|
|
||||||
|
|
||||||
def fuzzyfy_series(data, fuzzySets, method='maximum', alpha_cut=0.0):
|
def fuzzyfy_series(data, fuzzy_sets, method='maximum', alpha_cut=0.0, ordered_sets=None):
|
||||||
fts = []
|
fts = []
|
||||||
ordered_sets = set_ordered(fuzzySets)
|
if ordered_sets is None:
|
||||||
|
ordered_sets = set_ordered(fuzzy_sets)
|
||||||
for t, i in enumerate(data):
|
for t, i in enumerate(data):
|
||||||
mv = np.array([fuzzySets[key].membership(i) for key in ordered_sets])
|
mv = fuzzyfy_instance(i, fuzzy_sets, ordered_sets)
|
||||||
if len(mv) == 0:
|
if len(mv) == 0:
|
||||||
sets = check_bounds(i, fuzzySets.items(), ordered_sets)
|
sets = check_bounds(i, fuzzy_sets.items(), ordered_sets)
|
||||||
else:
|
else:
|
||||||
if method == 'fuzzy':
|
if method == 'fuzzy':
|
||||||
ix = np.ravel(np.argwhere(mv > alpha_cut))
|
ix = np.ravel(np.argwhere(mv > alpha_cut))
|
||||||
sets = [fuzzySets[ordered_sets[i]].name for i in ix]
|
sets = [fuzzy_sets[ordered_sets[i]].name for i in ix]
|
||||||
elif method == 'maximum':
|
elif method == 'maximum':
|
||||||
mx = max(mv)
|
mx = max(mv)
|
||||||
ix = np.ravel(np.argwhere(mv == mx))
|
ix = np.ravel(np.argwhere(mv == mx))
|
||||||
sets = fuzzySets[ordered_sets[ix[0]]].name
|
sets = fuzzy_sets[ordered_sets[ix[0]]].name
|
||||||
fts.append(sets)
|
fts.append(sets)
|
||||||
return fts
|
return fts
|
||||||
|
|
||||||
|
|
||||||
def grant_bounds(data, sets, ordered_sets):
|
def grant_bounds(data, fuzzy_sets, ordered_sets):
|
||||||
if data < sets[ordered_sets[0]].lower:
|
if data < fuzzy_sets[ordered_sets[0]].lower:
|
||||||
return sets[ordered_sets[0]].lower
|
return fuzzy_sets[ordered_sets[0]].lower
|
||||||
elif data > sets[ordered_sets[-1]].upper:
|
elif data > fuzzy_sets[ordered_sets[-1]].upper:
|
||||||
return sets[ordered_sets[-1]].upper
|
return fuzzy_sets[ordered_sets[-1]].upper
|
||||||
else:
|
else:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def check_bounds(data, sets, ordered_sets):
|
def check_bounds(data, fuzzy_sets, ordered_sets):
|
||||||
if data < sets[ordered_sets[0]].lower:
|
if data < fuzzy_sets[ordered_sets[0]].lower:
|
||||||
return sets[ordered_sets[0]]
|
return fuzzy_sets[ordered_sets[0]]
|
||||||
elif data > sets[ordered_sets[-1]].upper:
|
elif data > fuzzy_sets[ordered_sets[-1]].upper:
|
||||||
return sets[ordered_sets[-1]]
|
return fuzzy_sets[ordered_sets[-1]]
|
||||||
|
|
||||||
|
|
||||||
def check_bounds_index(data, sets, ordered_sets):
|
def check_bounds_index(data, fuzzy_sets, ordered_sets):
|
||||||
if data < sets[ordered_sets[0]].get_lower():
|
if data < fuzzy_sets[ordered_sets[0]].get_lower():
|
||||||
return 0
|
return 0
|
||||||
elif data > sets[ordered_sets[-1]].get_upper():
|
elif data > fuzzy_sets[ordered_sets[-1]].get_upper():
|
||||||
return len(sets) -1
|
return len(fuzzy_sets) - 1
|
||||||
|
@ -77,3 +77,14 @@ def sigmf(x, parameters):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
return 1 / (1 + math.exp(-parameters[0] * (x - parameters[1])))
|
return 1 / (1 + math.exp(-parameters[0] * (x - parameters[1])))
|
||||||
|
|
||||||
|
|
||||||
|
def singleton(x, parameters):
|
||||||
|
"""
|
||||||
|
Singleton membership function, a single value fuzzy function
|
||||||
|
|
||||||
|
:param x:
|
||||||
|
:param parameters: a list with one real value
|
||||||
|
:returns
|
||||||
|
"""
|
||||||
|
return x == parameters[0]
|
@ -68,8 +68,7 @@ class HighOrderFTS(fts.FTS):
|
|||||||
flrgs = []
|
flrgs = []
|
||||||
|
|
||||||
for ct, o in enumerate(self.lags):
|
for ct, o in enumerate(self.lags):
|
||||||
lhs = [key for key in self.partitioner.ordered_sets
|
lhs = FuzzySet.fuzzyfy(sample[o-1], partitioner=self.partitioner, mode="sets", alpha_cut=self.alpha_cut)
|
||||||
if self.sets[key].membership(sample[o-1]) > self.alpha_cut]
|
|
||||||
lags[ct] = lhs
|
lags[ct] = lhs
|
||||||
|
|
||||||
root = tree.FLRGTreeNode(None)
|
root = tree.FLRGTreeNode(None)
|
||||||
@ -95,8 +94,7 @@ class HighOrderFTS(fts.FTS):
|
|||||||
|
|
||||||
sample = data[k - self.max_lag: k]
|
sample = data[k - self.max_lag: k]
|
||||||
|
|
||||||
rhs = [key for key in self.partitioner.ordered_sets
|
rhs = FuzzySet.fuzzyfy(data[k], partitioner=self.partitioner, mode="sets", alpha_cut=self.alpha_cut)
|
||||||
if self.sets[key].membership(data[k]) > self.alpha_cut]
|
|
||||||
|
|
||||||
flrgs = self.generate_lhs_flrg(sample)
|
flrgs = self.generate_lhs_flrg(sample)
|
||||||
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
from pyFTS.common import FuzzySet
|
||||||
|
|
||||||
def fuzzyfy_instance(data_point, var):
|
def fuzzyfy_instance(data_point, var):
|
||||||
mv = np.array([var.partitioner.sets[key].membership(data_point) for key in var.partitioner.ordered_sets])
|
return FuzzySet.fuzzyfy(data_point, var.partitioner, mode='sets', method='fuzzy', alpha_cut=var.alpha_cut)
|
||||||
ix = np.ravel(np.argwhere(mv > var.alpha_cut))
|
|
||||||
sets = [(var.name, var.partitioner.ordered_sets[i]) for i in ix]
|
|
||||||
return sets
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,8 +128,8 @@ class ProbabilisticWeightedFTS(ifts.IntervalFTS):
|
|||||||
flrgs = []
|
flrgs = []
|
||||||
|
|
||||||
for ct, o in enumerate(self.lags):
|
for ct, o in enumerate(self.lags):
|
||||||
lhs = [key for key in self.partitioner.ordered_sets
|
lhs = FuzzySet.fuzzyfy(sample[o - 1], partitioner=self.partitioner, mode="sets", alpha_cut=self.alpha_cut)
|
||||||
if self.sets[key].membership(sample[o-1]) > self.alpha_cut]
|
|
||||||
lags[ct] = lhs
|
lags[ct] = lhs
|
||||||
|
|
||||||
root = tree.FLRGTreeNode(None)
|
root = tree.FLRGTreeNode(None)
|
||||||
|
@ -7,6 +7,8 @@ import matplotlib.pylab as plt
|
|||||||
#from mpl_toolkits.mplot3d import Axes3D
|
#from mpl_toolkits.mplot3d import Axes3D
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
|
from pyFTS.common import Util as cUtil, FuzzySet
|
||||||
from pyFTS.common import Transformations
|
from pyFTS.common import Transformations
|
||||||
|
|
||||||
tdiff = Transformations.Differential(1)
|
tdiff = Transformations.Differential(1)
|
||||||
@ -21,8 +23,16 @@ dataset = TAIEX.get_data()
|
|||||||
from pyFTS.partitioners import Grid, Util as pUtil
|
from pyFTS.partitioners import Grid, Util as pUtil
|
||||||
partitioner = Grid.GridPartitioner(data=dataset[:2000], npart=20) #, transformation=tdiff)
|
partitioner = Grid.GridPartitioner(data=dataset[:2000], npart=20) #, transformation=tdiff)
|
||||||
|
|
||||||
|
print(partitioner)
|
||||||
|
|
||||||
|
#print(FuzzySet.__binary_search(7000, partitioner.sets, partitioner.ordered_sets))
|
||||||
|
|
||||||
|
print(FuzzySet.fuzzyfy([5000, 7000, 8000], partitioner, mode='vector', method='fuzzy', alpha_cut=.5))
|
||||||
|
print(FuzzySet.fuzzyfy([5000, 7000, 8000], partitioner, mode='sets', method='fuzzy', alpha_cut=.5))
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
from pyFTS.common import Util as cUtil
|
|
||||||
from pyFTS.benchmarks import benchmarks as bchmk, Util as bUtil, Measures, knn, quantreg, arima, naive
|
from pyFTS.benchmarks import benchmarks as bchmk, Util as bUtil, Measures, knn, quantreg, arima, naive
|
||||||
|
|
||||||
from pyFTS.models import pwfts, song, chen, ifts, hofts
|
from pyFTS.models import pwfts, song, chen, ifts, hofts
|
||||||
@ -250,3 +260,4 @@ f, ax = plt.subplots(1, 1, figsize=[20,15])
|
|||||||
bchmk.plot_distribution(ax, 'blue', tmp, f, 0, reference_data=dataset[train_split:train_split+200])
|
bchmk.plot_distribution(ax, 'blue', tmp, f, 0, reference_data=dataset[train_split:train_split+200])
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
"""
|
Loading…
Reference in New Issue
Block a user