Краткое описание

CatSSA является упрощенным аналогом интерактивной программы анализа и прогноза временных рядов CaterpillarSSA, выполненным в виде COM-сервера. Это позволяет встроить основные шаги метода SSA в программу пользователя, предоставляя тем самым возможность автоматизации применения метода, его тестирования на исторических данных, подбора параметров, а также использования в режиме реального времени.

Для правильного использования методов COM-сервера CatSSA необходимо ознакомиться с методологией применения метода SSA. В этом могут помочь как материалы, размещенные на сайте http://www.gistatgroup.com/gus/, так и опыт работы с программой CaterpillarSSA.

Для нахождения собственных чисел и собственных векторов была использована свободно-распространяемая библиотека CLAPACK, см. Anderson, E. and Bai, Z. and Bischof, C. and Blackford, S. and Demmel, J. and Dongarra, J. and Du Croz, J. and Greenbaum, A. and Hammarling, S. and McKenney, A. and Sorensen, D., LAPACK Users' Guide, Third Edition, SIAM, 1999.

CatSSA реализует только основные алгоритмы метода SSA в общем виде. Вы можете заказать разработку специальной версии DLL, приспособленной для ваших нужд.


Регистрация

Демо-версия предназначена только для ознакомительных целей и имеет следующие ограничения:

  • длина временного ряда не может быть больше 256 точек.
  • методы Decomposition, Reconstruction и Forecast можно вызывать только один раз за время работы COM-сервера.
  • COM-сервер периодически показывает nag-screen.
Если Вы хотите полноценно использовать библиотеку, то вам необходимо приобрести лицензию. Существует три типа лицензии:

Personal

Предназначена только для персонального использования в некоммерческих целях.

Business

Данная лицензия покупается на фирму, лабораторию и т.д. Программу, использующую COM-сервер CatSSA, данная лицензия позволяет использовать только внутри купившей ее организации.

Distribution

Данная лицензия дает право распространять COM-сервер CatSSA в составе Вашего продукта.

Вы можете заказать нужную лицензию на странице: http://www.gistatgroup.com/gus/buy_com.html

После оплаты Вы получите на указанный при регистрации емейл полную версию библиотеки, соответствующую выбранной лицензии.


Техническая поддержка

Вы можете загрузить последнюю демо-версию CatSSA со страницы: http://www.gistatgroup.com/gus/programs.html

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


HRESULT Decomposition (int Lag, BOOL Centr, double Prec, int CovarMatr, int SVDMethod);

Позволяет получить разложение исходного временного ряда на компоненты. Результатом являются собственные тройки сингулярного разложения траекторной матрицы ряда, состоящие из собственного числа, собственного вектора (функции) и вектора главных компонент. Характеристики собственных троек помогают правильно выбрать номера собственных троек (или, что то же самое, номера главных компонент (ГК)), соответствующие интересующей нас компоненте исходного ряда. На следующем этапе Восстановления пользователь получает возможность восстановить на основе выбранных главных компонент одну из составляющих ряда (например, трендовую или колебательную).

Параметры

Lag [in] Задает длину окна. Обязательный параметр.

Centr [in]

Задает, использовать центрирование или нет. Значение по умолчанию - FALSE.

Prec [in]

Задает точность вычисления (вернее, ошибку применяемой численной процедуры). Значение по умолчанию - 0.000001.

CovarMatr [in]

Устанавливает метод вычислений ковариационной матрицы . Возможные значения:
0 | - SVD метод
1 | - Метод диагонального усреднения
2 | - Toeplitz
Значение по умолчанию 0.

SVDMethod [in]

Устанавливает метод вычисления с.в. Возможные значения:
0 | - Jacobi
1 | - Lapack
Значение по умолчанию 1.

Возвращаемое значение

В случае успешного выполнения возвращаемое значение - S_OK и можно обращаться к свойствам: CorrFunc, EigenVals, EigenVecs, PrincipalComps. В случае ошибки возвращаемое значение может принимать значения:
0x80005100 | Не был задан исходный ряд
0x80005101 | Неправильное значение для Lag (меньше 2 или больше [длины ряда - 1])
0x80005102 | Внутренняя ошибка при вычислениях

Замечание

Перед вызовом этого метода необходимо задать исходный временной ряд. См. SourceSeries.


HRESULT Reconstruction ();

Позволяет восстановить нужную составляющую временного ряда по выбранным ГК.

Возвращаемое значение

В случае успешного выполнения возвращаемое значение - S_OK и можно обращаться к свойствам: RecSeries, PV. В случае ошибки возвращаемое значение может принимать значения:
0x80005200 | Не были заданы ГК, по которым нужно восстановить ряд
0x80005201 | Внутренняя ошибка при вычислениях

