
純粋なMQL5におけるエネルギーベースの学習を用いた特徴量選択アルゴリズム
はじめに
アルゴリズム取引の分野では、機械学習の普及により、金融データの隠れたパターンを発見するためのデータマイニング技術の導入が進んでいます。このような状況の中で、実務家は多くの変数を選別し、特定の目標の達成や特定の問題の解決に最も有益と思われる変数を特定するという課題に取り組むことが多いです。この記事では、与えられた予測タスクに対する候補変数のセットの関連性を評価することを目的とした、特徴量選択アルゴリズムの実装を探求します。
Yun Li、Jennie Si、Guojing Zhou、Shasha Huang、Songcan Chenは研究論文「FREL: A Stable Feature Selection Algorithm」を共著しました。この論文では、正則化エネルギーベース学習(Feature Weighting as Regularized Energy-Based Learning:FREL)と名付けられたアルゴリズムが紹介されてます。このアルゴリズムは、精度と安定性の両方を提供するように設計された特徴量選択または重み付け技術として機能します。この議論では、正規化エネルギーベース学習と特徴の重み付けの背後にある理論的根拠の概要を示します。さらに、スクリプトとして作成されたMQL5プログラムの例を通して、提案されたアプローチの有効性を説明し、特徴量選択ツールとしてのこの手法の可能性を強調します。
加重最近傍分類
FRELの背後にある概念は、データセット内の点間の距離を活用して予測をおこなう、重み付きk近傍法として知られる技法からインスピレーションを得ています。各特徴量に対して適切な重みを決定することで、この方法は予測精度を高めます。重み付き最近傍分類は、機械学習で分類タスクに広く使われているk-最近傍(k-NN)アルゴリズムのバリエーションです。標準的なk-NN分類では、アルゴリズムは新しいデータ点を分類する際に、訓練セットの中で最も近いk個のデータ点を調べ、最終的にこれらの近傍データ点の中で多数派のクラスを新しいデータ点に割り当てます。
しかし、重み付き最近傍分類では、単に最近傍の票を集計するのではなく、各近傍の票は新しいデータ点からの距離に応じて重み付けされます。その根拠は、より近い隣人は、より遠い隣人よりも、分類決定に強い影響を及ぼすはずだということです。この重み付けプロセスでは、新しいデータ点と訓練セット内の各点との距離を計算します。よく使用される距離測定基準には、ユークリッド距離、マンハッタン距離、コサイン類似度などがあり、データの特徴量に基づいて選択されます。この文脈では、データ点間のマンハッタン距離(都市ブロック距離とも呼ばれる)を利用します。この距離の計算式を以下に示します。ここで、wは重みであり、テストケースは訓練ケースとして与えられた他の訓練データと比較して評価されます。
エネルギーベースモデリングについて
機械学習におけるエネルギーベースモデリング(英語)は、教師あり学習タスクと教師なし学習タスクの両方に適用できる汎用的なフレームワークとして機能します。エネルギーベースモデリングは、様々なデータ構成にエネルギー値を割り当て、望ましい構成と望ましくない構成を区別できるモデルを学習するという原理で動作します。これは、観測されたデータのエネルギーを最小化する一方で、観測されていない、あるいは望ましくないデータ構成のエネルギーを最大化することで達成されます。
エネルギーベースのモデルの核心は、E()と表記されるエネルギー関数の定義にあります。この関数は,モデルパラメータの集合とともに,入力変数または予測変数の設定を入力として受け取ります。エネルギー関数の出力は、入力変数の構成の関連性を示します。例えば、回帰モデルを評価する場合、エネルギー関数は平均二乗誤差として表されます。関連性の高い予測変数が平均2乗誤差式に入力されると、出力値はより小さくなる傾向があり、より高い関連性を反映します。逆に、悪い予測因子は平均二乗誤差を大きくします。エネルギー関数は、考えられる変数の各構成にスカラー値を割り当てます。
エネルギーベースのモデルを学習する目的は、エネルギー関数のパラメータを学習し、関連性のある入力変数には低いエネルギーを、関連性のない入力変数には高いエネルギーを割り当てるようにすることです。これは、正しい変数には高いエネルギーを、正しくない変数には低いエネルギーをペナルティーとして課す目的関数を定義することを必要とします。これを達成するために、目標は、モデルから誤った予測を引き起こす可能性の高いサンプルを表す、最も低いエネルギーをもたらす不正確な変数の構成を特定することです。以下の関数は、正確な予測を生み出す入力変数の構成と区別するために、誤った値yを出力する入力xとモデルパラメータwの構成のエネルギーが低すぎることを表しています。
最終的に、目的関数は、最も低いエネルギーを持つ誤った構成と、最も近い正しい変数構成との間の不一致を最大化することを目指します。このような構成から得られるエネルギーを以下に示します。
損失関数として知られる目的関数は、サンプルごとに平均化された損失関数で構成されます。対数損失は以下の通りです。
サンプルごとの損失関数としては、ハインゼル損失、ロジット損失、二乗損失、二乗指数損失など、さまざまな損失基準を用いることができ、用途に応じて選択することができます。
まとめると、これらがFRELの根底にある基本的な概念です。続くセクションでは、アルゴリズムそのものの詳細を掘り下げていきます。
FRELアルゴリズム
FRELアルゴリズムを効果的に適用するためには、特定の基本的な考慮事項に従わなければなりません。まず、訓練データを慎重に評価することが重要です。FRELは、候補変数のセットを単一の目標に写像するデータセットに理想的に適しています。同様に重要なのは、変数の規模が似ていることです。FRELを一貫性のないスケーリングを持つ予測変数の候補にさらすと、最終的な結果を大きく歪める可能性があります。
第二に、FRELがエネルギーに基づく学習法であることを考えると、重み付けパラメータを組み込んだエネルギー関数を定義する必要があります。したがって、使用するモデルは、対応する重み付けとともに、候補となる変数のセットを受け入れるように設定する必要があります。例えば、平均二乗誤差をエネルギー関数として考え、モデルが回帰モデルである場合、重み付けパラメータを組み込むことは比較的簡単です。それぞれの重みは、候補となる予測因子と対になっています。
最後に、損失関数を決定するために、サンプルごとの損失関数を選択しなければなりません。モデルの重み付けパラメータを組み込んだ損失関数は、最適な重みを得るために最小化される(関数の)関数です。
FRELアルゴリズムの核となるステップは以下の通りです。
- n個の目標値に対応するd個の予測子候補を持つn個の観測からなる訓練データ集合から始めます。目標は、目標値を決定するために、d個の候補の集合から最も関連性の高い予測子を確認することです。これは,d個の予測変数の各々に重みを割り当て,他の変数との相対的な変数の重要性を示します。重みが大きいほど、目標値を定義する際の関連性が高いことを意味します。
- 最初は、すべての重みに1の値を割り当てます。
- 訓練データの各観測に重み付き最近傍分類を適用し、最も低いエネルギーをもたらす不正確な変数の構成と、高いエネルギーを持つ正しい変数の最も近い構成を特定します。これらのエネルギー値を利用して、選択した損失関数を使用してサンプルごとの損失を計算します。
- 最後に、適切な最適化手順を用いて、正則化を用いて目的損失関数を最小化します(オプション)。これがFRELのコアとなるアルゴリズムです。
MQL5でのFRELの実装
このテキストで紹介するFRELの実装は、パウエルの最適化法を利用しています。使用する特定の最適化手法が重要なわけではありませんが、結果は手法間で比較的一貫しているはずです。この実装では、パウエル法はPowells.mqhで定義されたクラスPowellsMethodとして表現されます。FRELアルゴリズムは、frel.mqhで指定されているPowellsMethodの子孫であるクラスFRELにカプセル化されています。
//+------------------------------------------------------------------+ //| constructor | //+------------------------------------------------------------------+ FREL(matrix &in_data,int numboot=1, int bootsize=0) { m_data = in_data; m_num_boot=(numboot>0)?numboot:1; m_bootsize=(bootsize>2 && bootsize<=int(m_data.Rows()) && m_num_boot>1)?bootsize:int(m_data.Rows()); if(ArrayResize(m_indices, int(m_data.Rows()))!=int(m_data.Rows()) || ArrayResize(m_target_bin, int(m_data.Rows()))!=int(m_data.Rows()) || ArrayResize(m_trial_weights, int(m_data.Cols()-1))!=int(m_data.Cols()-1) || ArrayResize(m_work_weights, int(m_data.Cols()-1))!=int(m_data.Cols()-1) ) { Print(__FUNCTION__, " error ", GetLastError()); m_memory_allocated = false; } else m_memory_allocated = true; }
パラメトリックコンストラクタの説明を掘り下げてみましょう。少なくとも1つのパラメータ、すなわち学習データの行列を指定して起動します。訓練データを行列でどのように構成するかが重要です。各行は観測または1つの標本を表し,列は評価される候補変数または予測変数を表します。目標は行列の最後の列に存在すると予想されます。コンストラクタのオプションパラメータについては、以下の表で詳しく説明します。
パラメータ名 | データ型 | デフォルト値 | 詳細 |
---|---|---|---|
numboot | integer | 1 | numbootは、実施するブートストラップの数を設定します。 |
bootsize | integer | 0 | bootsizeは、各ブートストラップのサイズを定義します。このパラメータの設定には注意してください。行列の観測数より大きな値が使用された場合、numbootは自動的に1にフォールバックし、bootsizeは観測数にフォールバックします。 |
FRELクラスを利用するために、ユーザーが熟知しておく必要があるメソッドはただひとつ、WeighVars()です。
//+-----------------------------------------------------------------------+ //| Find the most relevant variables from a dataset of candidate variables| //+-----------------------------------------------------------------------+ bool WeighVars(int num_bins_target, double reg_factor,int &index[],double &weights[]) { if(!m_memory_allocated) { Print(" INTERNAL ERROR "); return false; } if(num_bins_target<=1 || num_bins_target>int(m_data.Rows())) { Print(__FUNCTION__, " invalid function parameter: num_bins_target. Parameter should be >=2 "); return false; } int ret=0; double target[], target_thresholds[] ; double sum ; int n_cases = int(m_data.Rows()); m_reg_factor = MathAbs(reg_factor); m_loss = 0.0; if(ArrayResize(index,int(m_data.Cols()-1))!=int(m_data.Cols()-1) || !np::vecAsArray(m_data.Col(m_data.Cols()-1),target) ) { Print(__FUNCTION__, " error ", GetLastError()); return false; } int k = num_bins_target ; if(!bin_array(target, k, target_thresholds, m_target_bin)) return false; if(k<num_bins_target) { Print("error bins of target vector ", num_bins_target," : ", k); return false; } for(int i=0 ; i<n_cases ; i++) { if(m_target_bin[i] >= num_bins_target) { Print("error m_target_bin array at index ", i, " is ",m_target_bin[i], " should be less than ", num_bins_target); return false; } } ret = calc_wt(num_bins_target,m_loss,weights); if(ret<0) return false; sum = 0.0 ; for(ulong var=0 ; var<m_data.Cols()-1 ; var++) { weights[var] = m_data.Col(var).Std() * exp(weights[var]); sum += weights[var] ; } for(ulong var=0 ; var<m_data.Cols()-1 ; var++) { weights[var] *= 100.0 / sum ; index[var] = int(var) ; } MathQuickSortDescending(weights,index,0,int(weights.Size()-1)) ; return true; }
このメソッドはコンストラクタで指定された訓練データを評価します。これはブール値を返し、falseはプロシージャが完了できなかったことを示します。このメソッドのパラメータは以下の通りです。
- num_bins_target:目標値が分割されるビンの数を定義する整数。このパラメータは、2以上かつ訓練データの観測の数以下の任意の整数に設定されるべきです。
- reg_factor:正則化の度合いを制御する正のdouble値。値0は正則化を無効にします。
- index[]:操作結果の一部を書き込む整数配列。これは、コンストラクタに供給されたオリジナルの列インデックスを、目標との関連性が高い順に並べたものです。
- weights[]:最適な重み付けを降順に並べたdouble配列
WeighVars()が呼び出されると、privateメソッドbin_array()の呼び出しに備えて、目標値が行列から抽出され、配列に入れられます。このメソッドは、配列をほぼ等しい大きさのカテゴリにセグメント化し、成功すると2つの配列を出力します。upperbound_thresholds[]は、各セグメントに対する上限しきい値の配列で、整数配列categories[]は、対応する目標値が属するセグメントを表すインデックス値を含みます。これらの各値は、すべての目標値が正しくビニングされたことを確認するために確認されます。
//+------------------------------------------------------------------+ //| calculates the optimal weights of candidate variables | //+------------------------------------------------------------------+ int calc_wt(int num_bins_target,double &loss_value, double &w[]) { int ret,rand_error, class_count[] ; ret = 0; if(ArrayResize(class_count,num_bins_target)!=num_bins_target || (w.Size()!=uint(m_data.Cols()-1) && ArrayResize(w,int(m_data.Cols()-1))!=int(m_data.Cols()-1))) { Print(__FUNCTION__, " error ", GetLastError()); return -1; } ArrayInitialize(w,0.0); loss_value = 0.0 ; for(ulong i=0 ; i<m_data.Rows() ; i++) m_indices[i] = int(i) ; for(int ibootstrap=0 ; ibootstrap<m_num_boot; ibootstrap++) { Comment(" Bootstrap iteration ", ibootstrap+1); ArrayInitialize(class_count,0); int ii, j, k, m; ii = int (m_data.Rows()) ; while(ii > 1) { m = int (m_data.Rows()) - ii ; if(m >= m_bootsize) break ; j = (int)(MathRandomUniform(0.0,1.0,rand_error) * ii) ; if(j >= ii) j = ii - 1 ; k = m_indices[m] ; m_indices[m] = m_indices[m+j] ; m_indices[m+j] = k ; --ii ; ++class_count[m_target_bin[m_indices[m]]] ; } for(int i=0 ; i<num_bins_target ; i++) { if(class_count[i] < 2) Print(__FUNCTION__, " class at ", i, " has less than 2 members. Consider adjusting Frel parameters. (number of partitions or bootstrap sample size)"); } ArrayInitialize(m_trial_weights,0.0); ret += Optimize(m_trial_weights); loss_value += PowellsMethod::GetFret() ; for(ulong i=0 ; i<m_data.Cols()-1 ; i++) w[i] += m_trial_weights[i] ; } for(ulong i=0 ; i<m_data.Cols()-1; i++) w[i] /= double(m_num_boot) ; return ret ; }
重みの推定はcalc_wt()の呼び出しから始まります。ここでは、ブートストラップサンプリングをおこない、初期重みを最適化する前にデータをシャッフルします。最適化は、親クラスのメソッドOptimize()によって実行されます。各ブートストラップの最適重みはw[]に合計され、calc_wt()を終了する前に平均されます。
//+------------------------------------------------------------------+ //| function minimized by Powells optimization method | //+------------------------------------------------------------------+ virtual double func(const double& p[]) { double pen = 0.0 ; for(ulong i=0 ; i<m_data.Cols()-1 ; i++) { if(p[i] > 4.0) { m_work_weights[i] = exp(4.0) + p[i] - 4.0 ; pen += (p[i] - 4.0) * (p[i] - 4.0) ; } else if(p[i] < -3.0) { m_work_weights[i] = exp(-3.0) + p[i] + 3.0 ; pen += (p[i] + 3.0) * (p[i] + 3.0) ; } else m_work_weights[i] = exp(p[i]) ; } return (loss(m_work_weights) + pen) ; }
最小化される関数は損失関数であり、親クラスのfunc()と呼ばれるオーバーライドされたメソッドで表されることを覚えておいてください。
//+------------------------------------------------------------------+ //| calculates the loss function | //+------------------------------------------------------------------+ double loss(double &w[]) { double totaloss = total_loss(w); totaloss/=double(m_data.Rows()); if(m_reg_factor>0.0) { for(ulong i=0; i<m_data.Cols()-1;i++) totaloss+=m_reg_factor*pow(w[i],2.0); } return totaloss; }
func()内で、メソッドloss()が実行され、privateメソッドtotal_loss()として実装されたサンプルごとの損失関数の計算がトリガーされます。
//+------------------------------------------------------------------+ //| loss over all data | //+------------------------------------------------------------------+ double total_loss(double &w[]) { int category,first, other ; double distance, top, bottom, loss ; loss = 0.0 ; for(int i=0; i<m_bootsize; i++) { other = m_indices[i] ; category = m_target_bin[other] ; top = bottom = DBL_MAX ; for(int iother=0 ; iother<m_bootsize; iother++) { first = m_indices[iother] ; if(first == other) continue ; distance = 0.0 ; for(ulong v=0 ; v<m_data.Cols()-1; v++) { distance += w[v] * fabs(m_data[other][v] - m_data[first][v]) ; } if(m_target_bin[first] == category) { if(distance < top) top = distance ; } else { if(distance < bottom) bottom = distance ; } } distance = top - bottom ; if(distance > 30.0) loss += distance ; else loss += log(1.0 + exp(distance)); } return loss ; }
すべてのブートストラップが完了すると、平均化された最適な重みが、ユーザーから与えられたweights[]配列に書き込まれます。降順に並び替える前に、重みが合計で100になるように変換され、解釈しやすくなっています。
FRELによる特徴量選択例
FRELアルゴリズムを実証するために、スクリプトFrelExample.mq5を提供します。このスクリプトは、FRELを利用して、候補変数と目標からなるランダムに生成されたデータセットを分析し、最良の予測因子を特定します。ユーザーは、FRELアルゴリズムのすべてのパラメータと合成データセットの特定の特性を調整することができます。これは観測の合計数(num_observations)と予測変数の候補数(num_candidate_predictors)を含みます。以下は、ユーザーが調整可能なスクリプトの入力を示すスニペットです。
//---user adjustable input parameters input int number_of_partitions = 8; //Number of partitions input double regularization_factor = 0.0; //Regularization factor input int number_of_bootstraps = 1; input int bootstrap_size = 0; input ulong num_observations = 2000;// Sample size of random dataset input ulong num_candidate_predictors = 10;// Maximum number of candidate predictors in dataset
このスクリプトは、num_observations行と num_candidate_predictors + 1列の乱数行列を生成します。最後の列は、インデックス1、3、5、7の列の合計で上書きされ、データセットの目標変数となります。
//+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { srand(126); //---check user input parameters if(number_of_partitions<2 || num_observations<10 || num_candidate_predictors<8) { Print("Invalid input parameters"); return; } //---the data matrix dataset; //---initialize size of random dataset dataset.Init(num_observations,num_candidate_predictors+1); //---fill dataset with random data dataset.Random(1.0,10.0); //---set the target variable in the last column if(!dataset.Col(dataset.Col(1) + dataset.Col(3) + dataset.Col(5) + dataset.Col(7),num_candidate_predictors)) { Print("error ", GetLastError()); return; } //---initialize Frel object FREL frel(dataset,number_of_bootstraps,bootstrap_size); //---declare containers to recieve output from Frel operation double optimal_weights[]; int index[]; //--- ulong timeIT = GetTickCount64(); //---find the most relevant predictors if(!frel.WeighVars(number_of_partitions,regularization_factor,index,optimal_weights)) return; //---calculate runtime Print("Runtime of FREL ", GetTickCount64() - timeIT, " ms"); //---display results for(uint i = 0; i<optimal_weights.Size(); i++) Print("Predictor at Column index ", index[i], " weight ", optimal_weights[i]); } //+------------------------------------------------------------------+
目的は、FRELが変数を適切に重み付けできるかどうかを観測することであり、1、3、5、7列目を目標との関係が最も強いと指定します。最初に、正則化が無効で、ブートストラップが1つだけ指定されていることに注意して、デフォルトのパラメータでスクリプトを実行します。
出力
ON 0 18:12:30.906 FrelExample (BTCUSD,D1) Runtime of FREL 273375 ms GD 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 7 weight 24.46987538756267 IH 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 3 weight 24.22319404776024 EL 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 5 weight 22.26820806768701 LP 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 1 weight 22.13748732798876 DD 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 0 weight 1.162036446785271 KK 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 8 weight 1.1532145209345603 RO 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 4 weight 1.1496286906955606 RS 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 2 weight 1.1472521997561425 NG 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 6 weight 1.14561384476096 DK 0 18:12:30.906 FrelExample (BTCUSD,D1) Predictor at Column index 9 weight 1.14348946606884
次に、正則化の度合いを0.1と1.0にして、正則化が推定重みに与える影響を調べました。
出力
MQ 0 18:19:03.951 FrelExample (BTCUSD,D1) Runtime of FREL 331296 ms QD 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 3 weight 19.63442784832085 PK 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 5 weight 19.009699240770477 GO 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 7 weight 18.823288529399388 GQ 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 1 weight 18.18026689510982 NE 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 0 weight 4.106428447842871 KI 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 8 weight 4.075425288243113 OM 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 2 weight 4.070169243578418 MQ 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 6 weight 4.051103060690134 FE 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 9 weight 4.025271426001863 FJ 0 18:19:03.951 FrelExample (BTCUSD,D1) Predictor at Column index 4 weight 4.0239200200430805
出力
HP 0 18:25:43.421 FrelExample (BTCUSD,D1) Runtime of FREL 362984 ms FF 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 3 weight 10.353013480731704 JJ 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 7 weight 10.227015183302557 IM 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 5 weight 10.213781888319609 KQ 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 1 weight 10.079770794877978 PF 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 0 weight 9.948300319843046 QJ 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 8 weight 9.938367489770178 KN 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 2 weight 9.897336276433514 DQ 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 6 weight 9.79559491756489 EF 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 9 weight 9.774541742551756 CI 0 18:25:43.421 FrelExample (BTCUSD,D1) Predictor at Column index 4 weight 9.77227790660475
正則化テストの結果は、重みが他の変数に分散し、正しい変数から乖離していることを示しています。正則化の度合いを大きく指定すると、重みがはっきりしなくなり、有用な変数と無関係な変数を区別するのが難しくなると思われます。
テストの実行結果を調べると、FRELの動作が比較的遅いことがわかります。このボトルネックは、おそらくtotal_loss()関数に起因していると思われます。この関数は、オプティマイザが実行される際に、データセット全体を何度も繰り返し処理しなければなりません。実行効率を向上させるために、少ないサンプルサイズで何度もブートストラップをおこないます。以下の結果は、40サンプルの100ブートストラップから得られたものです。
出力
IN 0 18:30:55.441 FrelExample (BTCUSD,D1) Runtime of FREL 22985 ms OK 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 3 weight 18.706272752181135 OL 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 1 weight 18.32079620338284 RS 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 5 weight 18.194009676469012 HG 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 7 weight 16.298306686632337 MI 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 4 weight 5.838867272535404 LM 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 9 weight 5.249285089162589 FQ 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 8 weight 4.791606631149278 DE 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 6 weight 4.770223641360407 KI 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 0 weight 3.974977300216029 KM 0 18:30:55.441 FrelExample (BTCUSD,D1) Predictor at Column index 2 weight 3.855654746910961
結論
本稿では、正則化エネルギーベースのモデリングを用いた特徴量重み付けのMQL5実装を紹介しました。アルゴリズムの理論的基礎について簡単に説明し、合成データセットでの有効性を紹介しました。結果は有望でしたが、このアルゴリズムには大きな計算コストがかかり、解析に時間がかかることが確認されました。この問題に対処するために、より小さなサンプルサイズの複数のブートストラップの利用を提案し、アルゴリズムの全体的な実行速度を顕著に改善しました。ただし、私たちの実装は、マルチスレッドやGPUアクセラレーションから大きな恩恵を受ける可能性があります。とはいえ、この方法に興味のある読者は、ご自分のニーズに応じてコードをカスタマイズすることが奨励されます。この記事で説明したコードはすべて含まれています。各ソースファイルは以下の表に詳述されています。
ソースファイル | 詳細 |
---|---|
Mql5\include\np.mqh | 様々なベクトル行列操作ツールのヘッダファイル |
Mql5\include\Powells.mqh | Powells関数最小化法を実装するPowellsMethodクラスの定義が含まれる |
Mql5\include\frel.mqh | 正則化エネルギーに基づく学習アルゴリズムとしての特徴量重み付けを表すFRELクラスの定義が含まれる |
Mql5\script\FrelExample.mq5 | FRELクラスの使用法を示すスクリプト |
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/14865





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索