English Русский 中文 Español 日本語 Português
preview
Datenwissenschaft und maschinelles Lernen (Teil 11): Naïve Bayes, Wahrscheinlichkeitsrechnung im Handel

Datenwissenschaft und maschinelles Lernen (Teil 11): Naïve Bayes, Wahrscheinlichkeitsrechnung im Handel

MetaTrader 5Handelssysteme | 26 April 2023, 11:20
256 0
Omega J Msigwa
Omega J Msigwa

Vierter Hauptsatz der Thermodynamik: Wenn die Erfolgswahrscheinlichkeit nicht fast eins ist, dann ist sie verdammt nahe null.

David J. Rose

Einführung

Der Naïve Bayes-Klassifikator ist ein probabilistischer Algorithmus, der beim maschinellen Lernen für Klassifizierungsaufgaben verwendet wird. Sie basiert auf dem Bayes-Theorem, mit dem die Wahrscheinlichkeit einer Hypothese anhand der verfügbaren Beweise berechnet wird. Dieser probabilistische Klassifikator ist ein einfacher, aber effektiver Algorithmus für verschiedene Situationen. Dabei wird davon ausgegangen, dass die für die Klassifizierung verwendeten Merkmale unabhängig voneinander sind. Zum Beispiel: Wenn Sie möchten, dass dieses Modell Menschen (männlich und weiblich) anhand von Größe, Fußgröße, Gewicht und Schulterlänge klassifiziert, behandelt dieses Modell alle diese Variablen als unabhängig voneinander. In diesem Fall geht es nicht einmal davon aus, dass Fußgröße und Größe bei einem Menschen zusammenhängen.

Da sich dieses Modell nicht darum kümmert, die Muster zwischen den unabhängigen Variablen zu verstehen, denke ich, dass wir einen Versuch wagen sollten, es zu nutzen, um fundierte Handelsentscheidungen zu treffen. Ich glaube, dass im Handelsbereich ohnehin niemand die Muster vollständig versteht, also schauen wir mal, wie sich Naïve Bayes schlägt.


Rufen wir also kurzerhand die Modellinstanz auf und verwenden sie sofort. Wir werden später erörtern, woraus dieses Modell besteht.

Vorbereiten der Trainingsdaten

Für dieses Beispiel habe ich 5 Indikatoren ausgewählt, die meisten von ihnen sind Oszillatoren und Volumina, da ich denke, dass sie gute Klassifizierungsvariablen darstellen. Außerdem haben sie eine endliche Menge, was sie gut für die Normalverteilung macht, die eine der Ideen im Kern dieses Algorithmus ist. Sie sind jedoch nicht auf diese Indikatoren beschränkt, Sie können also auch andere Indikatoren und Daten verwenden, die Sie bevorzugen.

Das Wichtigste zuerst:

matrix Matrix(TrainBars, 6);
int handles[5];

double buffer[];
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Preparing Data
   handles[0] = iBearsPower(Symbol(),TF, bears_period);
   handles[1] = iBullsPower(Symbol(),TF, bulls_period);
   handles[2] = iRSI(Symbol(),TF,rsi_period, rsi_price);
   handles[3] = iVolumes(Symbol(),TF,VOLUME_TICK);
   handles[4] = iMFI(Symbol(),TF,mfi_period,VOLUME_TICK );

//---   
   vector col_v;   
   for (ulong i=0; i<5; i++) //Independent vars
     { 
       CopyBuffer(handles[i],0,0,TrainBars, buffer);
       col_v = matrix_utils.ArrayToVector(buffer);
       
       Matrix.Col(col_v, i);
     }     
//-- Target var
   vector open, close;
   col_v.Resize(TrainBars);

   close.CopyRates(Symbol(),TF, COPY_RATES_CLOSE,0,TrainBars);
   open.CopyRates(Symbol(),TF, COPY_RATES_OPEN,0,TrainBars);

   for (int i=0; i<TrainBars; i++)
      {
         if (close[i] > open[i]) //price went up
            col_v[i] = 1;
         else 
            col_v[i] = 0;
      }
   
   Matrix.Col(col_v, 5); //Adding independent variable to the last column of matrix   
//---

Die Variablen TF, bears_period usw. sind durch die Eingabe definierte Variablen, die sich oben im obigen Code befinden:

Da es sich um überwachtes Lernen handelt, musste ich die Zielvariable erfinden, die Logik ist einfach. Wenn der Schlusskurs über dem Eröffnungskurs lag, wird die Zielvariable auf die Klasse 1 gesetzt, andernfalls ist die Klasse 0. Auf diese Weise wurde die Zielvariable festgelegt. Nachfolgend finden Sie einen Überblick über das Aussehen der Matrix mit den Daten:

CS      0       13:21:15.457    Naive Bayes Test (EURUSD,H1)    "Bears"           "Bulls"        "Rsi"      "Volumes" "MFI"     "Target Var"
CS      0       13:21:15.457    Naive Bayes Test (EURUSD,H1)    [-3.753148029472797e-06,0.008786246851970603,67.65238281791684,13489,55.24611392389958,0]
CS      0       13:21:15.457    Naive Bayes Test (EURUSD,H1)    [-0.002513216984025402,0.005616783015974569,50.29835423473968,12226,49.47293811405203,1]
CS      0       13:21:15.457    Naive Bayes Test (EURUSD,H1)    [-0.001829900272021678,0.0009700997279782353,47.33479153312328,7192,46.84320886771249,1]
CS      0       13:21:15.457    Naive Bayes Test (EURUSD,H1)    [-0.004718485947447171,-0.0001584859474472733,39.04848493977027,6267,44.61564654651691,1]
CS      0       13:21:15.457    Naive Bayes Test (EURUSD,H1)    [-0.004517273669240485,-0.001367273669240276,45.4127802340401,3867,47.8438816641815,0]

Ich beschloss dann, die Daten in Verteilungsdiagrammen zu visualisieren, um zu sehen, ob sie der Wahrscheinlichkeitsverteilung folgen:

Verteilung des Bears Indikator Verteilung des Bulls Indikators Normalverteilung des RSI Normalverteilung des MFI Normalverteilung des Volumens