Замечание

Перед вызовом этого метода необходимо провести разложение ряда методом Decomposition и задать ГК, по которым будет происходить восстановление. См. SelectedPC и SelectedAver.


HRESULT Forecast (int Count, int Start, int Method, BOOL AdjCentr, BOOL UseInitial);

Производит прогноз восстановленной составляющей ряда с заданной точки на заданное кол-во точек вперед.

Параметры

Count [in] Количество точек прогноза. Обязательный параметр.

Start [in]

Задает начальную точку прогноза. Если задать 0, то начальной точкой будет считаться (длина исходного ряда+1). Значение по умолчанию - 0.

Method [in]

Задает метод прогноза.
0 | - Recurrent
1 | - Vector
Значение по умолчанию 0.

AdjCentr [in]

Задает, надо ли делать поправку к прогнозу (параметр используется, только если было выбрано Centr=TRUE на этапе разложения). Поправка делается для достижения полного совпадения с алгоритмом, изложенным в книге Golyandina, Nekrutkin, Zhigljavsky "Analysis of time series structure: SSA and related techniques". Она проявляется при рекуррентном прогнозе с восстановленным рядов в качестве базы прогноза, а также при векторном прогнозе без тройки среднего.
TRUE | - Делать поправку
FALSE | - Не делать поправку. Этот вариант оставлен для преемственности версий.
Значение по умолчанию TRUE.

UseInitial [in]

Задает, какой ряд использовать в качестве базы прогноза.
TRUE | - исходный ряд
FALSE | - восстановленный
Значение по умолчанию FALSE.

Возвращаемое значение

В случае успешного выполнения возвращаемое значение - S_OK и можно обращаться к свойствам: ForecastSeries и ForecastSeriesStart. В случае ошибки возвращаемое значение может принимать значения:
0x80005300 | Внутренняя ошибка при вычислениях
0x80005301 | Неправильные значения для Count и Start ((Count < 1) or (Start < Lag) or (Start > длина ряда+1))

Замечание

Перед вызовом этого метода необходимо провести разложение ряда методом Decomposition и задать ГК, по которым будет происходить восстановление (см. SelectedPC и SelectedAver); затем вызвать метод Reconstruction .


HRESULT DisplayMessages (BOOL);

Задает, будет ли library показывать сообщения при ошибках. Read and write.

Примеры:

VC | CatSSA.SetDisplayMessages(TRUE);
Delphi | CatSSA.DisplayMessages := True;
VBA | CatSSA.DisplayMessages = True


HRESULT SourceSeries (VARIANT*);

Задает исходный временной ряд. Ряд задается как SAFEARRAY (VT_ARRAY|VT_R8). Read and write.

См. примеры: VC++, Delphi, VBA.


HRESULT CorrFunc (VARIANT*);

Корреляционная функция. Возвращается в виде SAFEARRAY (VT_ARRAY|VT_R8). Размерность: [1..Lag], где Lag - длина окна. Only read. К этому свойству можно обращаться после успешного вызова Decomposition.


HRESULT EigenVals (VARIANT*);

Собственные числа. Возвращается в виде SAFEARRAY (VT_ARRAY|VT_R8). Размерность: [1..min(Lag, Length-Lag+1)], где Lag - длина окна, Length - длина исходного ряда. Only read. К этому свойству можно обращаться после успешного вызова Decomposition.


HRESULT EigenVecs (VARIANT*);

Собственные вектора. Возвращается в виде двухмерного SAFEARRAY (VT_ARRAY|VT_R8). Размерность: [1..Lag] x [1..Lag], где Lag - длина окна. Only read. К этому свойству можно обращаться после успешного вызова Decomposition.

Пример для VBA:

  Dim EigenVecs As Variant
  EigenVecs = obj.EigenVecs
  For I = LBound(EigenVecs, 1) To UBound(EigenVecs, 1)
    For J = LBound(EigenVecs, 2) To UBound(EigenVecs, 2)
      ActiveSheet.Cells(J - LBound(EigenVecs, 2) + 2, 9 + I - LBound(EigenVecs, 1)) = EigenVecs(J, I)
    Next J
  Next I
Здесь индекс I - проходит по столбцам (с.в.), индекс J - по строкам (по координатам выбранного с.в.).


HRESULT PrincipalComps (VARIANT*);

Главные компоненты. Возвращается в виде двухмерного SAFEARRAY (VT_ARRAY|VT_R8). Размерность: [1..Lag] x [1..Length-Lag+1], где Lag - длина окна, Length - длина исходного ряда. Only read. К этому свойству можно обращаться после успешного вызова Decomposition.

