Поиск числовых закономерностей(паттернов) в массиве на 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 шт):
Можно сделать так, например:
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
---
Однозначного ответа на ваш вопрос нет.
Начнем с того, что вы даже не определили, а что есть "паттерн" в вашем представлении. Но давайте рассмотрим просто два набора чисел (кстати - вы не сказали, ваши числа это количественные переменные или ранговые) и попробуем ответить на вопрос, а похожи-ли они.
Уже тут есть различные варианты. Вы сами упомянули про среднее. Действительно, можно сравнивать средние значения, для чего в зависимости от природы данных можно применять различные статистические критерии, например t-критерий Стьюдента, z-критерий, критерий Уолша, критерий Вилкоксона-Манна-Уитни, критерий Ван дер Вардена.. и еще десятка два других. Что-до вашей идеи - "скользящее среднее с небольшим периодом 1 или 2 например" - то идея очень спорная. При малом сдвиге НИ ОДИН из критериев не покажет наличия значимого расхождения между двумя наборами. И обратите внимания - это я пока только о средних говорю, а еще можно поговорить о дисперсии таких наборов. А можно еще вместо среднего рассмотреть медианы, как более робастную характеристику ваших данных. Ну и так далее.
Второй подход - попробовать анализировать два набора с точки зрения наличия корреляции между ними. Замечание о "малом сдвиге" тут играет еще большую роль. Коэффициент корреляции в свою очередь бывает Пирсона, Кэндела, Спирмана и куча других, корректность применения которых напрямую зависит от природы ваших данных.
Третий подход - "модельный". Можно попытаться искать регрессии (в простейшем случае - линейные, в более продвинутых - вплоть до моделей типа ARIMA) для двух наборов данных, а потом определять наличие "паттернов" по схожести построенных моделей. Тут также большой простор для анализа, потому как методов сравнения (регрессионных) моделей тоже есть не мало: по близости коэффициентов, по сравнению ошибок предсказания и т.д.
Следующий подход - при более-менее длинных рядах - по сравнению эмпирических гистограмм данных двух выборок. Своя группа критериев ответа на вопросы - начиная с метода Колмогорова-Смирнова, заканчивая современными методами на основе кластерного анализа. Теоретически - наиболее корректный подход. Но предпосылки для использования- более жесткие. А применив без учета ограничений можно таких паттернов "понаобнаруживать", что мама не горюй.
Можно, наконец, попробовать "в лоб" использовать методы кластерного и классификационного анализа, считая каждую последовательность точкой в n-мерном пространстве (n-количество точек в ваших последовательностях). С одной стороны тут кластеры (классы) должны получиться достаточно "красивыми", т.е. некими шарами в этом пространстве. Но с другой стороны, опять необходимо четко понимать семантику и какую меру сходства принять в качестве базовой для этих алгоритмов. Потому как опять - методов и вариантов тут куча, а использования неподходящего заведомо приведет к неверным результатам.
Но в любом случае, еще раз подчеркну - работа со скользящим окном в любом из перечисленных методов - не так тривиальна, как может показаться при первоначальном ознакомлением с темой.
Важно отметить, что "паттерны", которые будут обнаружены при применении каждого из описанных классов методов и даже каждого конкретного метода могут существенно отличаться от паттернов, обнаруженных другими методами. И нельзя сказать (тем более просто формально), какой из них "правильный", а какой - "ложный". В общем, как я сказал, задача нетривиальна. И решать ее без привязки к семантике - как и любую задачу из области Data Science - не получиться.