Поиск числовых закономерностей(паттернов) в массиве на Python

Всем доброго времени. Такая проблема:

Есть таблица. Нужно найти схожие числовые паттерны в столбце. Начальный паттерн, по которому будем искать схожие участки определяем сами. Например, берем начальные данные, как первые 5 чисел столбца(с 0го по 4й), далее смещаемся на +1 и сравниваем начальные 5 чисел с числами с 1го по 5й, затем смещаемся еще на +1 и сравниваем начальные со 2го по 6й и так далее. Кто-то может подсказать как это сделать?

И можно ли как то искать не точные, а похожие цепочки. Например, [20, 35, 45, 60] схоже с [21, 34, 45, 59] . Как такое искать? Как результат, нужно вернуть количество совпадений с начальным числовым паттерном, который мы выбрали.

Как пример, в данной таблице есть колонка Diff, в которой первые 5 цифр повторяются еще раз в конце.

df = pd.DataFrame({
    'Date' : ['2022.06.13','2022.06.12','2022.06.11','2022.06.10','2022.06.9','2022.06.8','2022.06.7','2022.06.6', '2022.06.5','2022.06.4','2022.06.3','2022.06.3','2022.06.2'],
    'Diff': ['2','3','10','22','3','88','34','56','2','3','10','22','3']
    })

Ответы (2 шт):

Автор решения: strawdog

Можно сделать так, например:


df = pd.DataFrame({
    'Date' : ['2022.06.13','2022.06.12','2022.06.11','2022.06.10','2022.06.9','2022.06.8','2022.06.7','2022.06.6', '2022.06.5','2022.06.4','2022.06.3','2022.06.3','2022.06.2'],
    'Diff': [2,3,10,22,3,88,34,56,2,3,10,22,3]
    })

for i, g in df.rolling(5).mean().dropna().groupby("Diff"):
    if len(g)>1:
        print(f"Similar patterns with mean :{g['Diff'].mean()}")
        for i in g.index:            
            print(df.iloc[i-4:i+1,:])
        print("---")

получите:

Similar patterns with mean :8.0
         Date  Diff
0  2022.06.13     2
1  2022.06.12     3
2  2022.06.11    10
3  2022.06.10    22
4   2022.06.9     3
         Date  Diff
8   2022.06.5     2
9   2022.06.4     3
10  2022.06.3    10
11  2022.06.3    22
12  2022.06.2     3
---
Similar patterns with mean :36.6
        Date  Diff
4  2022.06.9     3
5  2022.06.8    88
6  2022.06.7    34
7  2022.06.6    56
8  2022.06.5     2
        Date  Diff
5  2022.06.8    88
6  2022.06.7    34
7  2022.06.6    56
8  2022.06.5     2
9  2022.06.4     3
---
→ Ссылка
Автор решения: passant

Однозначного ответа на ваш вопрос нет.

Начнем с того, что вы даже не определили, а что есть "паттерн" в вашем представлении. Но давайте рассмотрим просто два набора чисел (кстати - вы не сказали, ваши числа это количественные переменные или ранговые) и попробуем ответить на вопрос, а похожи-ли они.

Уже тут есть различные варианты. Вы сами упомянули про среднее. Действительно, можно сравнивать средние значения, для чего в зависимости от природы данных можно применять различные статистические критерии, например t-критерий Стьюдента, z-критерий, критерий Уолша, критерий Вилкоксона-Манна-Уитни, критерий Ван дер Вардена.. и еще десятка два других. Что-до вашей идеи - "скользящее среднее с небольшим периодом 1 или 2 например" - то идея очень спорная. При малом сдвиге НИ ОДИН из критериев не покажет наличия значимого расхождения между двумя наборами. И обратите внимания - это я пока только о средних говорю, а еще можно поговорить о дисперсии таких наборов. А можно еще вместо среднего рассмотреть медианы, как более робастную характеристику ваших данных. Ну и так далее.

Второй подход - попробовать анализировать два набора с точки зрения наличия корреляции между ними. Замечание о "малом сдвиге" тут играет еще большую роль. Коэффициент корреляции в свою очередь бывает Пирсона, Кэндела, Спирмана и куча других, корректность применения которых напрямую зависит от природы ваших данных.

Третий подход - "модельный". Можно попытаться искать регрессии (в простейшем случае - линейные, в более продвинутых - вплоть до моделей типа ARIMA) для двух наборов данных, а потом определять наличие "паттернов" по схожести построенных моделей. Тут также большой простор для анализа, потому как методов сравнения (регрессионных) моделей тоже есть не мало: по близости коэффициентов, по сравнению ошибок предсказания и т.д.

Следующий подход - при более-менее длинных рядах - по сравнению эмпирических гистограмм данных двух выборок. Своя группа критериев ответа на вопросы - начиная с метода Колмогорова-Смирнова, заканчивая современными методами на основе кластерного анализа. Теоретически - наиболее корректный подход. Но предпосылки для использования- более жесткие. А применив без учета ограничений можно таких паттернов "понаобнаруживать", что мама не горюй.

Можно, наконец, попробовать "в лоб" использовать методы кластерного и классификационного анализа, считая каждую последовательность точкой в n-мерном пространстве (n-количество точек в ваших последовательностях). С одной стороны тут кластеры (классы) должны получиться достаточно "красивыми", т.е. некими шарами в этом пространстве. Но с другой стороны, опять необходимо четко понимать семантику и какую меру сходства принять в качестве базовой для этих алгоритмов. Потому как опять - методов и вариантов тут куча, а использования неподходящего заведомо приведет к неверным результатам.

Но в любом случае, еще раз подчеркну - работа со скользящим окном в любом из перечисленных методов - не так тривиальна, как может показаться при первоначальном ознакомлением с темой.

Важно отметить, что "паттерны", которые будут обнаружены при применении каждого из описанных классов методов и даже каждого конкретного метода могут существенно отличаться от паттернов, обнаруженных другими методами. И нельзя сказать (тем более просто формально), какой из них "правильный", а какой - "ложный". В общем, как я сказал, задача нетривиальна. И решать ее без привязки к семантике - как и любую задачу из области Data Science - не получиться.

→ Ссылка