Пример для VBA:

  Dim PrincipalComps As Variant
  PC = obj.PrincipalComps
  For I = LBound(PC, 1) To UBound(PC, 1)
    For J = LBound(PC, 2) To UBound(PC, 2)
      ActiveSheet.Cells(J - LBound(PC, 2) + 2, 9 + I - LBound(PC, 1)) = PC(J, I)
    Next J
  Next I
Здесь индекс I - проходит по столбцам (ГК), индекс J - по строкам (по координатам выбранного ГК).


HRESULT SelectedPC (long Index, BOOL newVal);

Задает какие ГК будут использоваться для восстановления. По умолчанию считается что ни одна ГК не выбрана. Write only. Используется перед вызовом Reconstruction.

Примеры:

VC | for (int i=1; i<=3; ++i) CatSSA.SetSelectedPC(i, TRUE);
Delphi | for I := 1 to 3 do CatSSA.SelectedPC[I] := True;


HRESULT SelectedAver (BOOL);

Задает будет ли использоваться среднее при восстановлении. Значение по умолчанию - FALSE. Write only. Используется перед вызовом Reconstruction.

Examples:

VC | CatSSA.SetSelectedAver(TRUE);
Delphi | CatSSA.SelectedAver := True;
VBA | CatSSA.SelectedAver = True

Замечание

Можно устанавливать только если при Decomposition было указано Centr=True.


HRESULT RecSeries (VARIANT*);

Восстановленный ряд. Возвращается в виде SAFEARRAY (VT_ARRAY|VT_R8). Размерность: [1..Length], где Length - длина исходного ряда. . Only read. К этому свойству можно обращаться после успешного вызова Reconstruction.


HRESULT PV (VARIANT*);

Прогнозирующая формула (коэффициенты линейной рекуррентной формулы, по которой следующее значение прогноза выражается через предыдущие). Возвращается в виде SAFEARRAY (VT_ARRAY|VT_R8). Размерность: [1..Lag-1], где Lag - длина окна. Only read. К этому свойству можно обращаться после успешного вызова Reconstruction.


HRESULT ForecastSeries (VARIANT*);

Спрогнозированный ряд. Возвращается в виде SAFEARRAY (VT_ARRAY|VT_R8). Размерность: [1..Count], где Count - число точек прогноза. Only read. К этому свойству можно обращаться после успешного вызова Forecast.


HRESULT ForecastSeriesStart (VARIANT*);

Обновленный восстановленный ряд (ряд не совпадает с базой прогноза только при использовании векторного прогноза). Возвращается в виде SAFEARRAY (VT_ARRAY|VT_R8). Размерность: [1..Start-1], где Start - начальная точка прогноза. Only read. К этому свойству можно обращаться после успешного вызова Forecast.


Пример для VC++

Создаем SafeArray и загружаем в него данные из файла (в первой строке файла - длина ряда, потом идут значения ряда):

void GetSourceSer(VARIANT &ASrcSer, char *AFileName) {
    VariantInit(&ASrcSer);
    ifstream indat(AFileName); if(!indat) return;
    int n;
    indat>>n;
    SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 1; rgsabound[0].cElements = n;
    double *pSAr; int i, d;	SAFEARRAY* sa = SafeArrayCreate(VT_R8, 1, rgsabound);
    if ((sa == NULL) || FAILED(SafeArrayAccessData(sa, (void HUGEP**)&pSAr))) return;
    for (i=0; i<n; ++i,++pSAr) { indat>>d; *pSAr = d; }
    SafeArrayUnaccessData(sa);
    ASrcSer.vt = VT_ARRAY|VT_R8; ASrcSer.parray = sa;
}

Функция для сохранения результатов в файл:

BOOL SaveArrayToFile(VARIANT &ASer, char *AFileName) {
    if ((ASer.vt & (VT_ARRAY|VT_R8)) != (VT_ARRAY|VT_R8)) return FALSE;
    SAFEARRAY* sa = ASer.parray;
    double *pSAr; long iLeft, iRight, i;
    if ((SafeArrayGetDim(sa) != 1) ||
        FAILED(SafeArrayGetLBound(sa, 1, &iLeft))||
        FAILED(SafeArrayGetUBound(sa, 1, &iRight)) ||
        FAILED(SafeArrayAccessData(sa, (void HUGEP**)&pSAr))) return FALSE;
    ofstream outdat(AFileName);
    for (i=0; i<iRight-iLeft+1; ++i,++pSAr)
        outdat<<fixed<<setw(7)<<setprecision(2)<<*pSAr<<endl;
    SafeArrayUnaccessData(sa);
    return TRUE;
}

