Помогите написать линейную регрессию - страница 6

 

Наверно, самое лучшее в таком случае - найти среднее арифметическое всех X[i], вычесть его из самих значений, провести вычисления коэффициентов регрессии и заново скорректировать их обратно. В принципе ничто не мешает сделать то же самое и с Y[i]. Но формулы я не пытался найти, хотя это явно несложно. Тут явно какой-то прикол со слабо обусловленными матрицами.

P.S. А можно еще после нормирования рядов данных привести их примерно к одному порядку.

 
Mathemat писал (а) >>

Наверно, самое лучшее в таком случае - найти среднее арифметическое всех X[i], вычесть его из самих значений, провести вычисления коэффициентов регрессии и заново скорректировать их обратно. В принципе ничто не мешает сделать то же самое и с Y[i]. Но формулы я не пытался найти, хотя это явно несложно. Тут явно какой-то прикол со слабо обусловленными матрицами.

P.S. А можно еще после нормирования рядов данных привести их примерно к одному порядку.

А у меня и предложено через МОЖ. Прямая формула никакой корректировки не нужно.

Теперь можно и в код бейс выложить АКФ. Перепроверил, все совпадает с точностью до 8 знака, но это уже скорее всего из-за записи в файл значений АКФ расчитанных в MQL.

 

Сергей, я уже спотыкался об это пару лет назад, когда писал свою ЛР. Выход простой - прислушайтесь к рекомендации Candid'а. Единственное, что я бы в этой рекомендации уточнил, это вычесть не Time[Bars-1], а время первого значения Х[]. Во-первых, это делает код процедуры универсальным, поскольку перенос начала отсчета по Х осуществляется внутри процедуры. Во-вторых, если на графике много баров (3 года это уже 1000000 минуток, т.е. 60000000 сек.), то вычитание времени первого бара графика изменит ситуацию не принципиально. В третьих, вы сможете вернуться к своим первоначальным формулам без всяких МО, а значит убрать повторение цикла при сохранении точности.

И еще одно. Я обратил внимание, что ваши Х[] - это время минуток. То есть Х расположены эквидистантно. А это значит, что вы вообще можете уйти от времени и пользоваться номером бара. Если сделаете этот переход, то все будет считаться и точно и быстро. Можете проверить. Это предпочтительней и с той точки зрения, что ваша ЛР будет работать одинаково и на М1, и на Д1 (представьте себе, как будут отличаться значения Х на Д1 если это будет Time, а не номер бара).

 
Yurixx писал (а) >>

Сергей, ..

Спасибо.Все это перепробовал.

Просто выложил свой вариант расчета, может кому и пригодиться. Никуда ничего переносить не надо. Мне неудобно переносить X в точку 0. Т.к. эту функцию использую при расчете АКФ, а она должна быть привязана ко времени (есть там некоторые зависимости).

 

Да в общем нет необходимости переносить сам Х в точку 0. Для этого достаточно в функции строящей ЛР использовать не сам Х, а внутренний массив, сдвинутый по времени на X[1]. Можно даже и без массива обойтись, просто вычитать значение X[1] в момент вычисления сумм.

Кстати, если пробовал, неужели не помогло ?

 
Yurixx писал (а) >>

Да в общем нет необходимости переносить сам Х в точку 0. Для этого достаточно в функции строящей ЛР использовать не сам Х, а внутренний массив, сдвинутый по времени на X[1]. Можно даже и без массива обойтись, просто вычитать значение X[1] в момент вычисления сумм.

Кстати, если пробовал, неужели не помогло ?

Пробовал вроде работает. Но есть один ньюнс если алгоритм дает такую ошибку при массиве из 6 чисел, то нет гарантии что даже при смещении ошибка не будет накапливаться. Массив с которым работаю 7200 (минутки). Поэтому вот такой алгоритм и нашол, он правильно работает. А от того пришлось отказаться, т.к нет уже доверия.

//+------------------------------------------------------------------+
//| Формула предлагаемая мной                                        |
//| Рассчет коэффициентов A и B в уравнении                          |
//| y(x)=A*x+B                                                       |
//| используються формулы https://forum.mql4.com/ru/10780/page5       |
//+------------------------------------------------------------------+

void LinearRegr(double X[], double Y[], int N, double& A, double& B)
{
      double mo_X = 0.0, mo_Y = 0.0, var_0 = 0.0, var_1 = 0.0;
      
    for ( int i = 0; i < N; i ++ )
      {
        mo_X +=X[i];
        mo_Y +=Y[i];
      }
    mo_X /=N;
    mo_Y /=N;
        
    for ( i = 0; i < N; i ++ )
      {
        var_0 +=(X[i]-mo_X)*(Y[i]-mo_Y);
        var_1 +=(X[i]-mo_X)*(X[i]-mo_X);
      }
        A = var_0 / var_1;
        B = mo_Y - A * mo_X;
}

никакие смещения не нужны.

 

Нет проблем, Сергей, пользуй что хочешь. Хочу только обратить твое внимание на маленькую деталь.

Как ты конечно понимаешь, МО лежит между max и min для любого ряда. Приведенный тобой код фактически означает перенос начала отсчета в точку [mo_X, mo_Y]. И для этого ты прокручиваешь цикл по всем твоим 7200 значениям. А потом вычитаешь, в процессе вычисления сумм, координаты нулевой точки из координат ряда. С таким же успехом ты можешь взять любую точку ряда [Xm, Ym] в качестве начала отсчета и проделать вычисления второго цикла заменив [mo_X, mo_Y] на [Xm, Ym].

Параметр А линейной регрессии инвариантен относительно переносов начала координат. МО здесь ни при чем.

Ты можешь проверить этот факт за 3 минуты на бумаге.

А потому цикл по вычислению МО лишний. Надо просто привести значения Х и Y к близким порядкам.

 
Prival писал (а) >>

если алгоритм дает такую ошибку при массиве из 6 чисел, то нет гарантии что даже при смещении ошибка не будет накапливаться.

Здесь дело не в количестве чисел, а в том, что в каждом из этих 6 сидит в качестве постоянной (бесполезной) добавки 1216600000. Это просто не содержащий никакой информации мусор. Зато это 10 значащих цифр. Ну пусть 9, последний 0 неинформативен поскольку тоже у всех 6 присутствует. При возведении в квадрат этот мусор забьёт 17 значащих цифр мантиссы. А в ней всего 15. То есть пойдёт сброс младших цифр (в унитаз). Между тем именно эти сбрасываемые цифры содержат нужную информацию (в них сидит часть информации о переменной составляющей Х).

 

Так я эту формулу не выдумал. Она есть в книжках. Причем из той формулы, что использует квадраты выводиться эта (без квадратов). Просто посидите с карандашом. Доберусь до сканера, выложу страничку из Тихонов В.И. "Статистическая радиотехника" стр.446.

 
Вот именно, просто посиди с карандашом и ты увидишь, что если в изначальной твоей формуле для наклона b заменить Xi -> Xi-X0, а Yi -> Yi-Y0, то эта новая формула эквивалентна исходной. При любых значениях X0 и Y0. Поэтому суммы Xi и Yi (которые и есть вычисление МО) можно перенести внутрь второго цикла, что вдвое уменьшит время обсчета ЛР. А для получения точности надо выбрать подходящие X0 и Y0. И сделать это лучше так, чтобы порядки рядов X и Y были поближе друг к другу.