Für diejenigen, die die verschiedenen Arten von Wahrscheinlichkeitsverteilungen verstehen wollen, gibt es einen ganzen Artikel, der hier verlinkt ist.

Wenn man sich die Korrelationskoeffizientenmatrix aller unabhängigen Variablen genauer ansieht:

   string header[5] = {"Bears","Bulls","Rsi","Volumes","MFI"};

   matrix vars_matrix = Matrix; //Independent variables only
   matrix_utils.RemoveCol(vars_matrix, 5); //remove target variable
   
   ArrayPrint(header);
   Print(vars_matrix.CorrCoef(false));

Ausgabe:

CS      0       13:21:15.481    Naive Bayes Test (EURUSD,H1)    "Bears"   "Bulls"   "Rsi"     "Volumes" "MFI"    
CS      0       13:21:15.481    Naive Bayes Test (EURUSD,H1)    [[1,0.7784600081627714,0.8201955846987788,-0.2874457184671095,0.6211980865273238]
CS      0       13:21:15.481    Naive Bayes Test (EURUSD,H1)     [0.7784600081627714,1,0.8257210032763984,0.2650418244580489,0.6554288778228361]
CS      0       13:21:15.481    Naive Bayes Test (EURUSD,H1)     [0.8201955846987788,0.8257210032763984,1,-0.01205084357067248,0.7578863565293196]
CS      0       13:21:15.481    Naive Bayes Test (EURUSD,H1)     [-0.2874457184671095,0.2650418244580489,-0.01205084357067248,1,0.0531475992791923]
CS      0       13:21:15.481    Naive Bayes Test (EURUSD,H1)     [0.6211980865273238,0.6554288778228361,0.7578863565293196,0.0531475992791923,1]]

Sie werden feststellen, dass mit Ausnahme der Volumina Korrelation zum Rest, alle Variablen sind stark miteinander korreliert, einige zufällig zum Beispiel RSI gegen beide Bullen und Bären mit einer Korrelation von etwa 82%. Auch Volumen und MFI haben etwas gemeinsam, woraus sie bestehen, nämlich Volumen, sodass sie zu 62% korreliert sind. Da Gaussian Naïve Bayes sich nicht um all diese Dinge kümmert, sollten wir weitermachen, aber ich hielt es für eine gute Idee, die Variablen zu überprüfen und zu analysieren.

Training des Modells

Das Training des Gaussian Naïve Bayes ist einfach und dauert nur sehr kurz. Sehen wir uns zunächst an, wie man es richtig macht:

     Print("\n---> Training the Model\n");
     
     matrix x_train, x_test;
     vector y_train, y_test;
     
     matrix_utils.TrainTestSplitMatrices(Matrix,x_train,y_train,x_test,y_test,0.7,rand_state);
     
//--- Train  
     gaussian_naive = new CGaussianNaiveBayes(x_train,y_train);  //Initializing and Training the model    
     vector train_pred = gaussian_naive.GaussianNaiveBayes(x_train); //making predictions on trained data
     vector c= gaussian_naive.classes; //Classes in a dataset that was detected by mode    
     metrics.confusion_matrix(y_train,train_pred,c);  //analyzing the predictions in confusion matrix
//---

Die Funktion TrainTestSplitMatrices teilt die Daten in x Trainings- und x Testmatrizen und ihre jeweiligen Zielvektoren auf. Genau wie train_test_split in sklearn python. Die Funktion geht im Kern folgendermaßen:

void CMatrixutils::TrainTestSplitMatrices(matrix &matrix_,matrix &x_train,vector &y_train,matrix &x_test, vector &y_test,double train_size=0.7,int random_state=-1)

Standardmäßig werden 70 Prozent der Daten als Trainingsdaten und der Rest als Testdaten verwendet. Lesen Sie mehr über diese Aufteilung.

Was Viele wohl in dieser Funktion verwirrend finden, ist die Variable random_state. Menschen der Python ML-Community entscheiden sich oft für random_state = 42, obwohl jede Zahl gewählt werden könnte. Sie soll nur sicherstellen, dass bei jeder Generierung der randomisierten / gemischt Matrix jedes Mal die gleiche erstellt wird, damit so das Debuggen einfacher ist, da so Random-Seed für die Generierung von Zufallszahlen für das Mischen der Zeilen in einer Matrix setzt festlegt.

Sie werden bemerken, dass die von dieser Funktion erhaltenen Ausgabematrizen nicht in der Standardreihenfolge sind, die sie hatten. Es gibt mehrere Diskussionen über die Wahl dieser 42 Nummer.

Nachfolgend sehen Sie die Ausgabe dieses Codeblocks:

CS      0       14:33:04.001    Naive Bayes Test (EURUSD,H1)    ---> Training the Model
CS      0       14:33:04.001    Naive Bayes Test (EURUSD,H1)    
CS      0       14:33:04.002    Naive Bayes Test (EURUSD,H1)    ---> GROUPS [0,1]
CS      0       14:33:04.002    Naive Bayes Test (EURUSD,H1)    
CS      0       14:33:04.002    Naive Bayes Test (EURUSD,H1)    ---> Prior_proba [0.5457142857142857,0.4542857142857143] Evidence [382,318]

CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    Confusion Matrix
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    [[236,146]
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)     [145,173]]
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    Classification Report
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    _    Precision  Recall  Specificity  F1 score  Support
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    0.0    0.62     0.62     0.54       0.62     382.0
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    1.0    0.54     0.54     0.62       0.54     318.0
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    Accuracy                                   0.58
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    Average   0.58    0.58    0.58      0.58    700.0
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    W Avg     0.58    0.58    0.58      0.58    700.0
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    

Das trainierte Modell ist laut dem Klassifizierungsbericht der Konfusionsmatrix zu 58% genau. Aus diesem Bericht lässt sich vieles ablesen, z. B. die Genauigkeit, die angibt, wie genau jede Klasse klassifiziert wurde (mehr darüber hier). Grundsätzlich schien die Klasse 0 besser klassifiziert zu werden als die Klasse 1, was sinnvoll ist, weil das Modell sie besser vorhergesagt hat als die andere Klasse 1, ganz zu schweigen von der Prioritätswahrscheinlichkeit, die die Primärwahrscheinlichkeit oder die Wahrscheinlichkeit auf den ersten Blick im Daten ist. In diesen Daten sind die vorherigen Wahrscheinlichkeiten:

Prior_proba [0.5457142857142857,0.4542857142857143] Evidence [382,318]. Diese Vorabwahrscheinlichkeit wird wie folgt berechnet:

Prior Proba = Evidence/ Gesamtzahl der Ereignisse/Ergebnisse

In diesem Fall Prior Proba [382/700, 318/700]. Erinnern Sie sich: 700 ist die Größe der Trainingsdaten, den wir haben, nachdem wir 70% der 1000 Daten als Trainingsdaten verwenden.

Das Gaußsche Naïve-Bayes-Modell betrachtet zunächst die Wahrscheinlichkeiten des Auftretens von Klassen in den Daten und verwendet diese dann, um zu erraten, was in der Zukunft passieren könnte, was auf der Grundlage von Evidenz berechnet wird. Die Klasse mit der höheren Evidenz, die zu einer höheren Wahrscheinlichkeit führt als die andere, wird vom Algorithmus beim Trainieren und Testen bevorzugt. Das macht doch Sinn, oder? Dies ist einer der Nachteile dieses Algorithmus, denn wenn eine Klasse in den Trainingsdaten nicht vorkommt, geht das Modell davon aus, dass diese Klasse nicht existiert, sodass es ihr eine Wahrscheinlichkeit von Null gibt, was bedeutet, dass sie in den Testdaten oder irgendwann in der Zukunft nicht vorhergesagt werden wird.


Prüfung des Modells

Auch das Testen des Modells ist einfach. Sie müssen lediglich die neuen Daten in die Funktion GaussianNaiveBayes einfügen, die zu diesem Zeitpunkt bereits über die Parameter des trainierten Modells verfügt.

//--- Test   
     Print("\n---> Testing the model\n");     
     vector test_pred = gaussian_naive.GaussianNaiveBayes(x_test); //giving the model test data to predict and obtain predictions to a vector     
     metrics.confusion_matrix(y_test,test_pred, c); //analyzing the tested model

Ausgaben:

CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    ---> Testing the model
CS      0       14:33:04.294    Naive Bayes Test (EURUSD,H1)    
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    Confusion Matrix
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    [[96,54]
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)     [65,85]]
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    Classification Report
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    _    Precision  Recall  Specificity  F1 score  Support
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    0.0    0.60     0.64     0.57       0.62     150.0
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    1.0    0.61     0.57     0.64       0.59     150.0
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    Accuracy                                   0.60
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    Average   0.60    0.60    0.60      0.60    300.0
CS      0       14:33:04.418    Naive Bayes Test (EURUSD,H1)    W Avg     0.60    0.60    0.60      0.60    300.0

Großartig, also hat das Modell mit den Testdaten etwas besser abgeschnitten, mit einer Genauigkeit von 60%, 2% mehr als mit den Trainingsdaten, das sind gute Nachrichten.


Das Gaußsche Naïve-Bayes-Modell im Strategy Tester 

Die Verwendung von Modellen des maschinellen Lernens auf dem Strategietester erbringt oft keine guten Leistungen, nicht weil sie keine Vorhersagen machen könnten, sondern weil wir uns in der Regel das Gewinndiagramm auf dem Strategietester ansehen. Wenn ein maschinelles Lernmodell erahnen kann, wohin sich der Markt als Nächstes bewegt, bedeutet das nicht zwangsläufig, dass man damit Geld verdienen kann, vor allem nicht mit der einfachen Logik, die ich bei der Sammlung und Aufbereitung unserer Daten verwendet habe. Die Datensätze wurden auf jedem Balken mit TF, gemäß der Eingabe gleich PERIOD_H1 (eine Stunde) gesammelt.

   close.CopyRates(Symbol(),TF, COPY_RATES_CLOSE,0,TrainBars);
   open.CopyRates(Symbol(),TF, COPY_RATES_OPEN,0,TrainBars);

Ich habe 1000 Balken des einstündigen Zeitrahmen gesammelt und ihre Indikatorwerte als unabhängige Variablen gelesen. Ich habe dann die Zielvariablen erstellt, indem ich geschaut habe, ob es eine Aufwärtskerze war, dann setzt unser EA setzt die Klasse 1, ansonsten die Klasse 0. Als ich die Funktion für den Handel entwickelt habe, habe ich dies berücksichtigt. Da unser Modell die nächste Kerze vorhersagen wird, habe ich bei jeder neuen Kerze Positionen eröffnet und die vorherigen geschlossen. Im Grunde wird unser EA bei jedem Signal in jedem Balken handeln.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if (!train_state)
      TrainTest();
  
    train_state = true;   
     
//---
   vector v_inputs(5); //5 independent variables
   double buff[1];  //current indicator value
    
   for (ulong i=0; i<5; i++) //Independent vars
     { 
       CopyBuffer(handles[i],0,0,1, buff);
       
       v_inputs[i] = buff[0];
     }

//---
   MqlTick ticks;
   SymbolInfoTick(Symbol(), ticks);

   int signal = -1;
   double min_volume = SymbolInfoDouble(Symbol(), SYMBOL_VOLUME_MIN);
   
   if (isNewBar())
     { 
       signal = gaussian_naive.GaussianNaiveBayes(v_inputs);       
       Comment("SIGNAL ",signal);    
       CloseAll();
        
        if (signal == 1)
          { 
            if (!PosExist())
              m_trade.Buy(min_volume, Symbol(), ticks.ask, 0 , 0,"Naive Buy");
          }
        else if (signal == 0)
          {
            if (!PosExist())
              m_trade.Sell(min_volume, Symbol(), ticks.bid, 0 , 0,"Naive Sell");
          }
     } 
  }

Damit diese Funktion sowohl im Live-Handel als auch im Strategietester funktioniert, musste ich die Logik ein wenig ändern. Das Abrufen der Indikatorwerte mit CopyBuffer() und das Training befinden sich jetzt innerhalb der Funktion TrainTest(). Diese Funktion wird einmal bei der Funktion OnTick ausgeführt. Sie können sie öfter ausführen lassen, um das Modell sehr oft zu trainieren, aber das überlasse ich Ihnen zur Übung. 