Главный участок кода, где производится разложение, восстановление и прогноз исходного временного ряда:

    CoInitialize(NULL);
    ICatMain Cat;
    if(!Cat.CreateDispatch("CatSSA.Main")) { cout << "CatSSA - not ok" << endl; return 1; }
    Cat.SetDisplayMessages(TRUE);
    VARIANT vSrcSer; GetSourceSer(vSrcSer, "series.dat");
    if (vSrcSer.vt == VT_EMPTY) { cout << "Not get source series." << endl; return 1; }
    Cat.SetSourceSeries(&vSrcSer);

    Cat.Decomposition(72, FALSE, 0.000001);
    VARIANT vSN = Cat.GetEigenVals(); SaveArrayToFile(vSN, "sn.dat");

    for (int i=1; i<=5; ++i) Cat.SetSelectedPC(i, TRUE);
    Cat.Reconstruction();
    VARIANT vRecSer = Cat.GetRecSeries(); SaveArrayToFile(vRecSer, "rec.dat");

    Cat.Forecast(100, 0);
    VARIANT vFCastSer = Cat.GetForecastSeries(); SaveArrayToFile(vFCastSer, "forecast.dat");

    Cat.ReleaseDispatch();
    CoUninitialize();
Полные исходники примера для VC++ можно найти в папке [CatSSA Install Path]/Examples/VC/


Пример для Delphi

Создаем SafeArray и загружаем в него данные из файла (в первой строке файла - длина ряда, потом идут значения ряда):

function LoadSourceSeries(var ASeries: Variant; AFileName: string): Boolean;
var I, vN: Integer; F: TextFile; vD: Double;
begin
  Result := True;
  try
    AssignFile(F, AFileName); FileMode := 0; Reset(F);
    try
      Readln(F, vN);
      ASeries := VarArrayCreate([1, vN], varDouble);
      for I := 1 to vN do begin Readln(F, vD); ASeries[I] := vD; end;
    finally CloseFile(F); end;
  except Writeln('Can''t load source series'); Result := False; end;
end;

Функция для сохранения результатов в файл:

function SaveArrayToFile(var ASeries: Variant; AFileName: string): Boolean;
var I: Integer; F: TextFile;
begin
  Result := True;
  try
    AssignFile(F, AFileName); Rewrite(F);
    try
      for I := VarArrayLowBound(ASeries, 1) to VarArrayHighBound(ASeries, 1) do
        Writeln(F, Format('%7.12f', [Double(ASeries[I])]));
    finally CloseFile(F); end;
  except Writeln('Can''t save array'); Result := False; end;
end;

Главный участок кода, где производится разложение, восстановление и прогноз исходного временного ряда:

procedure Main;
var vObj, vSeries, vRecSer, vFCastSer: Variant; I: Integer;
begin
  OleInitialize(nil);
  if not LoadSourceSeries(vSeries, ExtractFilePath(ParamStr(0))+'series.dat') then Exit;
  vObj := CreateOleObject('CatSSA.Main');
  vObj.SourceSeries := vSeries; VarClear(vSeries);
  vObj.Decomposition(Lag:=72);
  for I := 1 to 5 do vObj.SelectedPC[I] := True;
  vObj.Reconstruction;
  vRecSer := vObj.RecSeries;
  vObj.Forecast(Count:=100);
  vFCastSer := vObj.ForecastSeries;
  VarClear(vObj);
  SaveArrayToFile(vRecSer, ExtractFilePath(ParamStr(0))+'recon.dat');
  SaveArrayToFile(vFCastSer, ExtractFilePath(ParamStr(0))+'forecast.dat');
  VarClear(vRecSer); VarClear(vFCastSer);
  Writeln('ok');
end;
Полные исходники примера для Delphi можно найти в папке [CatSSA Install Path]/Examples/Delphi/


Пример для VBA (Excel)

Пусть есть Excel file с исходным временным рядом (в первом столбце начиная со второй строки). Пусть длина ряда будет 174. Тогда мы можем создать следующий макрос, который будет прогнозировать наш ряд начиная со 175 точки на 100 точек вперед:

