示例#1
0
def get_periodic_stat(a):
    '''
    Given a sequence, find its periodicity statistics

    Returns
    -------

    stat: dictionary
        pmin
        pmax
        eps
        length

    '''

    assert_vector(a)
    assert_monotonic(a)

    stat = {}

    diff = []
    for i in range(len(a) - 1):
        diff.append(a[i + 1] - a[i])

    stat['pmin'] = min(diff)
    stat['pmax'] = max(diff)
    stat['eps'] = stat['pmax'] / stat['pmin'] - 1
    stat['start'] = epoch_to_datetime(a[0])
    stat['end'] = epoch_to_datetime(a[-1])
    stat['length'] = len(a)

    return stat
示例#2
0
def periodic_subsequence(peaksIndex,
                         peaksTime,
                         min_length=5,
                         max_length=100,
                         eps=0.15,
                         alpha=0.1,
                         low=500,
                         high=1000):
    '''
    Find periodic subsequences from an array of timestamp, and values

    Parameters
    ----------

    peaksIndex: list of peak index
    peaks_time: list of timestamps
    min_length: minimum length of the subsequence
    max_length: maximum length of the subsequence
    eps: periodicity attribute
    alpha: error bound percentage of upper margin
    low: lower bound for series of p_min
    high: upper bound for series of p_max

    Returns
    -------

    subsequences: a list of numpy vector
        each vector is one subsequence
        contains the index of periodic peaks

    '''

    assert_vector(peaksTime)
    assert_monotonic(peaksTime)

    subsIndex = relative_error_periodic_subsequence(peaksTime, eps, alpha, low,
                                                    high, min_length,
                                                    max_length)

    subsequences = []
    for s in subsIndex:
        tmp = [peaksIndex[i] for i in s]
        subsequences.append(np.array(tmp))

    return subsequences
示例#3
0
def periodic_subsequence(peaks_index,
                         peaks_time,
                         min_length=5,
                         max_length=100,
                         eps=0.15,
                         alpha=0.1,
                         low=500,
                         high=1000):
    '''
    Find periodic subsequences from an array of timestamp, and values

    Parameters
    ----------

    time: list of timestamps
    value: list of sensor value
    peak_neighbor: size of the neighborhood
    min_length: minimum length of the subsequence
    eps: periodicity
    low: lower bound for p_min
    high: upper bound for p_max

    Returns
    -------

    subsequences: a list of numpy vector
        each vector is one subsequence
        contains the index of periodic peaks

    '''

    assert_vector(peaks_time)
    assert_monotonic(peaks_time)

    subs_index = relative_error_periodic_subsequence(peaks_time, eps, alpha,
                                                     low, high, min_length,
                                                     max_length)

    subsequences = []
    for s in subs_index:
        tmp = [peaks_index[i] for i in s]
        subsequences.append(np.array(tmp))

    return subsequences
示例#4
0
def relative_error_periodic_subsequence(a, eps, alpha, low, high, min_length,
                                        max_length):
    '''
    Approximation algorithm that find eps-periodic subsequences
    '''

    assert_vector(a)
    assert_monotonic(a)

    subsequences = []

    n_steps = np.ceil(np.log(high / low) / np.log(1 + eps)).astype(int)
    for i in range(n_steps):
        pmin = low * np.power((1 + eps), i)
        pmax = pmin * (1 + eps) * (1 + alpha)

        if pmax > high:
            break

        logger.info("pmin {:0.2f} and pmax {:0.2f}".format(pmin, pmax))

        seqs = absolute_error_periodic_subsequence(a, pmin, pmax)
        seqs = [
            np.array(s) for s in seqs
            if len(s) > min_length and len(s) < max_length
        ]

        subsequences += seqs

    # sort subsequences by its start time
    start = [seq[0] for seq in subsequences]

    subsequences = [
        seq for _, seq in sorted(zip(start, subsequences),
                                 key=lambda pair: pair[0])
    ]

    return subsequences
示例#5
0
def absolute_error_periodic_subsequence(a, pmin, pmax):
    '''
    Return longest subsequences that is periodic
    Dynamic programming approach

    Parameters
    ----------

    a: list of increasing numbers

    '''

    assert_vector(a)
    assert_monotonic(a)

    N = len(a)

    traceback = {}
    for i in range(N):
        traceback[i] = []

    for i in range(1, N):

        valid = []
        for j in range(i - 1, -1, -1):
            if a[i] - a[j] > pmax:
                break
            if a[i] - a[j] >= pmin:
                valid.append(j)

        valid = list(reversed(valid))

        # now find valid predecessor for i
        for j in valid:

            if not traceback[j]:
                L = 2
            else:
                L = traceback[j][0]['L'] + 1

            predecessor = {'prev': j, 'L': L}

            tobe_kept = []
            for k in range(len(traceback[i])):
                if traceback[i][k]['L'] >= predecessor['L']:
                    tobe_kept.append(k)

            traceback[i] = [traceback[i][k] for k in tobe_kept]
            traceback[i].append(predecessor)

        # logger.debug(traceback[i])

    subsequences = []
    sequence = []
    i = N - 1
    while i >= 0:
        if traceback[i]:
            sequence.append(i)
            i = traceback[i][0]['prev']
        else:
            if len(sequence) > 0:
                sequence.append(i)
                reverse = list(reversed(sequence))
                subsequences.append(reverse)
                sequence = []
            i -= 1

    return list(reversed(subsequences))