Deze script is geschreven als onderdeel van het artikel "Machine Learning: Hoe Ondersteunende Vector Machines kunnen worden gebruikt in Trading", gepubliceerd op de MQL5-website.
Stel je het volgende hypothetische scenario voor: je bent een onderzoeker die een zeldzaam dier onderzoekt dat alleen in de diepten van de Arctische gebieden voorkomt, genaamd Schnicks. Vanwege de afgelegenheid van deze dieren zijn er slechts een handvol ooit gevonden (laten we zeggen ongeveer 5000). Als onderzoeker zit je met de vraag... hoe kan ik een Schnick identificeren?
Alles wat je tot je beschikking hebt, zijn de onderzoeksartikelen die eerder zijn gepubliceerd door de weinige onderzoekers die er een hebben gezien. In deze onderzoeksartikelen beschrijven de auteurs bepaalde kenmerken van de Schnicks die ze hebben gevonden, zoals hoogte, gewicht, aantal poten, enzovoort, maar al deze kenmerken variëren tussen de onderzoeksartikelen zonder een herkenbaar patroon...
Hoe kunnen we deze gegevens gebruiken om een nieuw dier als een Schnick te identificeren?
Een mogelijke oplossing voor ons probleem is om een ondersteunende vector machine te gebruiken om de patronen in de gegevens te identificeren en een raamwerk te creëren dat kan worden gebruikt om dieren te classificeren als zijnde een Schnick of geen Schnick. De eerste stap is om een set gegevens te creëren die kan worden gebruikt om je ondersteunende vector machine te trainen om Schnicks te identificeren. De trainingsdata is een set invoer- en bijpassende uitvoerwaarden voor de ondersteunende vector machine om te analyseren en een patroon uit te extraheren.
Dit script probeert de kracht van het gebruik van ondersteunende vector machines in het oplossen van classificatieproblemen te demonstreren door gebruik te maken van het Ondersteunende Vector Machine Leerhulpmiddel dat beschikbaar is in de MQL5-markt. Een volledige beschrijving van dit hypothetische probleem en het script is te vinden in het artikel "Machine Learning: Hoe Ondersteunende Vector Machines kunnen worden gebruikt in Trading". Dit artikel bevat een handleiding over hoe je het script kunt gebruiken en hoe dit probleem inzicht kan geven in het gebruik van machine learning voor het beoordelen van markttrends.
Code:
//+------------------------------------------------------------------+ //| Schnick_Demo.mq5 | //| Copyright 2011, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2011, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" //+------------------------------------------------------------------+ //| Dit script demonstreert de mogelijkheden van de Ondersteunende Vector //| Machine Leerhulpmiddel //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| De volgende verklaring importeert alle functies die zijn opgenomen in //| het Ondersteunende Vector Machine-hulpmiddel 'svMachineTool.ex5' //+------------------------------------------------------------------+ #import "svMachineTool_demo.ex5" enum ENUM_TRADE {BUY,SELL}; enum ENUM_OPTION {OP_MEMORY,OP_MAXCYCLES,OP_TOLERANCE}; int initSVMachine(void); void setIndicatorHandles(int handle,int &indicatorHandles[],int offset,int N); void setParameter(int handle,ENUM_OPTION option,double value); bool genOutputs(int handle,ENUM_TRADE trade,int StopLoss,int TakeProfit,double duration); bool genInputs(int handle); bool setInputs(int handle,double &Inputs[],int nInputs); bool setOutputs(int handle,bool &Outputs[]); bool training(int handle); bool classify(int handle); bool classify(int handle,int offset); bool classify(int handle,double &iput[]); void deinitSVMachine(void); #import //--- Het aantal invoeren dat we zullen gebruiken voor de svm int N_Inputs=7; //+------------------------------------------------------------------+ //| Expert initialisatie functie | //+------------------------------------------------------------------+ int OnInit() { double inputs[]; // lege double-array voor het creëren van trainingsinvoer bool outputs[]; // lege bool-array voor het creëren van trainingsinvoer int N_TrainingPoints=5000; // definieert het aantal te genereren trainingsmonsters int N_TestPoints=5000 // definieert het aantal monsters dat wordt gebruikt voor testen genTrainingData(inputs,outputs,N_TrainingPoints); // Genereert de invoer- en uitvoerwaarden voor training van de svm int handle1=initSVMachine(); // initialiseert een nieuwe ondersteunende vector machine en retourneert een handle setInputs(handle1,inputs,7); // geeft de invoerwaarden (zonder fouten) door aan de ondersteunende vector machine setOutputs(handle1,outputs); // geeft de uitvoerwaarden (zonder fouten) door aan de ondersteunende vector machine setParameter(handle1,OP_TOLERANCE,0.01); // stelt de fouttolerantieparameter in op <5% training(handle1); // traint de ondersteunende vector machine met de doorgegeven invoer/uitvoer insertRandomErrors(inputs,outputs,500); // neemt de originele invoer/uitvoer en voegt willekeurige fouten toe aan de gegevens int handle2=initSVMachine(); // initialiseert een nieuwe ondersteunende vector machine en retourneert een handle setInputs(handle2,inputs,7); // geeft de invoerwaarden (met fouten) door aan de ondersteunende vector machine setOutputs(handle2,outputs); // geeft de uitvoerwaarden (met fouten) door aan de ondersteunende vector machine setParameter(handle2,OP_TOLERANCE,0.01); // stelt de fouttolerantieparameter in op <5% training(handle2); // traint de ondersteunende vector machine met de doorgegeven invoer/uitvoer double t1=testSVM(handle1,N_TestPoints); // test de nauwkeurigheid van de getrainde ondersteunende vector machine en slaat deze op in t1 double t2=testSVM(handle2,N_TestPoints); // test de nauwkeurigheid van de getrainde ondersteunende vector machine en slaat deze op in t2 Print("De SVM-nauwkeurigheid is ",NormalizeDouble(t1,2),"% (met trainingsinvoer/uitvoer zonder fouten)"); Print("De SVM-nauwkeurigheid is ",NormalizeDouble(t2,2),"% (met trainingsinvoer/uitvoer met fouten)"); deinitSVMachine(); // Ruimt al het geheugen op dat is gebruikt bij het genereren van de SVM om geheugenlekken te voorkomen return(0); } //+------------------------------------------------------------------+ //| Expert deinitialisatie functie | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- Geen functies uitgevoerd in OnDeinit() } //+------------------------------------------------------------------+ //| Expert tick functie | //+------------------------------------------------------------------+ void OnTick() { //--- Geen functies uitgevoerd in OnTick() } //+------------------------------------------------------------------+ //| Deze functie neemt de observatie-eigenschappen van het geobserveerde //| dier en op basis van de criteria die we hebben gekozen, retourneert //| true/false of het een schnick is //+------------------------------------------------------------------+ bool isItASchnick(double height,double weight,double N_legs,double N_eyes,double L_arm,double av_speed,double f_call) { if(height < 1000 || height > 1100) return(false); //Als de hoogte buiten de parameters valt, > retourneer(false) if(weight < 40 || weight > 50) return(false); //Als het gewicht buiten de parameters valt, > retourneer(false) if(N_legs < 8 || N_legs > 10) return(false); //Als het aantal poten buiten de parameters valt, > retourneer(false) if(N_eyes < 3 || N_eyes > 4) return(false); //Als het aantal ogen buiten de parameters valt, > retourneer(false) if(L_arm < 400 || L_arm > 450) return(false); //Als de lengte van de arm buiten de parameters valt, > retourneer(false) if(av_speed < 2 || av_speed > 2.5) return(false); //Als de gemiddelde snelheid buiten de parameters valt, > retourneer(false) if(f_call < 11000 || f_call > 15000) return(false); //Als de roepfrequentie buiten de parameters valt, > retourneer(false) return(true); //Anders > retourneer(true) } //+------------------------------------------------------------------+ //| Deze functie neemt een lege double-array en lege boolean-array //| en genereert de invoer/uitvoer voor het trainen van de SVM //+------------------------------------------------------------------+ void genTrainingData(double &inputs[],bool &outputs[],int N) { double in[]; // creëert een lege double-array die wordt gebruikt // voor tijdelijk opslaan van de gegenereerde invoeren ArrayResize(in,N_Inputs); // wijzig de grootte van de in[]-array naar N_Inputs ArrayResize(inputs,N*N_Inputs); // wijzig de grootte van de inputs[]-array naar N*N_Inputs ArrayResize(outputs,N); // wijzig de grootte van de outputs[]-array naar N for(int i=0;i<N;i++) { in[0]= randBetween(980,1120); // Willekeurige invoer gegenereerd voor hoogte in[1]= randBetween(38,52); // Willekeurige invoer gegenereerd voor gewicht in[2]= randBetween(7,11); // Willekeurige invoer gegenereerd voor N_poten in[3]= randBetween(3,4.2); // Willekeurige invoer gegenereerd voor N_ogen in[4]= randBetween(380,450); // Willekeurige invoer gegenereerd voor L_armen in[5]= randBetween(2,2.6); // Willekeurige invoer gegenereerd voor gemiddelde_snelheid in[6]= randBetween(10500,15500); // Willekeurige invoer gegenereerd voor f_call //--- kopieert de nieuwe willekeurige invoeren in de trainingsinvoerarray ArrayCopy(inputs,in,i*N_Inputs,0,N_Inputs); //--- beoordeelt de willekeurige invoeren en bepaalt of het een schnick is outputs[i]=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]); } } //+------------------------------------------------------------------+ //| Deze functie neemt de handle voor de getrainde SVM en test hoe //| succesvol het is in het classificeren van nieuwe willekeurige invoeren //+------------------------------------------------------------------+ double testSVM(int handle,int N) { double in[]; int atrue=0; int afalse=0; int N_correct=0; bool Predicted_Output; bool Actual_Output; ArrayResize(in,N_Inputs); for(int i=0;i<N;i++) { in[0]= randBetween(980,1120); // Willekeurige invoer gegenereerd voor hoogte in[1]= randBetween(38,52); // Willekeurige invoer gegenereerd voor gewicht in[2]= randBetween(7,11); // Willekeurige invoer gegenereerd voor N_poten in[3]= randBetween(3,4.2); // Willekeurige invoer gegenereerd voor N_ogen in[4]= randBetween(380,450); // Willekeurige invoer gegenereerd voor L_armen in[5]= randBetween(2,2.6); // Willekeurige invoer gegenereerd voor gemiddelde_snelheid in[6]= randBetween(10500,15500); // Willekeurige invoer gegenereerd voor f_call //--- gebruikt de isItASchnick functie om de werkelijke gewenste uitvoer te bepalen Actual_Output=isItASchnick(in[0],in[1],in[2],in[3],in[4],in[5],in[6]); //--- gebruikt de getrainde SVM om de voorspelde uitvoer te retourneren. Predicted_Output=classify(handle,in); if(Actual_Output==Predicted_Output) { N_correct++; // Deze verklaring houdt het aantal keren bij dat de voorspelde uitvoer correct is. } } //--- retourneert de nauwkeurigheid van de getrainde SVM als percentage return(100*((double)N_correct/(double)N)); } //+------------------------------------------------------------------+ //| Deze functie neemt de correcte trainingsinvoeren en uitvoeren //| en voegt N willekeurige fouten toe aan de gegevens //+------------------------------------------------------------------+ void insertRandomErrors(double &inputs[],bool &outputs[],int N) { int nTrainingPoints=ArraySize(outputs); // berekent het aantal trainingspunten int index; // maakt een nieuwe integer 'index' bool randomOutput; // maakt een nieuwe bool 'randomOutput' double in[]; // creëert een lege double-array die wordt gebruikt // voor tijdelijk opslaan van de gegenereerde invoeren ArrayResize(in,N_Inputs); // wijzig de grootte van de in[]-array naar N_Inputs for(int i=0;i<N;i++) { in[0]= randBetween(980,1120); // Willekeurige invoer gegenereerd voor hoogte in[1]= randBetween(38,52); // Willekeurige invoer gegenereerd voor gewicht in[2]= randBetween(7,11); // Willekeurige invoer gegenereerd voor N_poten in[3]= randBetween(3,4.2); // Willekeurige invoer gegenereerd voor N_ogen in[4]= randBetween(380,450); // Willekeurige invoer gegenereerd voor L_armen in[5]= randBetween(2,2.6); // Willekeurige invoer gegenereerd voor gemiddelde_snelheid in[6]= randBetween(10500,15500); // Willekeurige invoer gegenereerd voor f_call //--- willekeurig kiezen van een van de trainingsinvoeren om een fout in te voegen index=(int)MathRound(randBetween(0,nTrainingPoints-1)); //--- genereert een willekeurige boolean uitvoer om een fout te creëren if(randBetween(0,1)>0.5) randomOutput=true; else randomOutput=false; //--- kopieert de nieuwe willekeurige invoeren in de trainingsinvoerarray ArrayCopy(inputs,in,index*N_Inputs,0,N_Inputs); //--- kopieert de nieuwe willekeurige uitvoer in de trainingsoutputarray outputs[index]=randomOutput; } } //+------------------------------------------------------------------+ //| Deze functie wordt gebruikt om een willekeurige waarde te creëren tussen t1 en t2 //+------------------------------------------------------------------+ double randBetween(double t1,double t2) { return((t2-t1)*((double)MathRand()/(double)32767)+t1); } //+------------------------------------------------------------------+
Reactie 0