Public Sub TestCatSSA()
      Const N = 174
      Dim Source(1 To N) As Double
      Dim RecSer As Variant, FCastSer As Variant
      For I = 1 To N
        Source(I) = ActiveSheet.Cells(I + 1, 1)
      Next I
      Set obj = CreateObject("CatSSA.Main")
      obj.SourceSeries = Source
      obj.Decomposition Lag:=72
      For I = 1 To 5
        obj.SelectedPC(I) = True
      Next I
      obj.Reconstruction
      RecSer = obj.RecSeries
      For I = LBound(RecSer) To UBound(RecSer)
        ActiveSheet.Cells(I - LBound(RecSer) + 2, 3) = RecSer(I)
      Next I
      obj.Forecast Count:=100
      FCastSer = obj.ForecastSeries
      Set obj = Nothing
      For I = LBound(FCastSer) To UBound(FCastSer)
        ActiveSheet.Cells(I - LBound(FCastSer) + 2 + N, 4) = FCastSer(I)
      Next I
      MsgBox "Ok"
End Sub
Полный исходник примера для VBA можно найти в папке [CatSSA Install Path]/Examples/VBA/


Основные понятия

Метод "Гусеница"-SSA служит для разложения временных рядов на интерпретируемые составляющие, такие как тренд, колебательные компоненты и шум. Метод также позволяет производить сглаживание временных рядов, являясь, в некотором смысле, частотным фильтром.

На первом этапе Разложения временной ряд раскладывается на элементарные составляющие, по виду которых можно определить, к какой из составляющих исходного ряда они относятся. Также при идентификации составляющих можно воспользоваться тем, что они упорядочены по величине их вклада в исходный ряд и компоненты, относящиеся к основным составляющим ряда, надо искать среди первых по вкладу.

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

Выбранный набор номеров собственных троек (или, что то же самое, набор номеров главных компонент) порождает линейную рекуррентную формулу, на основе которой на этапе Прогноза можно спрогнозировать ряд по полученной ЛРФ.

Дальнейшую информацию о методе и ссылки на литературу можно найти на сайте http://www.gistatgroup.com/.


Разложение

Основным параметром этапа Разложения является длина окна. Все остальные параметры этого этапа дополнительны и их значения можно оставить установленными по умолчанию. При первом ознакомлении с программой в качестве длины окна может быть выбрано любое целое значение больше 1 и меньше длины ряда (лучше брать значение меньше половины длины ряда). Необходимо только принять в внимание, что чем больше длина окна, тем больше время счета. Если предполагается наличие в ряде циклической компоненты с известным периодом, то лучше установить длину окна, кратной этому периоду. Для не слишком длинных рядов можно установить длину окна, близкой к половине длины ряда. Выбор маленькой длины окна ведет к сглаживанию ряда. Чем ближе длина окна к половине длины ряда, тем более детальное разложение исходного временного ряда будет получено.

Точность разложения (вернее, ошибка применяемой численной процедуры) не может выбираться меньше 1.е-14. Чем выше точность (меньше ошибка), тем медленнее проходят вычисления. Значение 1.e-6 является достаточным для большинства случаев. Для увеличения надежности вычислений можно выбрать значение, например, 1.e-9.

Стандартное разложение строится без центрирования. Использование центрирование является дополнительной возможностью.


Восстановление

Для восстановления нужной компоненты временного ряда необходимо задать номера главных компонент (собственных троек) в разложении, полученном на этапе Разложения. Основные принципы для идентификации собственных троек такие.

1. форма собственного вектора (собственной функции) и главной компоненты подобны форме восстанавливаемой составляющей ряда. В частности, для выделения тренда или сглаживания собственные функции должны быть медленно меняющимися. Для выделения колебаний они также должны иметь колебательный характер.

2. Для выделения одной периодической (синусоидальной) составляющей с периодом больше 2 нужно выбирать пару собственных троек с тем же периодом.

3. Для аппроксимации временного ряда можно выбирать первые собственные тройки (главные компоненты), так как они упорядочены по их вкладу в исходный ряд.

4. Если при разложении был выбран вариант с центрированием, то выбор компоненты среднего в некотором смысле подобен выбору первой главной компоненты.


Прогноз

Рекуррентный прогноз восстановленной составляющей ряда выполняется с использованием линейной рекуррентной формулы (ЛРФ). На какое число точек строится прогноз, столько раз последовательно применяется ЛРФ. Прогнозирующая ЛРФ строится на основе выбора компонент разложения для восстановления. Поэтому правильный выбор собственных троек (главных компонент) на этапе Восстановления в большой степени определяет точность прогноза.

Для прогнозирующей линейной рекуррентной формулы в качестве начальных данных могут быть выбраны последние по времени точки исходного временного ряда (это выбор по умолчанию). Также есть возможность начинать прогноз раньше, выбрав в качестве начальных значений (а их на 1 меньше, чем длина окна) отрезок временного ряда с заданной последней точкой.

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