Doğrusal regresyon yazmaya yardımcı olun - sayfa 5

 
Rosh писал (а) >>

İşte Excel 2007'nin ürettiği şey



Bu nedenle, Matkad'ı kontrol etmeniz gerekebilir.

Doğru anladıysam, Excel ilk ikisinden farklı olarak 3. sonucu verdi). Ve gerçek nerede? B matkad ile çakıştı, ancak A katsayısı farklı

 
Prival писал (а) >>

Doğru anladıysam, Excel ilk ikisinden farklı olarak 3. sonucu verdi). Ve gerçek nerede? B matkad ile çakıştı, ancak A katsayısı farklı

Genel olarak, bu kadar çok anlamlı basamak ve böyle bir aralıkla, hesaplamalar mantisin arkasında bir yere gider. Yani, rastgelelik unsurları bile cevaba dahil edilebilir. Doğruluğun yalnızca bazı özel artan doğruluk algoritması için beklenebileceğini düşünüyorum. Ama bu durumda daha iyi orijini X aralığına yaklaştırın.



PS Özellikle X*X miktarı hesaplandığında, bilgi direk tuvalete gidiyor :)

 
lna01 писал (а) >>

Genel olarak, bu kadar çok anlamlı basamak ve böyle bir aralıkla, hesaplamalar mantisin arkasında bir yere gider. Yani, rastgelelik unsurları bile cevaba dahil edilebilir. Doğruluğun yalnızca bazı özel artan doğruluk algoritması için beklenebileceğini düşünüyorum. Ama bu durumda daha iyi orijini X aralığına yaklaştırın.

Gerçek şu ki, şampiyonluk için hazırlanmaya başladı. Ve matcad'deki gelişmelerini MQL'ye çevirmeye başladı. Hatırlarsanız, ACF'yi (otokorelasyon işlevi) oluşturduk, onunla başladım, doğrudan formülleri kullanarak hesaplamaya karar verdim, çünkü Fourier dönüşümleri aracılığıyla işlemciyi yoğun bir şekilde yüklüyorum.