Da die Funktion Init nicht die geeignete Funktion für all diese Methoden CopyBuffer und CopyRates ist (sie geben beim Strategy Tester Nullwerte zurück, wenn sie auf diese Weise verwendet werden), wird nun alles in die Funktion TrainTest() verschoben .

int OnInit()
  {    
   handles[0] = iBearsPower(Symbol(),TF, bears_period);
   handles[1] = iBullsPower(Symbol(),TF, bulls_period);
   handles[2] = iRSI(Symbol(),TF,rsi_period, rsi_price);
   handles[3] = iVolumes(Symbol(),TF,VOLUME_TICK);
   handles[4] = iMFI(Symbol(),TF,mfi_period,VOLUME_TICK );

//---

   m_trade.SetExpertMagicNumber(MAGIC_NUMBER);
   m_trade.SetTypeFillingBySymbol(Symbol());
   m_trade.SetMarginMode();
   m_trade.SetDeviationInPoints(slippage);

   return(INIT_SUCCEEDED);
  }

Einzeltest: Zeitrahmen 1 Stunde

Ich habe einen Test über zwei Monate vom 1. Januar 2023 bis zum 14. Februar 2023 (gestern) durchgeführt:

Ich habe mich für einen Test über einen so kurzen Zeitraum (2 Monate) entschieden, weil 1000 einstündige Takte keine so lange Trainingszeit sind, fast 41 Tage, damit die Trainingszeit kurz ist und die Tests auch. Da die Funktion TrainTest() wurde auch auf dem Tester ausgeführt. Die Kerzen, mit denen das Modell trainiert wurde, sind 700 Balken. 

Was ist schief gelaufen?

Das Modell hinterließ beim Strategietester einen ersten Eindruck, indem es eine beeindruckende Genauigkeit von 60% bei den Trainingsdaten erzielte.

CS      0       08:30:13.816    Tester  initial deposit 1000.00 USD, leverage 1:100
CS      0       08:30:13.818    Tester  successfully initialized
CS      0       08:30:13.818    Network 80 Kb of total initialization data received
CS      0       08:30:13.819    Tester  Intel Core i5  660 @ 3.33GHz, 6007 MB
CS      0       08:30:13.900    Symbols EURUSD: symbol to be synchronized
CS      0       08:30:13.901    Symbols EURUSD: symbol synchronized, 3720 bytes of symbol info received
CS      0       08:30:13.901    History EURUSD: history synchronization started
....
....
....
CS      0       08:30:14.086    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   ---> Training the Model
CS      0       08:30:14.086    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   
CS      0       08:30:14.086    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   ---> GROUPS [0,1]
CS      0       08:30:14.086    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   
CS      0       08:30:14.086    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   ---> Prior_proba [0.4728571428571429,0.5271428571428571] Evidence [331,369]
CS      0       08:30:14.377    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   Confusion Matrix
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   [[200,131]
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00    [150,219]]
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   Classification Report
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   _    Precision  Recall  Specificity  F1 score  Support
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   0.0    0.57     0.60     0.59       0.59     331.0
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   1.0    0.63     0.59     0.60       0.61     369.0
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   Accuracy                                   0.60
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   Average   0.60    0.60    0.60      0.60    700.0
CS      0       08:30:14.378    Naive Bayes Test (EURUSD,H1)    2023.01.02 01:00:00   W Avg     0.60    0.60    0.60      0.60    700.0

Allerdings konnte er keine profitablen Geschäfte mit der versprochenen Genauigkeit oder auch nur annähernd so genau abschließen. Im Folgenden finden Sie meine Beobachtungen:

  • Die Logik ist irgendwie blind, sie tauscht Quantität gegen Qualität. 713 Abschlüsse im Laufe von zwei Monaten. Kommen Sie, das ist eine ganze Menge an Geschäften. Dies muss in sein Gegenteil umgewandelt werden. Wir müssen dieses Modell auf einem höheren Zeitrahmen trainieren und auf höheren Zeitrahmen handeln, was zu wenigen Qualitätspositionen führt.
  • Die Trainingsbalken müssen für diesen Test reduziert werden, ich möchte das Modell mit aktuellen Daten trainieren.

Um diese zu erreichen, führte ich die Optimierung mit dem Zeitrahmen 6H durch, und kam zu Train Bars = 80, TF = 12 Stunden, um so einen Test laufen zu lassen (2 Monate mit den neuen Parametern). Sehen Sie sich alle Parameter in der *set-Datei an, die am Ende dieses Artikels verlinkt ist.

Diesmal lag die Trainingsgenauigkeit des Gaußsche Naïve-Bayes-Modells bei 58%.

93 Positionen im Laufe von 2 Monaten, das nenne ich eine gesunde Handelsaktivität, im Durchschnitt sind es 2,3 pro Tag. Dieses Mal hat der Gaussian Naïve Bayes EA 63% der Trades profitabel gemacht, ganz zu schweigen von einem Gewinn von etwa 10%.

Nachdem Sie nun gesehen haben, wie Sie das Gaussian-Naïve-Bayes-Modell nutzen können, um fundierte Handelsentscheidungen zu treffen, wollen wir uns ansehen, wie es funktioniert.


Naïve Bayes-Theorie

Nicht zu verwechseln mit dem Gaußschen Naïve Bayes.

Der Algorithmus heißt

  • Naiv, weil er davon ausgeht, dass die Variablen/Merkmale unabhängig sind, was selten der Fall ist
  • Bayes, weil er auf dem Satz von Bayes beruht.

Die Formel für das Bayes-Theorem ist unten angegeben:

Wobei:

P(A|B) = die (bedingte) Wahrscheinlichkeit des Ereignisses A unter der Bedingung, dass B eingetreten ist,

P(B|A) = die (bedingte) Wahrscheinlichkeit des Ereignisses B unter der Bedingung, dass A eingetreten ist, In einfachen Worten: Wahrscheinlichkeit von B, wenn A wahr ist

P(A) = die A-priori-Wahrscheinlichkeit des Ereignisses A der Hypothese vor der Beobachtung einer Evidenz

