Article-22745-Categorical-H.../Scripts/Inference.mq5
2026-06-02 13:36:51 +03:00

117 lines
4.9 KiB
MQL5

//+------------------------------------------------------------------+
//| Inference.mq5 |
//| Eugene |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Eugene"
#property link "https://www.mql5.com"
#property version "1.00"
#include <CategoricalHMM\CategoricalHMM.mqh>
#include <Graphics\Graphic.mqh>
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
int n_states = 2; // Количество скрытых состояний
int n_emissions = 6; // Количество возможных исходов (количество классов)
// --- 1. Создаем модель (seed=99 для повторяемости) ---
CCategoricalHMM model(n_states, n_emissions, 99);
// --- Задаем параметры модели ---
// --- 2. Матрица переходов TR ---
matrix tr = {{0.95, 0.05},
{0.1, 0.9}
};
// --- 3.Матрицу эмиссий (E) ---
matrix e = {{1.0/6, 1.0/6, 1.0/6, 1.0/6, 1.0/6, 1.0/6},
{0.1, 0.1, 0.1, 0.1, 0.1, 0.5}
};
// --- 4. Генерируем последовательность наблюдений и скрытых состояний ---
vector y;
vector z;
int n_samples = 300; // Количество генерируемых выборок
model.Sample(n_samples, tr, e, y, z);
PrintFirst(z,"First 5 states",5); // First 5 states: [1 1 1 1 1]
PrintFirst(y,"First 5 emissions",5); // First 5 emissions: [6 1 5 2 3]
// --- БЛОК ВИЗУАЛИЗАЦИИ ---
int plotLimit = 300; // Рисуем первые 300 точек
double x[], y_[];
ArrayResize(x, plotLimit);
ArrayResize(y_, plotLimit);
for(int i = 0; i < plotLimit; i++)
{
x[i] = i;
y_[i] = z[i];
}
ChartSetInteger(0,CHART_SHOW,false);
CGraphic graphic;
ulong width = ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
ulong height = ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
graphic.Create(0,"HMM_States_Plot",0,0,0,int(width),int(height));
CCurve *curve = graphic.CurveAdd(x, y_, ColorToARGB(clrDodgerBlue, 255), CURVE_LINES,"States");
curve.LinesStyle(STYLE_SOLID);
curve.LinesWidth(2);
graphic.BackgroundMainColor(ColorToARGB(clrBlack,255));
graphic.BackgroundMainSize(24);
graphic.BackgroundMain("States over time");
graphic.XAxis().Name("Time");
graphic.XAxis().NameSize(18);
graphic.YAxis().Name("State (1=Fair, 2=Loaded)");
graphic.YAxis().NameSize(18);
graphic.YAxis().Min(1);
graphic.YAxis().Max(2);
graphic.CurvePlotAll();
graphic.Update();
Sleep(5*1000);
ChartSetInteger(0,CHART_SHOW,true);
graphic.Destroy();
ChartRedraw(0);
// --- Эмпирическая вероятность наблюдения=6 для симметричной(Fair) и смещенной (Loaded) кости ---
PrintFormat("Empirical probability '6' (Fair): %.3f", CalculateSixFreq(y, z, 1));
PrintFormat("Empirical probability '6' (Loaded): %.3f", CalculateSixFreq(y, z, 2));
// --- Inference ---
matrix Filtering, Smoothing, bs;
double marginal_loglik;
vector s;
if(model.Inference(y,tr,e,Smoothing,marginal_loglik,Filtering,bs,s))
{
Print("---Inference---");
PrintFormat("Логарифм правдоподобия (marginal_loglik): %.10f", marginal_loglik);
Print("\nМатрица Smoothing (апостериорные вероятности):");
PrintMatrixFormatted(Smoothing);
Print("\nМатрица Filtering :");
PrintMatrixFormatted(Filtering);
}
//MatrixToCSV("FilteringDist.csv",Filtering);
//MatrixToCSV("SmoothingDist.csv",Smoothing);
//VectorToCSV("TrueStates.csv", z);
}
//+------------------------------------------------------------------+
//+-------------------------------------------------------------------+
//|Возвращает частоту выпадения шестёрки | |
//+-------------------------------------------------------------------+
double CalculateSixFreq(const vector &r, const vector &s, int stateTarget)
{
int count = 0, total = 0;
for(int i=0; i<(int)r.Size(); i++)
{
if(s[i] == stateTarget)
{
total++;
if(r[i] == 6)
count++;
}
}
return (total > 0) ? (double)count/total : 0;
}
//+------------------------------------------------------------------+