Matcad'deki ilk deneme ve hemen ACF tırmığı, MQL'deki ACF ile çakışmıyor , bu yüzden tırmın nereden büyüdüğünü anlamaya başladım (

X'i (Zaman) 0 noktasına kaydırmaya çalışacağım. Ama yine, her şeyi yeniden kontrol etmem gerekiyor. Ve şimdiden fikirlerin %50'sinin terk edilmesi gerekiyor

 
Prival писал (а) >>

Gerçek şu ki, şampiyonluk için hazırlanmaya başladı. Ve matcad'deki gelişmelerini MQL'ye çevirmeye başladı. Hatırlarsanız, ACF'yi (otokorelasyon işlevi) oluşturduk, onunla başladım, doğrudan formülleri kullanarak hesaplamaya karar verdim, çünkü Fourier dönüşümleri aracılığıyla işlemciyi yoğun bir şekilde yüklüyorum.

Matcad'deki ilk deneme ve hemen ACF tırmığı, MQL'deki ACF ile çakışmıyor , bu yüzden tırmın nereden büyüdüğünü anlamaya başladım (

X'i (Zaman) 0 noktasına kaydırmaya çalışacağım. Ama yine, her şeyi yeniden kontrol etmem gerekiyor. Ve şimdiden fikirlerin %50'sinin terk edilmesi gerekiyor

MT, mantis içinde 15 hane tutar. Kökü çıkarırız, 10 ^ 7 elde ederiz. Yani, kareye almak ve hatta bundan sonra 10000000'den büyük sayıları toplamak için - bir önceki yazının yazısına bakın :). Neyse ki, bu sınır gerçek tarihteki dakika çubuklarının sayısına tekabül ediyor, bu yüzden bundan bahsediyorsak, o zaman hala çalışması gerekir. Ve eğer bu zaman ise, o zaman kökenin kayması basitçe kendini gösterir.


Not Bu arada şampiyonadaki fonksiyonunuzu kullanacaksanız sıfıra bölme koruması ekleyin. Aksi takdirde, göstergenizin şampiyonanın ortasında kalması riski vardır. Veya başlangıçta. Unutma, Fourier ile böyle bir numara vardı.

 

Java'da aynı algoritma

import java.util.ArrayList;

public class Prival {
public static void main(String arg[]){
int N = 6;
double Y[];
double X[];
ArrayList<Double> Parameters = new ArrayList<Double>();
Parameters.add(0.0);
Parameters.add(0.0);
X = new double[6];
Y = new double[6];
for ( int i = 0; i < N; i ++ )
{
// массивы Y и X для проверки работоспособности
// intercept = -3.33333333 slope = 5.00000000

X[i]=i;
Y[i]=i*i;
}

LinearRegr(X, Y, N,Parameters);
System.out.println("intercept = "+Parameters.get(0)+" slope = "+ Parameters.get(1));

// вторая проверка
X[0]=1216640160;
X[1]=1216640100;
X[2]=1216640040;
X[3]=1216639980;
X[4]=1216639920;
X[5]=1216639860;

Y[0]=1.9971;
Y[1]=1.9970;
Y[2]=1.9967;
Y[3]=1.9969;
Y[4]=1.9968;
Y[5]=1.9968;


LinearRegr(X, Y, N, Parameters);
System.out.println("intercept = "+Parameters.get(0)+" slope = "+ Parameters.get(1));

}
public static void LinearRegr(double X[], double Y[], int N, ArrayList<Double> Parameters){
double sumY = 0.0, sumX = 0.0, sumXY = 0.0, sumX2 = 0.0;
double A=0,B=0;
for ( int i = 0; i < N; i ++ ){
sumY +=Y[i];
sumXY +=X[i]*Y[i];
sumX +=X[i];
sumX2 +=X[i]*X[i];
}
B=(sumXY*N-sumX*sumY)/(sumX2*N-sumX*sumX);
A=(sumY-sumX*B)/N;
Parameters.set(0, A);
Parameters.set(1, B);
}
}


Sonuç:


kesişim = -3.3333333333333335 eğim = 5.0
kesişim = -1102.169141076954 eğim = 9.075536028198574E-7

Çıkış kodu 0 ile işlem tamamlandı

 

Roş

Bu formüllerin burada da aynı sonucu vereceğine katılıyorum matkad

Sonuçların MQL ve Java ile örtüştüğü görülüyor ancak matcad beni hiç yarı yolda bırakmadı, bu yüzden şüphelerim var. Üstelik bu ciddi bir mat. Paket defalarca test edildi.

Bir kontrol yaptım ve X'e göre sıraladım ve katsayıları tekrar hesapladı

SONUÇ değişti !!!, ama bu olmamalı. Büyük olasılıkla hata, büyük sayıların karesini alma nedeniyle oluşan hata birikiminden kaynaklanmaktadır ( Candid Sağ). Literatürü araştırdım ve daha basit bir formül buldum, kareler yok ve daha az hesaplama.

Sonuç matkad ile örtüşür ve sıralamaya bağlı değildir.

Doğrusal regresyon katsayılarını hesaplamak için bu formülü kullanmanızı öneririm.

 //+------------------------------------------------------------------+
//|                                                       LinReg.mq4 |
//|                                                    Привалов С.В. |
//|                                             Skype -> privalov-sv |
//+------------------------------------------------------------------+
#property copyright " Привалов С.В. "
#property link        " Skype -> privalov-sv "

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start ()
   {
//----
   int        N = 6 ;                 // Размер массива
   double    Y [] , X [] , A = 0.0 , B = 0.0 ;
   
   ArrayResize ( X , N ) ;
   ArrayResize ( Y , N ) ;
      
// проверка 
     X [ 0 ] = 1216640160 ;
     X [ 1 ] = 1216640100 ;
     X [ 2 ] = 1216640040 ;
     X [ 3 ] = 1216639980 ;
     X [ 4 ] = 1216639920 ;
     X [ 5 ] = 1216639860 ;
    
     Y [ 0 ] = 1.9971 ;
     Y [ 1 ] = 1.9970 ;    
     Y [ 2 ] = 1.9967 ;
     Y [ 3 ] = 1.9969 ;    
     Y [ 4 ] = 1.9968 ;    
     Y [ 5 ] = 1.9968 ;
    
    
   LinearRegr ( X , Y , N , A , B ) ;
  
   Print ( " A = " , DoubleToStr ( A , 8 ) , " B = " , DoubleToStr ( B , 8 )) ;
           
//----
   return ( 0 ) ;
   }
//+------------------------------------------------------------------+
//| Рассчет коэффициентов 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 ;
}

Birisi LinearRegr'i temizlerse (gerçek hayatta çalışırken ve performansı artırırken oluşan hatalar için) betiği ekliyorum, o zaman genellikle iyi olur. A ve B'yi değiştirdim çünkü

giriş y ( x )= a * x + b daha tanıdık (benim için kitaplardan).

Dosyalar:
linreg_1.mq4  2 kb
 

Sonucun sıralamaya nasıl bağlı olabileceğini anlamıyorum. Sıralama, formüllerin hiçbir yerinde açıkça kullanılmaz.


Ek olarak, ikinci algoritma beklenen X ve Y değerlerini kullanır ve potansiyel olarak hesaplamalarda bazı hatalara neden olur. Ve bir şey daha: Birine karşı iki döngü kullanmanın performansı artırması pek olası değildir.


Bir dizi fiyat dizisinde doğrusal regresyonun toplu hesaplamaları gerekiyorsa, göstergede ayrı tamponlar tahsis etmek ve bunları toplamları toplama yöntemiyle hesaplamak daha iyidir. Bu , büyüklük sıralarına göre hesaplamaları hızlandırmayı mümkün kılar. Örnek - Kaufman'ın optimize edilmiş AMA'sı : Perry Kaufman AMA optimize edilmiş

 
Rosh писал (а) >>

Sonucun sıralamaya nasıl bağlı olabileceğini anlamıyorum. Sıralama, formüllerin hiçbir yerinde açıkça kullanılmaz.


Ek olarak, ikinci algoritma beklenen X ve Y değerlerini kullanır ve potansiyel olarak hesaplamalarda bazı hatalara neden olur. Ve bir şey daha: Birine karşı iki döngü kullanmanın performansı artırması pek olası değildir.

Bir dizi fiyat dizisinde doğrusal regresyonun toplu hesaplamaları gerekiyorsa, göstergede ayrı tamponlar tahsis etmek ve bunları toplamları toplama yöntemiyle hesaplamak daha iyidir. Bu , büyüklük sıralarına göre hesaplamaları hızlandırmayı mümkün kılar. Örnek - Kaufman'ın optimize edilmiş AMA'sı : Perry Kaufman AMA optimize edilmiş

1. Bu, sonucun sıralamaya bağlı olmaması gereken noktadır ve bu algoritmada buna bağlıdır. İşte kontrol edin.

 //+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start ()
   {
//----
   int        N = 6 ;                 // Размер массива
   double    Y [] , X [] , Y1 [] , X1 [] , A = 0.0 , B = 0.0 ;
   
   ArrayResize ( X , N ) ;
   ArrayResize ( Y , N ) ;
   ArrayResize ( X1 , N ) ;
   ArrayResize ( Y1 , N ) ;
      
// проверка 
     X [ 0 ] = 1216640160 ;
     X [ 1 ] = 1216640100 ;
     X [ 2 ] = 1216640040 ;
     X [ 3 ] = 1216639980 ;
     X [ 4 ] = 1216639920 ;
     X [ 5 ] = 1216639860 ;
    
     Y [ 0 ] = 1.9971 ;
     Y [ 1 ] = 1.9970 ;    
     Y [ 2 ] = 1.9967 ;
     Y [ 3 ] = 1.9969 ;    
     Y [ 4 ] = 1.9968 ;    
     Y [ 5 ] = 1.9968 ;
    

// отсортируем массив по возрастанию X (исходный массив был по убыванию)
   for ( int i = 0 ; i < N ; i ++ )
   {
   X1 [ i ] = X [ N - i - 1 ] ;
   Y1 [ i ] = Y [ N - i - 1 ] ;
//   Print(X[i], " ", X1[i], " ", Y[i], " ", Y1[i]);
   }             
//----
// 
   LinearRegr ( X , Y , N , A , B ) ;
   Print ( " A = " , DoubleToStr ( A , 8 ) , " B = " , DoubleToStr ( B , 8 )) ;
   LinearRegr ( X1 , Y1 , N , A , B ) ;
   Print ( " A = " , DoubleToStr ( A , 8 ) , " B = " , DoubleToStr ( B , 8 )) ;

   LinearRegr1 ( X , Y , N , A , B ) ;
   Print ( " A = " , DoubleToStr ( A , 8 ) , " B = " , DoubleToStr ( B , 8 )) ;
   LinearRegr1 ( X1 , Y1 , N , A , B ) ;
   Print ( " A = " , DoubleToStr ( A , 8 ) , " B = " , DoubleToStr ( B , 8 )) ;

   return ( 0 ) ;
   }

//-------------------------------------------------------------------------------
// использование этой формулы приводит к ошибкам если X=Time
// формула предложена вот тут https://forum.mql4.com/ru/10780/page4
//| y(x)=A+B*x  

void LinearRegr ( double X [] , double Y [] , int N , double & A , double & B )
{
       double sumY = 0.0 , sumX = 0.0 , sumXY = 0.0 , sumX2 = 0.0 ;
      
     for ( int i = 0 ; i < N ; i ++ )
     {
         sumY    += Y [ i ] ;
         sumXY   += X [ i ] * Y [ i ] ;
         sumX    += X [ i ] ;
         sumX2   += X [ i ] * X [ i ] ;
     }
   B = ( sumXY * N - sumX * sumY ) / ( sumX2 * N - sumX * sumX ) ;
   A = ( sumY - sumX * B ) / N ;
}

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

void LinearRegr1 ( 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 ;
}

Sonuç

2008.07.30 13:51:08 LinReg EURUSD , M 1: A = 0.00000090 B =-1098.77264952

2008.07.30 13:51:08 LinReg EURUSD,M1: A = 0.00000090 B=-1098.77264952

2008.07.30 13:51:08 LinReg EURUSD,M1: A = -1078.77267965 B = 0.00000089

2008.07.30 13:51:08 LinReg EURUSD,M1: A = -1102.16914108 B = 0.00000091

Ve bu olmamalı.

2. İki döngü olduğunu görüyorum, bu yüzden bir şekilde hızı arttırmayı istedim. Bu algoritma muhtemelen daha hızlı olacaktır 'Regresyon: Nedir?' , ama aynı zamanda optimize edilmesi gerekiyor (Bence Vinin bunu zaten yaptı)

3. Kaufman için teşekkürler, iyi bir gösterge. Unutmadıysanız, ikinci şampiyonadan önce, işin yanlışlıklarını yakaladım. Onları düzelttiğiniz için teşekkür ederiz.

ZY Lütfen kimin Ma tlab'ı var . Bu dizileri girin ve yerleşik formüllerle hesaplayın (hatırladığım kadarıyla var) ve sonucu buraya gönderin. Bir fikir birliğine varmak için. Teşekkür ederim. Yardım)). Rosh'u ikna etmek oldukça zor ama benim de askeri bir alnım var))

 
Prival писал (а) >>

