- Sliding Window benchmark

- Refactoring of partitioners for OO design
This commit is contained in:
Petrônio Cândido de Lima e Silva 2017-02-24 13:29:55 -03:00
parent c708430313
commit 84e6e1abbf
19 changed files with 362 additions and 151 deletions

View File

@ -23,13 +23,106 @@ styles = ['-','--','-.',':','.']
nsty = len(styles)
def get_point_methods():
return [naive.Naive, chen.ConventionalFTS, yu.WeightedFTS, ismailefendi.ImprovedWeightedFTS,
sadaei.ExponentialyWeightedFTS, hofts.HighOrderFTS, pwfts.ProbabilisticWeightedFTS]
def sliding_window(data, windowsize, train=0.8,models=None,partitioners=[Grid.GridPartitioner],
partitions=[10], max_order=3,transformation=None,indexer=None):
if models is None:
models = get_point_methods()
objs = {}
lcolors = {}
rmse = {}
smape = {}
u = {}
for train,test in Util.sliding_window(data, windowsize, train):
for partition in partitions:
for partitioner in partitioners:
pttr = str(partitioner.__module__).split('.')[-1]
if transformation is not None:
data_train_fs = partitioner(transformation.apply(train), partition)
else:
data_train_fs = partitioner(train, partition)
for count, model in enumerate(models, start=0):
mfts = model("")
_key = mfts.shortname + " " + pttr+ " q = " +str(partition)
mfts.partitioner = data_train_fs
if not mfts.isHighOrder:
if _key not in objs:
objs[_key] = mfts
lcolors[_key] = colors[count % ncol]
rmse[_key] = []
smape[_key] = []
u[_key] = []
if transformation is not None:
mfts.appendTransformation(transformation)
mfts.train(train, data_train_fs.sets)
_rmse, _smape, _u = get_point_statistics(test, mfts, indexer)
rmse[_key].append(_rmse)
smape[_key].append(_smape)
u[_key].append(_u)
else:
for order in np.arange(1, max_order + 1):
if order >= mfts.minOrder:
mfts = model("")
_key = mfts.shortname + " n = " + str(order) + " " + pttr + " q = " + str(partition)
mfts.partitioner = data_train_fs
if _key not in objs:
objs[_key] = mfts
lcolors[_key] = colors[count % ncol]
rmse[_key] = []
smape[_key] = []
u[_key] = []
if transformation is not None:
mfts.appendTransformation(transformation)
mfts.train(train, data_train_fs.sets, order=order)
_rmse, _smape, _u = get_point_statistics(test, mfts, indexer)
rmse[_key].append(_rmse)
smape[_key].append(_smape)
u[_key].append(_u)
ret = "Model\t&Order\t&Scheme\t&Partitions\t&RMSE AVG\t&RMSE STD\t& SMAPE AVG\t& SMAPE STD\t& U AVG\t& U STD \\\\ \n"
for k in sorted(objs.keys()):
mfts = objs[k]
ret += mfts.shortname + "\t &"
ret += str( mfts.order ) + "\t &"
ret += mfts.partitioner.name + "\t &"
ret += str(mfts.partitioner.partitions) + "\t &"
ret += str(round(np.mean(rmse[k]),2)) + "\t &"
ret += str(round(np.std(rmse[k]), 2)) + "\t &"
ret += str(round(np.mean(smape[k]), 2)) + "\t &"
ret += str(round(np.std(smape[k]), 2)) + "\t &"
ret += str(round(np.mean(u[k]), 2)) + "\t &"
ret += str(round(np.std(u[k]), 2)) + "\t &"
ret += str(len(mfts)) + "\\\\ \n"
print(ret)
def allPointForecasters(data_train, data_test, partitions, max_order=3, statistics=True, residuals=True,
series=True, save=False, file=None, tam=[20, 5], models=None, transformation=None,
distributions=False):
if models is None:
models = [naive.Naive, chen.ConventionalFTS, yu.WeightedFTS, ismailefendi.ImprovedWeightedFTS,
sadaei.ExponentialyWeightedFTS, hofts.HighOrderFTS, pwfts.ProbabilisticWeightedFTS]
models = get_point_methods()
objs = []
@ -62,7 +155,7 @@ def allPointForecasters(data_train, data_test, partitions, max_order=3, statisti
lcolors.append(colors[(count + order) % ncol])
if statistics:
print(getPointStatistics(data_test, objs))
print(print_point_statistics(data_test, objs))
if residuals:
print(ResidualAnalysis.compareResiduals(data_test, objs))
@ -87,29 +180,38 @@ def allPointForecasters(data_train, data_test, partitions, max_order=3, statisti
plotProbabilityDistributions(pmfs, lcolors,tam=tam)
def getPointStatistics(data, models, externalmodels = None, externalforecasts = None, indexers=None):
ret = "Model & Order & RMSE & SMAPE & Theil's U \\\\ \n"
for count,model in enumerate(models,start=0):
if indexers is not None and indexers[count] is not None:
ndata = np.array(indexers[count].get_data(data[model.order:]))
def get_point_statistics(data, model, indexer=None):
if indexer is not None:
ndata = np.array(indexer.get_data(data[model.order:]))
else:
ndata = np.array(data[model.order:])
if model.isMultivariate or indexers is None:
if model.isMultivariate or indexer is None:
forecasts = model.forecast(data)
elif not model.isMultivariate and indexers is not None:
forecasts = model.forecast( indexers[count].get_data(data) )
elif not model.isMultivariate and indexer is not None:
forecasts = model.forecast(indexer.get_data(data))
if model.hasSeasonality:
nforecasts = np.array(forecasts)
else:
nforecasts = np.array(forecasts[:-1])
ret = list()
ret.append(np.round(Measures.rmse(ndata, nforecasts), 2))
ret.append(np.round(Measures.smape(ndata, nforecasts), 2))
ret.append(np.round(Measures.UStatistic(ndata, nforecasts), 2))
return ret
def print_point_statistics(data, models, externalmodels = None, externalforecasts = None, indexers=None):
ret = "Model & Order & RMSE & SMAPE & Theil's U \\\\ \n"
for count,model in enumerate(models,start=0):
_rmse, _smape, _u = get_point_statistics(data, model, indexers[count])
ret += model.shortname + " & "
ret += str(model.order) + " & "
ret += str(round(Measures.rmse(ndata, nforecasts), 2)) + " & "
ret += str(round(Measures.smape(ndata, nforecasts), 2))+ " & "
ret += str(round(Measures.UStatistic(ndata, nforecasts), 2))
ret += str(_rmse) + " & "
ret += str(_smape)+ " & "
ret += str(_u)
#ret += str(round(Measures.TheilsInequality(np.array(data[fts.order:]), np.array(forecasts[:-1])), 4))
ret += " \\\\ \n"
if externalmodels is not None:
@ -194,7 +296,7 @@ def plotDistribution(dist):
def plotComparedSeries(original, models, colors, typeonlegend=False, save=False, file=None, tam=[20, 5],
intervals=True):
points=True, intervals=True, linewidth=1.5):
fig = plt.figure(figsize=tam)
ax = fig.add_subplot(111)
@ -203,10 +305,10 @@ def plotComparedSeries(original, models, colors, typeonlegend=False, save=False,
legends = []
ax.plot(original, color='black', label="Original", linewidth=1.5)
ax.plot(original, color='black', label="Original", linewidth=linewidth*1.5)
for count, fts in enumerate(models, start=0):
if fts.hasPointForecasting and not intervals:
if fts.hasPointForecasting and points:
forecasted = fts.forecast(original)
mi.append(min(forecasted) * 0.95)
ma.append(max(forecasted) * 1.05)
@ -214,7 +316,7 @@ def plotComparedSeries(original, models, colors, typeonlegend=False, save=False,
forecasted.insert(0, None)
lbl = fts.shortname
if typeonlegend: lbl += " (Point)"
ax.plot(forecasted, color=colors[count], label=lbl, ls="-")
ax.plot(forecasted, color=colors[count], label=lbl, ls="-",linewidth=linewidth)
if fts.hasIntervalForecasting and intervals:
forecasted = fts.forecastInterval(original)
@ -227,8 +329,8 @@ def plotComparedSeries(original, models, colors, typeonlegend=False, save=False,
upper.insert(0, None)
lbl = fts.shortname
if typeonlegend: lbl += " (Interval)"
ax.plot(lower, color=colors[count], label=lbl, ls="-")
ax.plot(upper, color=colors[count], ls="-")
ax.plot(lower, color=colors[count], label=lbl, ls="--",linewidth=linewidth)
ax.plot(upper, color=colors[count], ls="--",linewidth=linewidth)
handles0, labels0 = ax.get_legend_handles_labels()
lgd = ax.legend(handles0, labels0, loc=2, bbox_to_anchor=(1, 1))

View File

@ -20,10 +20,13 @@ class ConventionalFLRG(object):
tmp2 = tmp2 + c.name
return tmp + tmp2
def __len__(self):
return len(self.RHS)
class ConventionalFTS(fts.FTS):
def __init__(self, name):
super(ConventionalFTS, self).__init__(1, "CFTS")
super(ConventionalFTS, self).__init__(1, "CFTS " + name)
self.name = "Conventional FTS"
self.detail = "Chen"
self.flrgs = {}

View File

@ -1,6 +1,7 @@
import time
import matplotlib.pyplot as plt
import dill
import numpy as np
current_milli_time = lambda: int(round(time.time() * 1000))
@ -29,6 +30,12 @@ def enumerate2(xs, start=0, step=1):
yield (start, x)
start += step
def sliding_window(data, windowsize, train=0.8):
l = len(data)
ttrain = int(round(windowsize * train, 0))
for count in np.arange(0,l,windowsize):
yield ( data[count : count + ttrain], data[count + ttrain : count + windowsize] )
def persist_obj(obj, file):
with open(file, 'wb') as _file:

8
fts.py
View File

@ -25,6 +25,7 @@ class FTS(object):
self.transformations_param = []
self.original_max = 0
self.original_min = 0
self.partitioner = None
def fuzzy(self, data):
best = {"fuzzyset": "", "membership": 0.0}
@ -104,6 +105,12 @@ class FTS(object):
tmp = tmp + str(self.flrgs[r]) + "\n"
return tmp
def __len__(self):
return len(self.flrgs)
def len_total(self):
return sum([len(k) for k in self.flrgs])
def buildTreeWithoutOrder(self, node, lags, level):
if level not in lags:
@ -168,3 +175,4 @@ class FTS(object):

View File

@ -3,7 +3,7 @@ from pyFTS.common import FuzzySet,FLR
from pyFTS import fts
class HighOrderFLRG:
class HighOrderFLRG(object):
def __init__(self, order):
self.LHS = []
self.RHS = {}
@ -34,6 +34,10 @@ class HighOrderFLRG:
return self.strLHS() + " -> " + tmp
def __len__(self):
return len(self.RHS)
class HighOrderFTS(fts.FTS):
def __init__(self, name):
super(HighOrderFTS, self).__init__(1, "HOFTS" + name)

View File

@ -3,7 +3,7 @@ from pyFTS.common import FuzzySet,FLR
from pyFTS import fts
class ImprovedWeightedFLRG:
class ImprovedWeightedFLRG(object):
def __init__(self, LHS):
self.LHS = LHS
self.RHS = {}
@ -28,10 +28,13 @@ class ImprovedWeightedFLRG:
tmp2 = tmp2 + c + "(" + str(round(self.RHS[c] / self.count, 3)) + ")"
return tmp + tmp2
def __len__(self):
return len(self.RHS)
class ImprovedWeightedFTS(fts.FTS):
def __init__(self, name):
super(ImprovedWeightedFTS, self).__init__(1, "IWFTS")
super(ImprovedWeightedFTS, self).__init__(1, "IWFTS " + name)
self.name = "Improved Weighted FTS"
self.detail = "Ismail & Efendi"
self.setsDict = {}

View File

@ -3,6 +3,7 @@ import math
import random as rnd
import functools, operator
from pyFTS.common import FuzzySet, Membership
from pyFTS.partitioners import partitioner
def distancia(x, y):
@ -75,20 +76,23 @@ def c_means(k, dados, tam):
return centroides
class CMeansPartitioner(partitioner.Partitioner):
def __init__(self, npart,data,func = Membership.trimf):
super(CMeansPartitioner, self).__init__("CMeans ",data,npart,func)
def CMeansPartitionerTrimf(data, npart, names=None, prefix="A"):
def build(self, data):
sets = []
dmax = max(data)
dmax += dmax * 0.10
dmin = min(data)
dmin -= dmin * 0.10
centroides = c_means(npart, data, 1)
centroides = c_means(self.partitions, data, 1)
centroides.append(dmax)
centroides.append(dmin)
centroides = list(set(centroides))
centroides.sort()
for c in np.arange(1, len(centroides) - 1):
sets.append(FuzzySet.FuzzySet(prefix + str(c), Membership.trimf,
sets.append(FuzzySet.FuzzySet(self.prefix + str(c), Membership.trimf,
[round(centroides[c - 1], 3), round(centroides[c], 3), round(centroides[c + 1], 3)],
round(centroides[c], 3)))

View File

@ -3,7 +3,7 @@ import math
import random as rnd
import functools, operator
from pyFTS.common import FuzzySet, Membership
from pyFTS.partitioners import partitioner
# C. H. Cheng, R. J. Chang, and C. A. Yeh, “Entropy-based and trapezoidal fuzzification-based fuzzy time series approach for forecasting IT project cost,”
# Technol. Forecast. Social Change, vol. 73, no. 5, pp. 524542, Jun. 2006.
@ -76,21 +76,24 @@ def bestSplit(data, npart):
else:
return [threshold]
class EntropyPartitioner(partitioner.Partitioner):
def __init__(self, data,npart,func = Membership.trimf):
super(EntropyPartitioner, self).__init__("Entropy" ,data,npart,func)
def EntropyPartitionerTrimf(data, npart, prefix="A"):
def build(self, data):
sets = []
dmax = max(data)
dmax += dmax * 0.10
dmin = min(data)
dmin -= dmin * 0.10
partitions = bestSplit(data, npart)
partitions = bestSplit(data, self.partitions)
partitions.append(dmin)
partitions.append(dmax)
partitions = list(set(partitions))
partitions.sort()
for c in np.arange(1, len(partitions) - 1):
sets.append(FuzzySet.FuzzySet(prefix + str(c), Membership.trimf,
sets.append(FuzzySet.FuzzySet(self.prefix + str(c), Membership.trimf,
[partitions[c - 1], partitions[c], partitions[c + 1]],partitions[c]))
return sets

View File

@ -3,19 +3,20 @@ import math
import random as rnd
import functools,operator
from pyFTS.common import FuzzySet,Membership
from pyFTS.partitioners import partitioner
#import CMeans
# S. T. Li, Y. C. Cheng, and S. Y. Lin, “A FCM-based deterministic forecasting model for fuzzy time series,”
# Comput. Math. Appl., vol. 56, no. 12, pp. 30523063, Dec. 2008. DOI: 10.1016/j.camwa.2008.07.033.
def distancia(x,y):
def fuzzy_distance(x, y):
if isinstance(x, list):
tmp = functools.reduce(operator.add, [(x[k] - y[k])**2 for k in range(0,len(x))])
else:
tmp = (x - y) ** 2
return math.sqrt(tmp)
def pert(val, vals):
def membership(val, vals):
soma = 0
for k in vals:
if k == 0:
@ -55,7 +56,7 @@ def fuzzy_cmeans(k, dados, tam, m, deltadist=0.001):
grupo_count = 0
for grupo in centroides:
dist_grupos[grupo_count] = distancia(grupo, instancia)
dist_grupos[grupo_count] = fuzzy_distance(grupo, instancia)
grupo_count = grupo_count + 1
dist_grupos_total = functools.reduce(operator.add, [xk for xk in dist_grupos])
@ -64,7 +65,7 @@ def fuzzy_cmeans(k, dados, tam, m, deltadist=0.001):
if dist_grupos[grp] == 0:
grupos[inst_count][grp] = 1
else:
grupos[inst_count][grp] = 1 / pert(dist_grupos[grp], dist_grupos)
grupos[inst_count][grp] = 1 / membership(dist_grupos[grp], dist_grupos)
# grupos[inst_count][grp] = 1/(dist_grupos[grp] / dist_grupos_total)
# grupos[inst_count][grp] = (1/(dist_grupos[grp]**2))**m_exp / (1/(dist_grupos_total**2))**m_exp
@ -90,7 +91,7 @@ def fuzzy_cmeans(k, dados, tam, m, deltadist=0.001):
norm = functools.reduce(operator.add, [grupos[xk][grupo_count] for xk in range(0, tam_dados)])
centroides[grupo_count] = soma / norm
alteracaomedia = alteracaomedia + distancia(oldgrp, grupo)
alteracaomedia = alteracaomedia + fuzzy_distance(oldgrp, grupo)
grupo_count = grupo_count + 1
alteracaomedia = alteracaomedia / k
@ -98,18 +99,23 @@ def fuzzy_cmeans(k, dados, tam, m, deltadist=0.001):
return centroides
def FCMPartitionerTrimf(data,npart,names = None,prefix = "A"):
class FCMPartitioner(partitioner.Partitioner):
def __init__(self, data,npart,func = Membership.trimf):
super(FCMPartitioner, self).__init__("FCM ",data,npart,func)
def build(self,data):
sets = []
dmax = max(data)
dmax = dmax + dmax*0.10
dmin = min(data)
dmin = dmin - dmin*0.10
centroides = fuzzy_cmeans(npart, data, 1, 2)
centroides = fuzzy_cmeans(self.partitions, data, 1, 2)
centroides.append(dmax)
centroides.append(dmin)
centroides = list(set(centroides))
centroides.sort()
for c in np.arange(1,len(centroides)-1):
sets.append(FuzzySet.FuzzySet(prefix+str(c),Membership.trimf,[round(centroides[c-1],3), round(centroides[c],3), round(centroides[c+1],3)], round(centroides[c],3) ) )
sets.append(FuzzySet.FuzzySet(self.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

View File

@ -3,11 +3,14 @@ import math
import random as rnd
import functools, operator
from pyFTS.common import FuzzySet, Membership
from pyFTS.partitioners import partitioner
# print(common.__dict__)
class GridPartitioner(partitioner.Partitioner):
def __init__(self, data,npart,func = Membership.trimf):
super(GridPartitioner, self).__init__("Grid",data,npart,func)
def GridPartitionerTrimf(data, npart, names=None, prefix="A"):
def build(self, data):
sets = []
_min = min(data)
if _min < 0:
@ -22,30 +25,17 @@ def GridPartitionerTrimf(data, npart, names=None, prefix="A"):
dmax = _max * 0.9
dlen = dmax - dmin
partlen = dlen / npart
partlen = dlen / self.partitions
count = 0
for c in np.arange(dmin, dmax, partlen):
if self.membership_function == Membership.trimf:
sets.append(
FuzzySet.FuzzySet(prefix + str(count), Membership.trimf, [c - partlen, c, c + partlen],c))
FuzzySet.FuzzySet(self.prefix + str(count), Membership.trimf, [c - partlen, c, c + partlen],c))
elif self.membership_function == Membership.gaussmf:
sets.append(
FuzzySet.FuzzySet(self.prefix + str(count), Membership.gaussmf, [c, partlen / 3], c))
count += 1
return sets
def GridPartitionerGaussmf(data, npart, names=None, prefix="A"):
sets = []
dmax = max(data)
dmax += dmax * 0.10
dmin = min(data)
dmin -= dmin * 0.10
dlen = dmax - dmin
partlen = math.ceil(dlen / npart)
partition = math.ceil(dmin)
for c in range(npart):
sets.append(
FuzzySet.FuzzySet(prefix + str(c), Membership.gaussmf, [partition, partlen/3],
partition))
partition += partlen
return sets

View File

@ -7,8 +7,14 @@ from pyFTS.common import FuzzySet, Membership, Transformations
# K. H. Huarng, “Effective lengths of intervals to improve forecasting in fuzzy time series,”
# Fuzzy Sets Syst., vol. 123, no. 3, pp. 387394, Nov. 2001.
from pyFTS.partitioners import partitioner
def GridPartitionerTrimf(data, prefix="A"):
class HuarngPartitioner(partitioner.Partitioner):
def __init__(self, npart,data,func = Membership.trimf):
super(HuarngPartitioner, self).__init__("Huarng",data,npart,func)
def build(self, data):
data2 = Transformations.differential(data)
davg = np.abs( np.mean(data2) / 2 )
@ -31,7 +37,7 @@ def GridPartitionerTrimf(data, prefix="A"):
partition = math.ceil(dmin)
for c in range(npart):
sets.append(
FuzzySet.FuzzySet(prefix + str(c), Membership.trimf, [partition - base, partition, partition + base], partition))
FuzzySet.FuzzySet(self.prefix + str(c), Membership.trimf, [partition - base, partition, partition + base], partition))
partition += base
return sets

View File

@ -0,0 +1,38 @@
from pyFTS.common import FuzzySet, Membership
import numpy as np
class Partitioner(object):
def __init__(self,name,data,npart,func = Membership.trimf, names=None, prefix="A"):
self.name = name
self.partitions = npart
self.sets = []
self.membership_function = func
self.setnames = names
self.prefix = prefix
_min = min(data)
if _min < 0:
self.min = _min * 1.1
else:
self.min = _min * 0.9
_max = max(data)
if _max > 0:
self.max = _max * 1.1
else:
self.max = _max * 0.9
self.sets = self.build(data)
def build(self,data):
pass
def plot(self,ax):
ax.set_title(self.name)
ax.set_ylim([0, 1])
ax.set_xlim([self.min, self.max])
for s in self.sets:
if s.mf == Membership.trimf:
ax.plot([s.parameters[0], s.parameters[1], s.parameters[2]], [0, 1, 0])
elif s.mf == Membership.gaussmf:
tmpx = [kk for kk in np.arange(s.lower, s.upper)]
tmpy = [s.membership(kk) for kk in np.arange(s.lower, s.upper)]
ax.plot(tmpx, tmpy)

View File

@ -43,8 +43,8 @@ class ProbabilisticWeightedFLRG(hofts.HighOrderFLRG):
class ProbabilisticWeightedFTS(ifts.IntervalFTS):
def __init__(self, name):
super(ProbabilisticWeightedFTS, self).__init__("PFTS")
self.shortname = "PFTS " + name
super(ProbabilisticWeightedFTS, self).__init__("PWFTS")
self.shortname = "PWFTS " + name
self.name = "Probabilistic FTS"
self.detail = "Silva, P.; Guimarães, F.; Sadaei, H."
self.flrgs = {}

View File

@ -2,7 +2,7 @@ import numpy as np
from pyFTS.common import FuzzySet,FLR
from pyFTS import fts
class ExponentialyWeightedFLRG:
class ExponentialyWeightedFLRG(object):
def __init__(self, LHS, c):
self.LHS = LHS
self.RHS = []
@ -31,6 +31,9 @@ class ExponentialyWeightedFLRG:
cc = cc + 1
return tmp + tmp2
def __len__(self):
return len(self.RHS)
class ExponentialyWeightedFTS(fts.FTS):
def __init__(self, name):

View File

@ -21,6 +21,9 @@ class SeasonalFLRG(FLR.FLR):
tmp2 = tmp2 + c.name
return tmp + tmp2
def __len__(self):
return len(self.RHS)
class SeasonalFTS(fts.FTS):
def __init__(self, name):

31
tests/general.py Normal file
View File

@ -0,0 +1,31 @@
#!/usr/bin/python
# -*- coding: utf8 -*-
import os
import numpy as np
import pandas as pd
import matplotlib as plt
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import pandas as pd
from pyFTS.partitioners import Grid, Entropy, FCM
from pyFTS.common import FLR,FuzzySet,Membership,Transformations
from pyFTS import fts,hofts,ifts,pwfts,tree, chen
from pyFTS.benchmarks import benchmarks as bchmk
from pyFTS.benchmarks import Measures
from numpy import random
#print(FCM.FCMPartitionerTrimf.__module__)
gauss = random.normal(0,1.0,2000)
#gauss_teste = random.normal(0,1.0,400)
os.chdir("/home/petronio/dados/Dropbox/Doutorado/Disciplinas/AdvancedFuzzyTimeSeriesModels/")
#from pyFTS.common import Util
bchmk.sliding_window(gauss,500,train=0.7,partitioners=[Grid.GridPartitioner, FCM.FCMPartitioner, Entropy.EntropyPartitioner])

View File

@ -61,4 +61,4 @@ for max_part in [10, 20, 30, 40, 50]:
models.append(model)
ixs.append(ix)
print(bchmk.getPointStatistics(sample, models, indexers=ixs))
print(bchmk.print_point_statistics(sample, models, indexers=ixs))

2
yu.py
View File

@ -32,7 +32,7 @@ class WeightedFLRG(fts.FTS):
class WeightedFTS(fts.FTS):
def __init__(self, name):
super(WeightedFTS, self).__init__(1, "WFTS")
super(WeightedFTS, self).__init__(1, "WFTS " + name)
self.name = "Weighted FTS"
self.detail = "Yu"