P(B) = die A-priori-Wahrscheinlichkeit des Ereignisses B der Hypothese vor der Beobachtung einer Evidenz

Diese Begriffe in der Formel mögen auf den ersten Blick verwirrend erscheinen. Sie werden in der Praxis deutlich werden, also bleiben Sie bei mir.

Arbeiten mit dem Klassifikator

Werfen wir einen Blick auf ein einfaches Beispiel: Wetterdaten. Konzentrieren wir uns auf die erste Spalte Vorhersage. Sobald das verstanden ist, ist das Hinzufügen anderer Spalten als unabhängige Variablen genau derselbe Prozess.

Vorhersage Tennis spielen
 Sonnig  No
 Sonnig   No
 Bedeckt  Ja
 Regen  Ja
 Regen  Ja
 Regen  No
 Bedeckt  Ja
 Sonnig  No
 Sonnig  Ja
 Regen   Ja
 Sonnig   Ja
 Bedeckt  Ja
 Bedeckt  Ja
 Regen  No

Nun wollen wir das Gleiche in MetaEditor tun:

void OnStart()
  {
//---
   matrix Matrix = matrix_utils.ReadCsvEncode("weather dataset.csv");
   
   int cols[3] = {1,2,3};
   
   matrix_utils.RemoveMultCols(Matrix, cols); //removing Temperature Humidity and Wind 
   ArrayRemove(matrix_utils.csv_header,1,3); //removing column headers
   
   ArrayPrint(matrix_utils.csv_header);
   Print(Matrix);
   
   matrix x_matrix; vector y_vector;
   
   matrix_utils.XandYSplitMatrices(Matrix, x_matrix, y_vector);
       
  } 

Beachten Sie, dass Naïve Bayes nur für diskrete/nicht-kontinuierliche Variablen geeignet ist. Nicht zu verwechseln mit dem Gaußschen Naïve Bayes-Modell, das wir oben in Aktion gesehen haben und das mit kontinuierlichen Variablen umgehen kann, ist der Fall bei diesem Naïve Bayes-Modell anders. Nachfolgend sehen Sie die Ausgabe des obigen Vorgangs

CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)   "Outlook" "Play"   
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)   [[0,0]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [0,0]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [1,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [2,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [2,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [2,0]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [1,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [0,0]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [0,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [2,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [0,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [1,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [1,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)    [2,0]]

Lassen Sie uns also die vorherige Wahrscheinlichkeit in unserem Naïve Bayes-Klassenkonstruktor ermitteln:

CNaiveBayes::CNaiveBayes(matrix &x_matrix, vector &y_vector)
 {
   XMatrix.Copy(x_matrix);
   YVector.Copy(y_vector); 
   
   classes = matrix_utils.Classes(YVector);
   
   c_evidence.Resize((ulong)classes.Size());
   
   n = YVector.Size();
   
   if (n==0) { Print("--> n == 0 | Naive Bayes class failed"); return; }
   
//---

   vector v = {};
   for (ulong i=0; i<c_evidence.Size(); i++)
       {
         v = matrix_utils.Search(YVector,(int)classes[i]);
         
         c_evidence[i] = (int)v.Size();
       }

//---
     
   c_prior_proba.Resize(classes.Size());
   
   for (ulong i=0; i<classes.Size(); i++)
      c_prior_proba[i] = c_evidence[i]/(double)n;
  
 
   #ifdef DEBUG_MODE
      Print("---> GROUPS ",classes);
      Print("Prior Class Proba ",c_prior_proba,"\nEvidence ",c_evidence);
   #endif   

 }

Ausgaben:

CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)   ---> GROUPS [0,1]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)   Prior Class Proba [0.3571428571428572,0.6428571428571429]
CS      0       12:59:37.386    Naive Bayes theory script (EURUSD,H1)   Evidence [5,9]

Die vorherige Wahrscheinlichkeit von [Nein, Ja] ist ungefähr [0,36, 0,64].

Angenommen, Sie wollen wissen, wie hoch die Wahrscheinlichkeit ist, dass eine Person an einem sonnigen Tag Tennis spielt, dann werden Sie Folgendes tun;

P(Ja | Sonnig) = P(Sonnig | Ja) * P(Ja) / P(Sonnig) 

Mehr Details in einfacher Sprache:

Die Wahrscheinlichkeit, dass jemand an einem sonnigen Tag Tennis spielt = wie oft (als Wahrscheinlichkeitswert) war es sonnig und irgendein Idiot hat Tennis gespielt * wie oft (als Wahrscheinlichkeitswert) haben Menschen Tennis gespielt / wie oft (als Wahrscheinlichkeitswert) gab es einen sonniger Tag im Allgemeinen.

P(Sonnig | Ja) = 2/9

P(Ja) = 0,64

P(Sonnig ) = 5/14 = 0,357

also schließlich das P(Ja | Sonnig) = 0,333 x 0,64 / 0,357 = 0,4

Wie sieht es mit der Wahrscheinlichkeit von (Nein| Sonnig) aus: Wir können es berechnen, indem wir 1 - Wahrscheinlichkeit für Ja = 1 - 0,5972 = 0,4027 nehmen als Abkürzung, aber schauen wir uns das an:

P(Nein|Sonnig) = (3/5) x 0,36 / (0,357) = 0,6

Nachstehend finden Sie den entsprechenden Code:

vector CNaiveBayes::calcProba(vector &v_features)
 {
    vector proba_v(classes.Size()); //vector to return
    
    if (v_features.Size() != XMatrix.Cols())
      {
         printf("FATAL | Can't calculate probability,  features columns size = %d is not equal to XMatrix columns =%d",v_features.Size(),XMatrix.Cols());
         return proba_v;
      }

//---
    
    vector v = {}; 
    
    for (ulong c=0; c<classes.Size(); c++)
      {
        double proba = 1;
          for (ulong i=0; i<XMatrix.Cols(); i++)
            {
                v = XMatrix.Col(i);
                
                int count =0;
                for (ulong j=0; j<v.Size(); j++)
                  {
                     if (v_features[i] == v[j] && classes[c] == YVector[j])
                        count++;
                  }
                  
                proba *= count==0 ? 1 : count/(double)c_evidence[c]; //do not calculate if there isn't enough evidence'
            }
          
        proba_v[c] = proba*c_prior_proba[c];
     }
     
    return proba_v;
 }

Der von dieser Funktion bereitgestellte Wahrscheinlichkeitsvektor für Sonnig ist:

2023.02.15 16:34:21.519 Naive Bayes theory script (EURUSD,H1)   Probabilities [0.6,0.4]

Genau das, was wir erwartet haben, aber machen wir keinen Fehler, diese Funktion gibt uns keine Wahrscheinlichkeiten. Lassen Sie mich erklären. Wenn es nur zwei Klassen in dem Daten gibt, den wir in diesem Szenario vorherzusagen versuchen, ist das Ergebnis eine Wahrscheinlichkeit, aber ansonsten müssen die Ausgaben dieser Funktion in Wahrscheinlichkeitsbedingungen validiert werden. Das zu erreichen, ist einfach:

Nehmen wir die Summe des Vektors, der aus dieser Funktion hervorgegangen ist, und dividieren dann jedes Element durch die Gesamtsumme. Der verbleibende Vektor wird die realen Wahrscheinlichkeitswerte sein, die, wenn sie addiert werden, gleich eins sind.

probability_v = v[i]/probability_v.Sum()

Dieser kleine Prozess wird innerhalb der Funktion NaiveBayes() durchgeführt, die die Ergebnisklasse oder die Klasse mit der höchsten Wahrscheinlichkeit von allen vorhersagt:

int CNaiveBayes::NaiveBayes(vector &x_vector)
 {   
   vector v = calcProba(x_vector);
   
   double sum = v.Sum();
   
   for (ulong i=0; i<v.Size(); i++) //converting the values into probabilities
      v[i] = NormalizeDouble(v[i]/sum,2);       
   
   vector p = v;
   
   #ifdef   DEBUG_MODE
      Print("Probabilities ",p);
   #endif 
   
   return((int)classes[p.ArgMax()]);
 }

Nun, das war's. Der Naïve Bayes ist ein einfacher Algorithmus. Nun wollen wir uns dem Gaußschen Naïve Bayes zuwenden, den wir zu Beginn dieses Artikels verwendet haben.


Gaußscher Naïve Bayes

Der Gaußsche Naïve Bayes geht davon aus, dass die Merkmale einer Normalverteilung folgen, d. h. wenn die Prädiktoren kontinuierliche statt diskrete Variablen annehmen, wird davon ausgegangen, dass diese Werte aus der Gaußschen Verteilung gezogen werden.

Eine kurze Wiederholung zur Normalverteilung

Die Normalverteilung ist eine kontinuierliche Wahrscheinlichkeitsverteilung, die um ihren Mittelwert symmetrisch ist, wobei sich die meisten Beobachtungen um die zentrale Spitze gruppieren und die Wahrscheinlichkeiten für Werte, die weiter vom Mittelwert entfernt sind, in beide Richtungen gleichmäßig abnehmen. Extremwerte in beiden Enden der Verteilung sind ebenfalls unwahrscheinlich.

Normalverteilungskurve

Diese glockenförmige Wahrscheinlichkeitskurve ist so aussagekräftig, dass sie zu den nützlichen statistischen Analyseinstrumenten gehört. Sie zeigt, dass die Wahrscheinlichkeit, etwas zu finden, das eine Standardabweichung vom Mittelwert abweicht, ungefähr 34% beträgt, und 34%, etwas auf der anderen Seite der Glockenkurve zu finden. Das bedeutet, dass die Wahrscheinlichkeit, einen Wert zu finden, der auf beiden Seiten zusammen einen Standard vom Mittelwert entfernt ist, etwa 68% beträgt. Diejenigen, die den Mathematikunterricht geschwänzt haben, sollten hier weiterlesen

Aus dieser Normalverteilung/Gaußschen Verteilung wollen wir die Wahrscheinlichkeitsdichte ermitteln. Sie wird nach der folgenden Formel berechnet.

Wahrscheinlichkeitsdichtefunktion

Wobei:

 μ = Mittelwert

𝜎 = Standardabweichung

x = Eingabewert  

Ok, da der Gaußsche Naïve Bayes davon abhängt, wollen wir ihn codieren.

class CNormDistribution
  {

public:
   
   double m_mean; //Assign the value of the mean
   double m_std;  //Assign the value of Variance
   
                     CNormDistribution(void);
                    ~CNormDistribution(void);
                    
                     double PDF(double x); //Probability density function
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

CNormDistribution::CNormDistribution(void)
 {
   
 }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

CNormDistribution::~CNormDistribution(void)
 {
   ZeroMemory(m_mean);
   ZeroMemory(m_std);
 }
 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

double CNormDistribution::PDF(double x)
 {
   double nurm = MathPow((x - m_mean),2)/(2*MathPow(m_std,2));
   nurm = exp(-nurm);
   
   double denorm = 1.0/(MathSqrt(2*M_PI*MathPow(m_std,2)));
      
  return(nurm*denorm);
 }


Erstellen des Gauß-Naïve-Bayes-Modells

Der Klassenkonstruktor von Gaussian Naïve Bayes sieht ähnlich aus wie der von Naïve Bayes. Der Konstruktorcode muss hier nicht gezeigt und erklärt werden. Im Folgenden finden Sie unsere Hauptfunktion, die für die Berechnung der Wahrscheinlichkeit zuständig ist.

vector CGaussianNaiveBayes::calcProba(vector &v_features)
 {    
    vector proba_v(classes.Size()); //vector to return
    
    if (v_features.Size() != XMatrix.Cols())
      {
         printf("FATAL | Can't calculate probability, features columns size = %d is not equal to XMatrix columns =%d",v_features.Size(),XMatrix.Cols());
         return proba_v;
      }

//---
    vector v = {}; 
    
    for (ulong c=0; c<classes.Size(); c++)
      {
        double proba = 1;
          for (ulong i=0; i<XMatrix.Cols(); i++)
            {
                v = XMatrix.Col(i);                
                int count =0;
                vector calc_v = {};
                
                for (ulong j=0; j<v.Size(); j++)
                  {
                     if (classes[c] == YVector[j])
                       {
                         count++;
                         calc_v.Resize(count);
                         
                         calc_v[count-1] = v[j];
                       }
                  } 
                
                norm_distribution.m_mean = calc_v.Mean(); //Assign these to Gaussian Normal distribution
                norm_distribution.m_std = calc_v.Std();   
                
                #ifdef DEBUG_MODE
                  printf("mean %.5f std %.5f ",norm_distribution.m_mean,norm_distribution.m_std);
                #endif 
                
                proba *= count==0 ? 1 : norm_distribution.PDF(v_features[i]); //do not calculate if there isn't enought evidence'
            }
          
        proba_v[c] = proba*c_prior_proba[c]; //Turning the probability density into probability
        
        #ifdef DEBUG_MODE
         Print(">> Proba ",proba," prior proba ",c_prior_proba);
        #endif 
     }
     
    return proba_v;
 }

Sehen wir uns an, wie sich dieses Modell in der Praxis bewährt.

Verwendung des Genderdaten.

Höhe(ft)
 Gewicht (lbs)  Schuhgröße (Zoll) Person(0 männlich, 1 weiblich)
 6  180  12   0
 5.92  190   11   0
 5.58  170   12   0
 5.92  165   10   0
 5  100   6   1
 5.5  150   8   1
 5.42  130   7   1
 5.75  150   9   1
//--- Gaussian naive bayes
   Matrix = matrix_utils.ReadCsv("gender dataset.csv");
   
   ArrayPrint(matrix_utils.csv_header);
   Print(Matrix);
   
   matrix_utils.XandYSplitMatrices(Matrix, x_matrix, y_vector);   
   gaussian_naive = new CGaussianNaiveBayes(x_matrix, y_vector);      

Ausgabe:

CS      0       18:52:18.653    Naive Bayes theory script (EURUSD,H1)   ---> GROUPS [0,1]
CS      0       18:52:18.653    Naive Bayes theory script (EURUSD,H1)   
CS      0       18:52:18.653    Naive Bayes theory script (EURUSD,H1)   ---> Prior_proba [0.5,0.5] Evidence [4,4]

Da 4 von 8 Personen männlich und die restlichen 4 weiblich waren, besteht eine 50:50-Chance, dass das Modell in erster Linie einen Mann oder eine Frau vorhersagt.

Versuchen wir das Modell mit diesen neuen Daten einer Person mit einer Größe von 5,3, einem Gewicht von 140 und einer Fußgröße von 7,5. Wir beide wissen, dass diese Person höchstwahrscheinlich eine Frau ist.

   vector person = {5.3, 140, 7.5};
   
   Print("The Person is a ",gaussian_naive.GaussianNaiveBayes(person));

Ausgabe:

2023.02.15 19:14:40.424 Naive Bayes theory script (EURUSD,H1)   The Person is a 1

Gut, es wurde richtig vorhergesagt, dass es sich um eine weibliche Person handelt.

Das Testen des Gaußschen Naïven Bayes-Modells ist relativ einfach. Übergeben wir einfach die Matrix, mit der es trainiert wurde, und messen die Genauigkeit der Vorhersagen anhand der Konfusionsmatrix.

CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   Confusion Matrix
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   [[4,0]
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)    [0,4]]
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   Classification Report
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   _    Precision  Recall  Specificity  F1 score  Support
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   0.0    1.00     1.00     1.00       1.00     4.0
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   1.0    1.00     1.00     1.00       1.00     4.0
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   Accuracy                                   1.00
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   Average   1.00    1.00    1.00      1.00    8.0
CS      0       19:21:22.951    Naive Bayes theory script (EURUSD,H1)   W Avg     1.00    1.00    1.00      1.00    8.0

Ja, die Trainingsgenauigkeit beträgt 100%, unser Modell kann erkennen, ob eine Person männlich oder weiblich ist, wenn alle Daten als Trainingsdaten verwendet wurden.


Vorteile von Naïve & Gaussian Bayes Klassifikatoren

  • Sie sind einer der einfachsten und schnellsten Algorithmen für maschinelles Lernen, die zur Klassifizierung von Datensätzen verwendet werden.
  • Sie können sowohl für die binäre als auch für die Mehrklassen-Klassifizierung verwendet werden.
  • So einfach sie auch sind, sie leisten oft gute Arbeit bei der Klassifizierung mehrerer Klassen, die die meisten Algorithmen
  • Es ist die beliebteste Wahl für Textklassifizierungsprobleme

Nachteile dieser Klassifikatoren.

Naïve Bayes ist zwar ein einfacher und effektiver Algorithmus für maschinelles Lernen zur Klassifizierung, hat aber einige Einschränkungen und Nachteile, die berücksichtigt werden sollten.

Naïve Bayes.

  1. Vermutung der Unabhängigkeit: Naïve Bayes geht davon aus, dass alle Merkmale unabhängig voneinander sind, was in der Praxis nicht immer der Fall ist. Diese Annahme kann zu einer Verschlechterung der Klassifizierungsgenauigkeit führen, wenn die Merkmale stark voneinander abhängig sind.
  2. Zu wenig Daten: Naïve Bayes beruht auf dem Vorhandensein einer ausreichenden Anzahl von Trainingsbeispielen für jede Klasse, um die Klassenprioritäten und bedingten Wahrscheinlichkeiten genau zu schätzen. Wenn der Datensatz zu klein ist, können die Schätzungen ungenau sein und zu einer schlechten Klassifizierungsleistung führen.
  3. Empfindlichkeit gegenüber irrelevanten Merkmalen: Naïve Bayes behandelt alle Merkmale gleich, unabhängig von ihrer Relevanz für die Klassifizierungsaufgabe. Dies kann zu einer schlechten Klassifizierungsleistung führen, wenn irrelevante Merkmale in den Datensatz aufgenommen werden. Es ist eine unbestreitbare Tatsache, dass einige Merkmale in einem Datensatz wichtiger sind als andere.
  4. Unfähigkeit, mit kontinuierlichen Variablen umzugehen: Naïve Bayes geht davon aus, dass alle Merkmale diskret oder kategorisiert sind, und kann kontinuierliche Variablen nicht direkt verarbeiten. Um Naïve Bayes mit kontinuierlichen Variablen zu verwenden, müssen die Daten diskretisiert werden, was zu Informationsverlusten und einer geringeren Klassifizierungsgenauigkeit führen kann.
  5. Begrenzte Ausdruckskraft: Naïve Bayes kann nur lineare Entscheidungsgrenzen modellieren, was für komplexere Klassifizierungsaufgaben möglicherweise nicht ausreicht. Dies kann zu einer schlechten Leistung führen, wenn die Entscheidungsgrenze nicht linear ist.
  6. Ungleichgewicht der Klassen: Naïve Bayes kann schlecht funktionieren, wenn die Verteilung der Beispiele über die Klassen sehr unausgewogen ist, da es zu verzerrten Klassenprioritäten und einer schlechten Schätzung der bedingten Wahrscheinlichkeiten für die Minderheitsklasse führen kann. Wenn die Evidenz nicht ausreicht, wird die Klasse nicht vorhergesagt - Punkt.

Gaußsche Naïve Bayes.

Die Gaußsche Naïve Bayes-Methode teilt die oben genannten Nachteile aber noch zwei weitere:

  1. Empfindlich gegenüber Ausreißern: Der Gaußsche Naïve Bayes geht davon aus, dass die Merkmale normalverteilt sind, was bedeutet, dass Extremwerte oder Ausreißer einen erheblichen Einfluss auf die Schätzungen von Mittelwert und Varianz haben können. Dies kann zu einer schlechten Klassifizierungsleistung führen, wenn der Datensatz Ausreißer enthält.
  2. Nicht geeignet für Merkmale mit starken Rändern: Der Gaußsche Naïve Bayes geht davon aus, dass die Merkmale eine Normalverteilung mit endlicher Varianz haben. Wenn die Merkmale starke Rändern haben, wie z. B. eine Cauchy-Verteilung, kann der Algorithmus nicht gut funktionieren.

Schlussfolgerung

Damit ein Modell des maschinellen Lernens im Strategietester Ergebnisse liefert, muss man nicht nur das Modell trainieren, sondern auch die Leistung verbessern und gleichzeitig sicherstellen, dass man am Ende eine aufwärtsgerichtete Gewinnkurve erhält. Auch wenn Sie nicht unbedingt zum Strategietester gehen müssen, um ein maschinelles Lernmodell zu testen, weil einige Modelle zu rechenintensiv sind, um sie zu testen, werden Sie aus anderen Gründen wie der Optimierung Ihrer Handelsvolumina, Zeitrahmen usw. auf jeden Fall dorthin gehen müssen. Eine sorgfältige Analyse der Logik muss durchgeführt werden, bevor man sich entscheidet, mit einem beliebigen Modus in den Live-Handel einzusteigen.

Mit freundlichen Grüßen.

Verfolgen Sie die Entwicklung und Änderungen an diesem Algorithmus auf meinem GitHub Repo https://github.com/MegaJoctan/MALE5

Datei  Inhalt & Verwendung
 Naive Bayes.mqh  Enthält die Klassen der Naïve Bayes-Modelle
 Naive Bayes theory script.mq5  Ein Skript zum Testen der Bibliothek 
 Naive Bayes Test.mq5  EA für den Handel mit den besprochenen Modellen
 matrix_utils.mqh  Enthält zusätzliche Matrixfunktionen 
 metrics.mqh  Enthält die Funktionen zur Analyse der Leistung von ML-Modellen, wie die Konfusionsmatrix
 naive bayes visualize.py  Python-Skript zum Zeichnen von Verteilungsdiagrammen für alle vom Modell verwendeten unabhängigen Variablen
 gender datasets.csv & weather dataset.csv  In diesem Artikel als Beispiele verwendete Datensätze

Haftungsausschluss: Dieser Artikel ist nur für Bildungszwecke, Handel ist ein riskantes Spiel hoffentlich wissen Sie, das Risiko mit ihm verbunden. Der Autor übernimmt keine Verantwortung für Verluste oder Schäden, die durch die Anwendung der in diesem Artikel beschriebenen Methoden verursacht werden können, denken Sie daran. Riskieren Sie das Geld, das Sie sich leisten können zu verlieren.


Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/12184

Beigefügte Dateien |
MQL5.zip (15.93 KB)
Kategorientheorie in MQL5 (Teil 3) Kategorientheorie in MQL5 (Teil 3)
Die Kategorientheorie ist ein vielfältiger und expandierender Zweig der Mathematik, der in der MQL-Gemeinschaft noch relativ unentdeckt ist. In dieser Artikelserie sollen einige der Konzepte vorgestellt und untersucht werden, mit dem übergeordneten Ziel, eine offene Bibliothek einzurichten, die Einblicke gewährt und hoffentlich die Nutzung dieses bemerkenswerten Bereichs für die Strategieentwicklung von Händlern fördert.
Algorithmen zur Optimierung mit Populationen: Harmonie-Suche (HS) Algorithmen zur Optimierung mit Populationen: Harmonie-Suche (HS)
In diesem Artikel werde ich den leistungsstärksten Optimierungsalgorithmus untersuchen und testen - die Harmonie-Suche (HS), inspiriert durch den Prozess der Suche nach der perfekten Klangharmonie. Welcher Algorithmus ist nun der führende in unserer Bewertung?
Lernen Sie, wie man ein Handelssystem mit Bill Williams' MFI entwickelt Lernen Sie, wie man ein Handelssystem mit Bill Williams' MFI entwickelt
Dies ist ein neuer Artikel in der Serie, in der wir lernen, wie man ein Handelssystem auf der Grundlage beliebter technischer Indikatoren entwickelt. Dieses Mal werden wir den Market Facilitation Index von Bill Williams (BW MFI) besprechen.
Ein Beispiel für die Zusammenstellung von ONNX-Modellen in MQL5 Ein Beispiel für die Zusammenstellung von ONNX-Modellen in MQL5
ONNX (Open Neural Network eXchange) ist ein offenes Format zur Darstellung neuronaler Netze. In diesem Artikel zeigen wir Ihnen, wie Sie zwei ONNX-Modelle gleichzeitig in einem Expert Advisor verwenden können.