2. İki döngü olduğunu görüyorum, bu yüzden bir şekilde hızı arttırmayı istedim. Bu algoritma 'Regresyon: nedir?' , ama aynı zamanda optimize edilmesi gerekiyor (Bence Vinin bunu zaten yaptı)

LWMA gerçekten de X*X'ten daha güvenlidir, bu nedenle Mathemat ile çalışmanız yeni bir anlam kazanır :). Ama ilk tavsiyem (kökeni değiştirmek) en iyi seçeneği düşünmeye devam ediyorum. Time[pos]'un Time[pos]-Time[Bars-1] ile biçimsel olarak değiştirilmesi her yerde böyle bir hata oluşturma riskini taşır mı?

 
Prival писал (а) >>

1. Bu, sonucun sıralamaya bağlı olmaması gereken noktadır ve bu algoritmada buna bağlıdır. İşte kontrol edin.

Sonuç

2008.07.30 13:51:08 LinReg EURUSD , M 1: A = 0.00000090 B =-1098.77264952

2008.07.30 13:51:08 LinReg EURUSD,M1: A = 0.00000090 B=-1098.77264952

2008.07.30 13:51:08 LinReg EURUSD,M1: A = -1078.77267965 B = 0.00000089

2008.07.30 13:51:08 LinReg EURUSD,M1: A = -1102.16914108 B = 0.00000091

