Как найти «стабильность/колебание» последовательности?

Приветствую
Не знаю как обозвать то, что мне надо, постараюсь разъяснить. Для примера возьмем несколько последовательностей:
1, 2, 3, 4, 5 (рост, стабильно)
5, 4, 3, 2, 1 (спад, стабильно)
5, 50, 4, 3, 1 (в общем — это спад, нестабильный)
1, 2, 1, 2, 1 (колебания, стабильно)
2, 1, 2, 1, 2 (колебания, стабильно)
1, 5, 2, 5, 1 (колебания, нестабильно)
5, 4, 4, 5, 4 (колебания, стабильно)

Есть ли какие-то формулы/алгоритмы, которые могут определить состояние последовательности? Например, такие:
— стабильность (небольшие отклонения в колебаниях)
— нестабильность (значительные отклонения)
— рост, спад (стремительный, стабильный).
Визуально и логически я могу определить состояние последовательности, но обличить это дело в скрипт расчета затрудняюсь. Люди добрые, расскажите пожалуйста что почитать, чтобы понять реализацию, а если покажете примеры — вообще отлично!
  • Вопрос задан
  • 328 просмотров
Решения вопроса 4
sergiks
@sergiks Куратор тега Алгоритмы
♬♬
«Стабильностью» считаем точное попадание данных в одну из предопределённых функций - линейную, периодическую? Могут ли быть другие варианты «стабильности» ?

Можно проверять каждую из гипотез [ a*x + b, a*sin(b*x) + c] на данных, подбирая коэффициенты, минимизируя отклонения. Посчитать сумму квадратов отклонений данных от теории, сделать вывод, попадает идеально или нет.

См. Регрессионный анализ
Ответ написан
Комментировать
@balamyt92
; select * from users; --
Ну я бы наверно так делал:
  1. Бъем на сектора по n шагов
  2. В каждом шаге вычисляем среднее и смотрим дельту между началом и концом шага и запоминаем экстремумы
  3. Объединяем шаги в сектора по крупнее по признаку стабилен/возрастает/убывает.
  4. Уточняем края секторов по крайним экстремумам в секторе.

но это чисто теоретически решение в лоб
Ответ написан
Комментировать
@savao
Python-программист
Хочу уточнить, а последний пример - точно стабильно? Или там предполагается что в 6 число будет 4?
В общем, если так, то у вас получается довольно простая задача:
Рост и спад действительно проверяются по линейной функции. Можно посчитать МНК отклонений для того чтобы ввести некую оценку стабильности.
Для колебаний тут можно проверять по одной из периодических функций, скажем по sin().

Т.е. по некоторой части последовательности строим коэфициенты апроксимирующей функции, на остальной части последовательности проверяем отклонения от предсказанного значения. Через МНК находим разницу (ну или по сумме модулей отклонений или ещё как-то)

Можно всё это реализовать самому, можно посмотреть в сторону numpy.
Если данных очень много (последовательности в действительности длинные), то можно задействовать библиотеки для ML.
Ответ написан
Комментировать
# -*- coding: utf-8 -*-
# Author: Metalofon


def stab(numbers, last_number=None):
    numbers = list(numbers)
    if len(numbers) < 1:
        return True
    number = numbers[0]
    if last_number is not None:
        if last_number - 1 <= number <= last_number + 1:
            return True and stab(numbers[1:], number)
        else:
            return False
    else:
        return True and stab(numbers[1:], number)


def add_or_sub(numbers, last_number=None):
    numbers = list(numbers)
    if len(numbers) < 1:
        return []
    number = numbers[0]
    if last_number is not None:
        if last_number < number:
            return [1, *add_or_sub(numbers[1:], number)]
        else:
            return [-1, *add_or_sub(numbers[1:], number)]
    else:
        return [0, *add_or_sub(numbers[1:], number)]


def stabil(numbers):
    result = stab(numbers)
    if result:
        return "Стабильно"
    else:
        return "Нестабильно"


def col(numbers):
    colbs = sum(add_or_sub(numbers))
    if colbs > 0:
        return "Рост"
    elif colbs < 0:
        return "Спад"
    else:
        return "Колебания"


numbers_m = (
    (1, 2, 3, 4, 5),
    (5, 4, 3, 2, 1),
    (5, 50, 4, 3, 1),
    (1, 2, 1, 2, 1),
    (2, 1, 2, 1, 2),
    (1, 5, 2, 5, 1),
    (5, 4, 4, 5, 4)
)

for numbers_n in numbers_m:
    print(stabil(numbers_n), col(numbers_n))

Вот. Работает... Но в последнем случае колебание не возвращает.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы