Time_series_fuzzy

Last updated: May 3rd, 20212021-05-03Project preview
In [ ]:
!pip install networks
!pip install linkpred
!pip install scikit-fuzzy
!pip install more-itertools
In [ ]:
# import packages
import networkx as nx
import linkpred
import skfuzzy as fuzz
import numpy as np

from itertools import combinations
from numpy import array
from matplotlib import pyplot
from math import log2
from skfuzzy import control as ctrl
In [ ]:
def visibility_graph(series):

    g = nx.Graph()
    
    # convert list of magnitudes into list of tuples that hold the index
    tseries = []
    n = 0
    for magnitude in series:
        tseries.append( (n, magnitude ) )
        n += 1

    # contiguous time points always have visibility
    for n in range(0,len(tseries)-1):
        (ta, ya) = tseries[n]
        (tb, yb) = tseries[n+1]
        g.add_node(ta, mag=ya)
        g.add_node(tb, mag=yb)

    for a,b in combinations(tseries, 2):
        # two points, maybe connect
        (ta, ya) = a
        (tb, yb) = b

        connect = True
        
        # let's see all other points in the series
        for tc, yc in tseries:
            # other points, not a or b
            if ta < tc < tb and tc != ta and tc != tb:
                # does c obstruct?
                if yc >= yb + (ya - yb) * ( (tb - tc) / (tb - ta) ):
                    connect = False
                    
        if connect and tb-ta > 1:
            g.add_edge(ta, tb)
            
    nx.write_pajek(g, "graph.net")
In [ ]:
def link_pred():
    
    # import generated network
    G = linkpred.read_network("graph.net")
    
    # build similarity rank
    sim = nx.simrank_similarity(G)
    lol = [[sim[u][v] for v in sorted(sim[u])] for u in sorted(sim)]
    sim_array = array(lol)
            
    return sim_array, G
In [ ]:
def init_pred(sim_array):
    
    # get point with the highest similarity
    l = list(sim_array[:-1,-1])
    sim_pos = len(l) - l[::-1].index(max(l)) - 1

    # do initial forecast
    dx = len(series) - sim_pos - 1
    dy = series[-1] - series[sim_pos]
    pred_init = dy/dx + series[-1]
    
    return pred_init, sim_pos, dx
In [ ]:
def plot_init_forecast(series, pred_init, sim_pos):
    
    pyplot.plot(series, color='red')
    pyplot.scatter(len(series), pred_init, color='blue')
    pyplot.scatter(sim_pos, series[sim_pos], color='blue')
    pyplot.plot([sim_pos, len(series)], [series[sim_pos], pred_init], 'g--')
In [ ]:
def plot_forecast(series, pred_init):
    
    pyplot.plot(series, color='red')
    pyplot.scatter(len(series), pred_init, color='blue')
    pyplot.plot([len(series)-1, len(series)], [series[-1], pred_init], 'r--')
In [ ]:
def fuzzy_pred(dx):

    # calculate fuzzy variable r
    r = log2(abs(dx))

    # create fuzzy sets p and q
    p = ctrl.Antecedent(np.arange(0, 5, 1), 'p')
    q = ctrl.Antecedent(np.linspace(0, 1, 10000), 'q')

    # Pythonic API
    P1 = fuzz.trimf(p.universe, [0, 0, 1])
    P2 = fuzz.trimf(p.universe, [0, 1, 2])
    P3 = fuzz.trimf(p.universe, [1, 2, 3])
    P4 = fuzz.trimf(p.universe, [2, 3, 4])
    P5 = fuzz.trimf(p.universe, [3, 4, 4])

    Q1 = fuzz.trapmf(q.universe, [0, 0, .1, .2])
    Q2 = fuzz.trimf(q.universe, [.1, .2, .3])
    Q3 = fuzz.trimf(q.universe, [.2, .4, .6])
    Q4 = fuzz.trimf(q.universe, [.3, .6, .9])
    Q5 = fuzz.trimf(q.universe, [.7, .8, .9])
    Q6 = fuzz.trapmf(q.universe, [.8, .9, 1, 1])

    # create fuzzy rules
    Q1_fac = round(fuzz.defuzz(q.universe, Q1, 'lom'), 3)
    Q2_fac = round(fuzz.defuzz(q.universe, Q2, 'centroid'), 3)
    Q3_fac = round(fuzz.defuzz(q.universe, Q3, 'centroid'), 3)
    Q4_fac = round(fuzz.defuzz(q.universe, Q4, 'centroid'), 3)
    Q5_fac = round(fuzz.defuzz(q.universe, Q5, 'centroid'), 3)
    Q6_fac = round(fuzz.defuzz(q.universe, Q6, 'som'), 3)

    mu_p1 = fuzz.interp_membership(p.universe, P1, r)
    mu_p2 = fuzz.interp_membership(p.universe, P2, r)
    mu_p3 = fuzz.interp_membership(p.universe, P3, r)
    mu_p4 = fuzz.interp_membership(p.universe, P4, r)
    mu_p5 = fuzz.interp_membership(p.universe, P5, r)

    # calculate real number of f and g
    f = (Q1_fac*mu_p1 + Q2_fac*mu_p2 + Q3_fac*mu_p3 + Q5_fac*mu_p4 + Q6_fac*mu_p5) / (mu_p1 + mu_p2 + mu_p3 + mu_p4 + mu_p5)
    g = (Q6_fac*mu_p1 + Q5_fac*mu_p2 + Q4_fac*mu_p3 + Q2_fac*mu_p4 + Q1_fac*mu_p5) / (mu_p1 + mu_p2 + mu_p3 + mu_p4 + mu_p5)
    
    return f, g
In [ ]:
def forecast(f, g, pred_init, series):
    
    return f*pred_init + g*series[-1]
In [ ]:
# INPUT time series
series = [20, 40, 48, 70, 40, 60, 40, 100, 40, 80]
# series = [10, 20, 30, 20, 10, 20, 30, 20, 10, 20]
# series = [20, 40, 30, 50, 60, 40, 50, 55]

# create visibililty graph
visibility_graph(series)

# get link prediction with highest similarity
sim_array, G = link_pred()

# calculate initial forecast
pred_init, sim_pos, dx = init_pred(sim_array)

# get f and g
f, g = fuzzy_pred(dx)

# do the forecasting
y_pred = forecast(f, g, pred_init, series)
In [ ]:
# plot initial prediction
plot_init_forecast(series, pred_init, sim_pos)
In [ ]:
# plot forecast
plot_forecast(series, pred_init)
In [ ]:
# nx.draw(G, with_labels=True, font_weight='bold')
nx.draw_networkx(G)
Notebooks AI
Notebooks AI Profile20060