Ve bu olmamalı.



Çıktıyı kodunuza yapıştırın:

 //-------------------------------------------------------------------------------
// использование этой формулы приводит к ошибкам если X=Time
// формула предложена вот тут https://forum.mql4.com/ru/10780/page4
//| y(x)=A+B*x  
 
void LinearRegr ( double X [] , double Y [] , int N , double & A , double & B )
{
       double sumY = 0.0 , sumX = 0.0 , sumXY = 0.0 , sumX2 = 0.0 ;
      
     for ( int i = 0 ; i < N ; i ++ )
     {
         sumY    += Y [ i ] ;
         sumXY   += X [ i ] * Y [ i ] ;
         sumX    += X [ i ] ;
         sumX2   += X [ i ] * X [ i ] ;
     }
   Print ( " sumY = " , DoubleToStr ( sumY , 8 ) , " sumX = " , DoubleToStr ( sumX , 8 ) , " sumXY = " , DoubleToStr ( sumXY , 8 ) , " sumX2 = " , DoubleToStr ( sumX2 , 8 )) ;
   Print ( " sumXY*dN-sumX*sumY = " , DoubleToStr ( sumXY * dN - sumX * sumY , 8 )) ;    
   Print ( " sumX2*dN-sumX*sumX = " , DoubleToStr ( sumX2 * dN - sumX * sumX , 8 )) ;    
 
   B = ( sumXY * N - sumX * sumY ) / ( sumX2 * N - sumX * sumX ) ;
   A = ( sumY - sumX * B ) / N ;
}

Bunun gibi bir şey alın:

ilk arama
toplamY = 11.98130000 toplamX = 7299840060.00000000 toplamXY = 14576928951.87000100 toplamX2 = 8881277483596863500.00000000
toplamXY*dN-toplamX*toplamY = 0.34199524
sumX2*dN-sumX*sumX = 376832.00000000
A = -1102.16914108 B = 0.00000091
ikinci arama
toplamY = 11.98130000 toplamX = 7299840060.00000000 toplamXY = 14576928951.87000300 toplamX2 = 8881277483596864500.00000000
toplamXY*dN-toplamX*toplamY = 0.34202576
sumX2*dN-sumX*sumX = 385024.00000000
A = -1078.77267965 B = 0.00000089

Bu, bilgisayar hesaplamalarının ve yuvarlamanın başka bir tuzağıdır. Bir yandan, kendim böyle bir komisyon beklemiyordum, ancak diğer yandan, iki dizi değerin (X ve Y) değerler sırasında çok fazla farkı olduğunda böyle bir fark oldukça anlaşılabilir.

Neden: