SAX - это метод дискретизации временных рядов для лучшего понимания паттернов и мотивов. Он включает в себя объединение временных рядов и последующее преобразование этих дискретных интервалов в слова, которые представляют собой дискретные объекты, состоящие из дискретных букв. Например, я мог бы взять [-1,0,1] и, учитывая только буквы a, b и c в моем алфавите, назначить a самой нижней ячейке, b - средней ячейке и 'c' в самый верхний бункер. Это могло закончиться как abc, а [1,0,0] могло закончиться как cbb.

Вот проблема: каждый год имеет 250–252 торговых дня, и мне не нужны такие длинные слова - поэтому я использовал кусочно-агрегатное приближение (PAA) в качестве метода уменьшения размерности, чтобы сократить это 250-буквенное слово до 4- буквенное слово, как если бы я представлял четыре квартала в году. Если вы сделаете это, а затем преобразуете в слово, вы получите такие слова, как aacc, abaa и т. Д.

Может быть 81 уникальное слово, но если вы посмотрите на SPY с 1993 по 2018 год, вы найдете только 11 шаблонов или слов, причем некоторые, такие как 'aacc' и 'abbc', встречаются 4 раза за эти 26 годовой период. Конечно, степень детализации зависит от размера слова, а также от параметров размера алфавита. Вы не хотите, чтобы все было уникальным, чтобы было сложно сравнивать, но также не хотите, чтобы все было настолько похоже, чтобы сравнения были ложными.

Есть 3 модуля Python, которые имеют реализации SAX и PAA - pyts, saxpy и tslearn. В основном для этой цели я использовал saxpy; это просто казалось немного более простым. Если у вас есть цены закрытия в массиве numpy типа (26,252), вы можете использовать следующие фрагменты кода для аппроксимации временного ряда как четырехбуквенного слова с использованием букв a, b и c.

import numpy as np
from saxpy.znorm import znorm
from saxpy.paa import paa
from saxpy.sax import ts_to_string
from saxpy.alphabet import cuts_for_asize #alphabet size
words = []
for year in years:
  dat = year
  dat_znorm = znorm(dat)
  dat_paa_4 = paa(dat_znorm, 4) #a not so dirty 4-letter word
  word = ts_to_string(dat_paa_4, cuts_for_asize(3))
  words.append(word)
print(words)

Чтобы увидеть раздачу, используйте коллекции и Counter.

Counter({'aabc': 3, 'aacc': 4,  'abbc': 4,  'abcc': 4,          'acbb': 1, 'bbac': 2, 'bbca': 2, 'bcab': 1, 'cabb': 1,          'ccaa': 3, 'ccba': 1})

Если вы попробуете 5 букв (a-e) на 4-буквенных словах, вы получите следующее:

Counter({'abde': 6, 'bbde': 2, 'eacc': 1, 'abbe': 1, 'adcd': 1, 'accd': 1, 'cdea': 1, 'edba': 1, 'edaa': 1, 'ccae': 1, 'bbdd': 1, 'bbbe': 1, 'addd': 1, 'ddca': 1, 'bcbe': 1, 'ddbb': 1, 'cdbc': 1, 'acde': 1, 'abce': 1, 'cbeb': 1})

Интересно посмотреть, какие модели S & P500 существовали в годы типа «выброса». Вы можете видеть, что для некоторых лет большого роста, когда вы используете SAX_abcde (5 букв, 4-буквенные слова), то 2009 и 2013 годы, оба + 20% прироста, имели шаблон 'abde', как это было в 2014 году, хотя и с меньшим выигрышем. Без какого-либо причудливого машинного обучения, основанного на этих шаблонах, это просто своего рода прославленный спарклайн. У меня была одна мысль: как я могу предсказать закономерность развития года, скажем, в середине июня? Возможно, вы могли бы сделать приближение SAX-PAA в разных временных масштабах - так что у вас есть «слово» для января-февраля, февраля-марта, то есть двухмесячной шкалы ~ 40 баллов. Затем вы можете использовать их как функции для прогнозирования общей картины на весь год. Вы также можете использовать более одной шкалы - например, январь-февраль (2 месяца), затем январь-март (3 месяца) и январь-июнь (6 месяцев), чтобы получить 3 функции, которые можно использовать для прогнозирования. класс или слово на оставшуюся часть года.