xml doc rewrite

This commit is contained in:
Miha
2024-10-27 09:38:53 -07:00
parent c21b96152c
commit b2fcdda785
71 changed files with 2607 additions and 1102 deletions
+39 -1
View File
@@ -1,11 +1,44 @@
using System;
namespace QuanTAlib;
/// <summary>
/// Huber Loss: A robust error metric that combines squared error for small deviations
/// and absolute error for large deviations. This provides a balance between the high
/// sensitivity of MSE to outliers and the constant gradient of MAE.
/// </summary>
/// <remarks>
/// The Huber Loss calculation process:
/// 1. For each point, calculates error between actual and predicted values
/// 2. If absolute error ≤ delta: uses squared error (like MSE)
/// 3. If absolute error > delta: uses linear error (like MAE)
/// 4. Averages the losses over the period
///
/// Key characteristics:
/// - Combines benefits of MSE and MAE
/// - Less sensitive to outliers than MSE
/// - More sensitive to small errors than MAE
/// - Differentiable at all points
/// - Adjustable via delta parameter
///
/// Formula:
/// For error e = actual - predicted:
/// L(e) = 0.5 * e² if |e| ≤ δ
/// L(e) = δ * (|e| - 0.5δ) if |e| > δ
///
/// Sources:
/// Peter J. Huber - "Robust Estimation of a Location Parameter"
/// https://projecteuclid.org/euclid.aoms/1177703732
/// </remarks>
public class Huber : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
private readonly double _delta;
/// <param name="period">The number of points over which to calculate the loss.</param>
/// <param name="delta">The threshold between squared and linear loss (default 1.0).</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1 or delta is not positive.</exception>
public Huber(int period, double delta = 1.0)
{
if (period < 1)
@@ -24,6 +57,9 @@ public class Huber : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the loss.</param>
/// <param name="delta">The threshold between squared and linear loss (default 1.0).</param>
public Huber(object source, int period, double delta = 1.0) : this(period, delta)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -53,6 +89,7 @@ public class Huber : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
@@ -70,10 +107,12 @@ public class Huber : AbstractBase
if (absError <= _delta)
{
// Squared error for small deviations
sumLoss += 0.5 * error * error;
}
else
{
// Linear error for large deviations
sumLoss += _delta * (absError - 0.5 * _delta);
}
}
@@ -84,5 +123,4 @@ public class Huber : AbstractBase
IsHot = _index >= WarmupPeriod;
return huberloss;
}
}
+33 -1
View File
@@ -1,10 +1,40 @@
using System;
namespace QuanTAlib;
/// <summary>
/// MAE: Mean Absolute Error
/// A straightforward error metric that measures the average magnitude of errors
/// between predicted and actual values, without considering their direction.
/// MAE treats all individual differences equally in the average.
/// </summary>
/// <remarks>
/// The MAE calculation process:
/// 1. Calculates absolute difference between each actual and predicted value
/// 2. Sums all absolute differences
/// 3. Divides by the number of observations
///
/// Key characteristics:
/// - Linear scale (all differences weighted equally)
/// - Robust to outliers compared to MSE
/// - Easy to interpret (same units as data)
/// - Constant gradient for optimization
/// - Less sensitive to large errors than MSE
///
/// Formula:
/// MAE = (1/n) * Σ|actual - predicted|
///
/// Sources:
/// https://en.wikipedia.org/wiki/Mean_absolute_error
/// https://www.statisticshowto.com/absolute-error/
/// </remarks>
public class Mae : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the MAE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Mae(int period)
{
if (period < 1)
@@ -18,6 +48,8 @@ public class Mae : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the MAE.</param>
public Mae(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +79,7 @@ public class Mae : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
@@ -68,5 +101,4 @@ public class Mae : AbstractBase
IsHot = _index >= WarmupPeriod;
return mae;
}
}
+35 -1
View File
@@ -1,10 +1,42 @@
using System;
namespace QuanTAlib;
/// <summary>
/// MAPD: Mean Absolute Percentage Deviation
/// A percentage-based error metric that measures the average absolute percentage
/// difference between predicted and actual values. MAPD expresses accuracy as a
/// percentage, making it scale-independent and easy to interpret.
/// </summary>
/// <remarks>
/// The MAPD calculation process:
/// 1. Calculates absolute percentage difference for each point
/// 2. Sums all absolute percentage differences
/// 3. Divides by the number of observations
///
/// Key characteristics:
/// - Scale-independent (percentage-based)
/// - Easy to interpret (0-100% range)
/// - Useful for comparing different scales
/// - Cannot handle zero actual values
/// - Asymmetric (treats over/under predictions differently)
///
/// Formula:
/// MAPD = (1/n) * Σ|((actual - predicted) / actual)|
///
/// Sources:
/// https://en.wikipedia.org/wiki/Mean_absolute_percentage_error
/// https://www.statisticshowto.com/mean-absolute-percentage-error-mape/
///
/// Note: Also known as MAPE (Mean Absolute Percentage Error) in some contexts
/// </remarks>
public class Mapd : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the MAPD.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Mapd(int period)
{
if (period < 1)
@@ -18,6 +50,8 @@ public class Mapd : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the MAPD.</param>
public Mapd(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +81,7 @@ public class Mapd : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
@@ -71,5 +106,4 @@ public class Mapd : AbstractBase
IsHot = _index >= WarmupPeriod;
return mapd;
}
}
+35
View File
@@ -1,10 +1,42 @@
using System;
namespace QuanTAlib;
/// <summary>
/// MAPE: Mean Absolute Percentage Error
/// A percentage-based error metric that measures the average absolute percentage
/// difference between predicted and actual values. MAPE expresses accuracy as a
/// percentage, making it scale-independent and easy to interpret.
/// </summary>
/// <remarks>
/// The MAPE calculation process:
/// 1. Calculates absolute percentage error for each point
/// 2. Sums all absolute percentage errors
/// 3. Divides by the number of observations
///
/// Key characteristics:
/// - Scale-independent (percentage-based)
/// - Easy to interpret (0-100% range)
/// - Useful for comparing different scales
/// - Cannot handle zero actual values
/// - Asymmetric (treats over/under predictions differently)
///
/// Formula:
/// MAPE = (1/n) * Σ|((actual - predicted) / actual)| * 100%
///
/// Sources:
/// https://en.wikipedia.org/wiki/Mean_absolute_percentage_error
/// https://www.statisticshowto.com/mean-absolute-percentage-error-mape/
///
/// Note: Also known as MAPD (Mean Absolute Percentage Deviation) in some contexts
/// </remarks>
public class Mape : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the MAPE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Mape(int period)
{
if (period < 1)
@@ -18,6 +50,8 @@ public class Mape : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the MAPE.</param>
public Mape(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +81,7 @@ public class Mape : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+41 -22
View File
@@ -1,20 +1,41 @@
using System;
namespace QuanTAlib;
/// <summary>
/// Represents the Mean Absolute Scaled Error (MASE) calculation.
/// MASE: Mean Absolute Scaled Error
/// A scale-free error metric that compares the mean absolute error of the forecast
/// with the mean absolute error of the naive forecast. MASE is particularly useful
/// for comparing forecast accuracy across different datasets.
/// </summary>
/// <remarks>
/// The MASE calculation process:
/// 1. Calculates mean absolute error of the forecast
/// 2. Calculates mean absolute error of naive forecast (using previous value)
/// 3. Divides forecast error by naive forecast error
///
/// Key characteristics:
/// - Scale-free (independent of data scale)
/// - Handles zero values unlike percentage errors
/// - Symmetric (treats over/under predictions equally)
/// - Easy interpretation (MASE < 1 means better than naive forecast)
/// - Robust to outliers
///
/// Formula:
/// MASE = MAE(forecast) / MAE(naive_forecast)
/// where naive_forecast[t] = actual[t-1]
///
/// Sources:
/// Rob J. Hyndman - "Another Look at Forecast-Accuracy Metrics for Intermittent Demand"
/// https://robjhyndman.com/papers/another-look-at-measures-of-forecast-accuracy/
/// </remarks>
public class Mase : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
private readonly CircularBuffer _naiveBuffer;
/// <summary>
/// Initializes a new instance of the Mase class.
/// </summary>
/// <param name="period">The period for MASE calculation.</param>
/// <param name="period">The number of points over which to calculate the MASE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Mase(int period)
{
@@ -30,20 +51,14 @@ public class Mase : AbstractBase
Init();
}
/// <summary>
/// Initializes a new instance of the Mase class with a source object.
/// </summary>
/// <param name="source">The source object for event subscription.</param>
/// <param name="period">The period for MASE calculation.</param>
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the MASE.</param>
public Mase(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
}
/// <summary>
/// Initializes the Mase instance.
/// </summary>
public override void Init()
{
base.Init();
@@ -52,10 +67,6 @@ public class Mase : AbstractBase
_naiveBuffer.Clear();
}
/// <summary>
/// Manages the state of the Mase instance.
/// </summary>
/// <param name="isNew">Indicates if the input is new.</param>
protected override void ManageState(bool isNew)
{
if (isNew)
@@ -65,10 +76,6 @@ public class Mase : AbstractBase
}
}
/// <summary>
/// Performs the MASE calculation.
/// </summary>
/// <returns>The calculated MASE value.</returns>
protected override double Calculation()
{
ManageState(Input.IsNew);
@@ -76,9 +83,11 @@ public class Mase : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
// Naive forecast uses previous actual value
if (_actualBuffer.Count > 1)
{
_naiveBuffer.Add(_actualBuffer.GetSpan()[^2], Input.IsNew);
@@ -90,6 +99,10 @@ public class Mase : AbstractBase
return mase;
}
/// <summary>
/// Calculates the MASE value by comparing forecast error to naive forecast error.
/// </summary>
/// <returns>The calculated MASE value, or positive infinity if naive error is zero.</returns>
private double CalculateMase()
{
if (_actualBuffer.Count <= 1) return 0;
@@ -104,6 +117,9 @@ public class Mase : AbstractBase
return _naiveForecastError != 0 ? (sumAbsoluteError / _actualBuffer.Count) / _naiveForecastError : double.PositiveInfinity;
}
/// <summary>
/// Calculates the sum of absolute errors between actual and predicted values.
/// </summary>
private static double CalculateSumAbsoluteError(ReadOnlySpan<double> actualValues, ReadOnlySpan<double> predictedValues)
{
double sum = 0;
@@ -114,6 +130,9 @@ public class Mase : AbstractBase
return sum;
}
/// <summary>
/// Calculates the naive forecast error using the previous value as prediction.
/// </summary>
private static double CalculateNaiveForecastError(ReadOnlySpan<double> actualValues, ReadOnlySpan<double> naiveValues)
{
double sum = 0;
+35
View File
@@ -1,10 +1,42 @@
using System;
namespace QuanTAlib;
/// <summary>
/// MDA: Mean Directional Accuracy
/// A metric that measures how well a forecast predicts the direction of change
/// rather than the magnitude. MDA focuses on whether the predicted movement
/// (up or down) matches the actual movement.
/// </summary>
/// <remarks>
/// The MDA calculation process:
/// 1. For each consecutive pair of points:
/// - Calculate direction of actual change
/// - Calculate direction of predicted change
/// - Compare directions (match = 1, mismatch = 0)
/// 2. Average the directional matches
///
/// Key characteristics:
/// - Scale-independent (only considers direction)
/// - Range is 0 to 1 (easy interpretation)
/// - Useful for trend prediction evaluation
/// - Ignores magnitude of changes
/// - Equal weight to all directional changes
///
/// Formula:
/// MDA = (1/(n-1)) * Σ(sign(actual[t] - actual[t-1]) == sign(pred[t] - pred[t-1]))
///
/// Sources:
/// https://www.sciencedirect.com/science/article/abs/pii/S0169207016000121
/// "Evaluating Forecasting Performance" - International Journal of Forecasting
/// </remarks>
public class Mda : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the MDA.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Mda(int period)
{
if (period < 1)
@@ -18,6 +50,8 @@ public class Mda : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the MDA.</param>
public Mda(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +81,7 @@ public class Mda : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+35
View File
@@ -1,10 +1,42 @@
using System;
namespace QuanTAlib;
/// <summary>
/// ME: Mean Error
/// A basic error metric that measures the average difference between actual and
/// predicted values. Unlike MAE, it allows positive and negative errors to cancel
/// out, making it useful for detecting systematic bias in predictions.
/// </summary>
/// <remarks>
/// The ME calculation process:
/// 1. Calculates error (actual - predicted) for each point
/// 2. Sums all errors (allowing cancellation)
/// 3. Divides by the number of observations
///
/// Key characteristics:
/// - Same units as input data
/// - Can detect systematic bias
/// - Positive ME indicates underprediction
/// - Negative ME indicates overprediction
/// - Errors can cancel out
///
/// Formula:
/// ME = (1/n) * Σ(actual - predicted)
///
/// Sources:
/// https://en.wikipedia.org/wiki/Mean_signed_difference
/// https://www.statisticshowto.com/mean-error/
///
/// Note: Also known as Mean Bias Error (MBE) or Mean Signed Difference (MSD)
/// </remarks>
public class Me : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the ME.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Me(int period)
{
if (period < 1)
@@ -18,6 +50,8 @@ public class Me : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the ME.</param>
public Me(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +81,7 @@ public class Me : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+36
View File
@@ -1,10 +1,43 @@
using System;
namespace QuanTAlib;
/// <summary>
/// MPE: Mean Percentage Error
/// A percentage-based error metric that measures the average percentage difference
/// between actual and predicted values. Like ME, it allows positive and negative
/// errors to cancel out, but expresses the bias in percentage terms.
/// </summary>
/// <remarks>
/// The MPE calculation process:
/// 1. Calculates percentage error for each point
/// 2. Sums all percentage errors (allowing cancellation)
/// 3. Divides by the number of observations
///
/// Key characteristics:
/// - Scale-independent (percentage-based)
/// - Can detect systematic bias
/// - Positive MPE indicates underprediction
/// - Negative MPE indicates overprediction
/// - Cannot handle zero actual values
/// - Errors can cancel out
///
/// Formula:
/// MPE = (1/n) * Σ((actual - predicted) / actual) * 100%
///
/// Sources:
/// https://en.wikipedia.org/wiki/Mean_percentage_error
/// https://www.statisticshowto.com/mean-percentage-error/
///
/// Note: Similar to MAPE but allows error cancellation
/// </remarks>
public class Mpe : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the MPE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Mpe(int period)
{
if (period < 1)
@@ -18,6 +51,8 @@ public class Mpe : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the MPE.</param>
public Mpe(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +82,7 @@ public class Mpe : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+31 -34
View File
@@ -1,25 +1,42 @@
using System;
namespace QuanTAlib;
/// <summary>
/// Represents a Mean Squared Error calculator that measures the average of the squares
/// of the differences between actual values and predicted values.
/// MSE: Mean Squared Error
/// A fundamental error metric that measures the average of squared differences
/// between predicted and actual values. MSE heavily penalizes large errors due
/// to the squaring operation.
/// </summary>
/// <remarks>
/// The Mse class calculates the Mean Squared Error using a circular buffer
/// to efficiently manage the data points within the specified period.
/// The MSE calculation process:
/// 1. Calculates error (actual - predicted) for each point
/// 2. Squares each error value
/// 3. Averages the squared errors
///
/// Key characteristics:
/// - Heavily penalizes large errors
/// - Always non-negative
/// - Units are squared (harder to interpret)
/// - More sensitive to outliers than MAE
/// - Differentiable (useful for optimization)
///
/// Formula:
/// MSE = (1/n) * Σ(actual - predicted)²
///
/// Sources:
/// https://en.wikipedia.org/wiki/Mean_squared_error
/// https://www.statisticshowto.com/probability-and-statistics/statistics-definitions/mean-squared-error/
///
/// Note: Often used in optimization due to its mathematical properties
/// </remarks>
public class Mse : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <summary>
/// Initializes a new instance of the Mse class with the specified period.
/// </summary>
/// <param name="period">The period over which to calculate the Mean Squared Error.</param>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown when period is less than 1.
/// </exception>
/// <param name="period">The number of points over which to calculate the MSE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Mse(int period)
{
if (period < 1)
@@ -33,20 +50,14 @@ public class Mse : AbstractBase
Init();
}
/// <summary>
/// Initializes a new instance of the Mse class with the specified source and period.
/// </summary>
/// <param name="source">The source object to subscribe to for value updates.</param>
/// <param name="period">The period over which to calculate the Mean Squared Error.</param>
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the MSE.</param>
public Mse(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
pubEvent?.AddEventHandler(source, new ValueSignal(Sub));
}
/// <summary>
/// Initializes the Mse instance by clearing the buffers.
/// </summary>
public override void Init()
{
base.Init();
@@ -54,10 +65,6 @@ public class Mse : AbstractBase
_predictedBuffer.Clear();
}
/// <summary>
/// Manages the state of the Mse instance based on whether new values are being processed.
/// </summary>
/// <param name="isNew">Indicates whether the current inputs are new values.</param>
protected override void ManageState(bool isNew)
{
if (isNew)
@@ -67,17 +74,6 @@ public class Mse : AbstractBase
}
}
/// <summary>
/// Performs the Mean Squared Error calculation for the current period.
/// </summary>
/// <returns>
/// The calculated Mean Squared Error value for the current period.
/// </returns>
/// <remarks>
/// This method calculates the Mean Squared Error using the formula:
/// MSE = sum((actual - predicted)^2) / n
/// where actual is each actual value, predicted is each predicted value, and n is the number of values.
/// </remarks>
protected override double Calculation()
{
ManageState(Input.IsNew);
@@ -85,6 +81,7 @@ public class Mse : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+36
View File
@@ -1,10 +1,43 @@
using System;
namespace QuanTAlib;
/// <summary>
/// MSLE: Mean Squared Logarithmic Error
/// A variation of MSE that operates on log-transformed values. MSLE is particularly
/// useful for data with exponential growth or when errors in larger values should
/// not be penalized more heavily than errors in smaller values.
/// </summary>
/// <remarks>
/// The MSLE calculation process:
/// 1. Adds 1 to both actual and predicted values (to handle zeros)
/// 2. Takes natural log of both values
/// 3. Calculates squared difference of logs
/// 4. Averages the squared differences
///
/// Key characteristics:
/// - Scale-independent due to log transformation
/// - Penalizes underestimates more than overestimates
/// - Handles exponential trends well
/// - More sensitive to relative differences
/// - Can handle zero values (adds 1 before log)
///
/// Formula:
/// MSLE = (1/n) * Σ(log(actual + 1) - log(predicted + 1))²
///
/// Sources:
/// https://scikit-learn.org/stable/modules/model_evaluation.html#mean-squared-logarithmic-error
/// https://medium.com/analytics-vidhya/root-mean-square-log-error-rmse-vs-rmlse-935c6cc1802a
///
/// Note: Often used in cases where target values follow exponential growth
/// </remarks>
public class Msle : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the MSLE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Msle(int period)
{
if (period < 1)
@@ -18,6 +51,8 @@ public class Msle : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the MSLE.</param>
public Msle(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +82,7 @@ public class Msle : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+35
View File
@@ -1,10 +1,42 @@
using System;
namespace QuanTAlib;
/// <summary>
/// RAE: Relative Absolute Error
/// A normalized error metric that compares the total absolute error to the total
/// magnitude of actual values. RAE provides a scale-independent measure of error
/// that is robust to the overall magnitude of the data.
/// </summary>
/// <remarks>
/// The RAE calculation process:
/// 1. Calculates sum of absolute errors
/// 2. Calculates sum of absolute actual values
/// 3. Divides total error by total actual magnitude
///
/// Key characteristics:
/// - Scale-independent (normalized by actual values)
/// - Range typically between 0 and 1
/// - Easy to interpret (0 is perfect, 1 means error equals data magnitude)
/// - Robust to data scale changes
/// - Less sensitive to outliers than squared errors
///
/// Formula:
/// RAE = Σ|actual - predicted| / Σ|actual|
///
/// Sources:
/// https://en.wikipedia.org/wiki/Relative_absolute_error
/// https://www.sciencedirect.com/topics/engineering/relative-absolute-error
///
/// Note: Values greater than 1 indicate predictions worse than using zero
/// </remarks>
public class Rae : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the RAE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Rae(int period)
{
if (period < 1)
@@ -18,6 +50,8 @@ public class Rae : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the RAE.</param>
public Rae(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +81,7 @@ public class Rae : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+36
View File
@@ -1,10 +1,43 @@
using System;
namespace QuanTAlib;
/// <summary>
/// RMSE: Root Mean Square Error
/// A widely used error metric that measures the square root of the average squared
/// differences between predicted and actual values. RMSE provides error measurements
/// in the same units as the original data.
/// </summary>
/// <remarks>
/// The RMSE calculation process:
/// 1. Calculates error (actual - predicted) for each point
/// 2. Squares each error value
/// 3. Averages the squared errors
/// 4. Takes the square root of the average
///
/// Key characteristics:
/// - Same units as input data (unlike MSE)
/// - Penalizes large errors more than small ones
/// - Always non-negative
/// - More interpretable than MSE
/// - Commonly used in regression problems
///
/// Formula:
/// RMSE = √((1/n) * Σ(actual - predicted)²)
///
/// Sources:
/// https://en.wikipedia.org/wiki/Root-mean-square_deviation
/// https://www.statisticshowto.com/probability-and-statistics/regression-analysis/rmse-root-mean-square-error/
///
/// Note: Square root of MSE, making it more interpretable in original units
/// </remarks>
public class Rmse : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the RMSE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Rmse(int period)
{
if (period < 1)
@@ -18,6 +51,8 @@ public class Rmse : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the RMSE.</param>
public Rmse(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +82,7 @@ public class Rmse : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+37
View File
@@ -1,10 +1,44 @@
using System;
namespace QuanTAlib;
/// <summary>
/// RMSLE: Root Mean Square Logarithmic Error
/// A variation of RMSE that operates on log-transformed values. RMSLE is particularly
/// useful for data with exponential growth or when relative errors in larger values
/// should be treated similarly to relative errors in smaller values.
/// </summary>
/// <remarks>
/// The RMSLE calculation process:
/// 1. Adds 1 to both actual and predicted values (to handle zeros)
/// 2. Takes natural log of both values
/// 3. Calculates squared difference of logs
/// 4. Averages the squared differences
/// 5. Takes the square root
///
/// Key characteristics:
/// - Scale-independent due to log transformation
/// - Penalizes underestimates more than overestimates
/// - Handles exponential trends well
/// - More sensitive to relative differences
/// - Can handle zero values (adds 1 before log)
///
/// Formula:
/// RMSLE = √((1/n) * Σ(log(actual + 1) - log(predicted + 1))²)
///
/// Sources:
/// https://www.kaggle.com/wiki/RootMeanSquaredLogarithmicError
/// https://medium.com/analytics-vidhya/root-mean-square-log-error-rmse-vs-rmlse-935c6cc1802a
///
/// Note: Square root of MSLE, useful for data with exponential growth
/// </remarks>
public class Rmsle : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the RMSLE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Rmsle(int period)
{
if (period < 1)
@@ -18,6 +52,8 @@ public class Rmsle : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the RMSLE.</param>
public Rmsle(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +83,7 @@ public class Rmsle : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+36
View File
@@ -1,10 +1,43 @@
using System;
using System.Linq;
namespace QuanTAlib;
/// <summary>
/// RSE: Relative Squared Error
/// A normalized error metric that compares the squared error of predictions to
/// the variance of actual values. RSE provides a scale-independent measure of
/// prediction accuracy relative to the inherent variability in the data.
/// </summary>
/// <remarks>
/// The RSE calculation process:
/// 1. Calculates sum of squared prediction errors
/// 2. Calculates sum of squared deviations from mean (variance)
/// 3. Divides squared error by variance and takes square root
///
/// Key characteristics:
/// - Scale-independent (normalized by data variance)
/// - Range typically between 0 and 1
/// - Easy interpretation relative to data variance
/// - Penalizes large errors more than small ones
/// - Accounts for data variability
///
/// Formula:
/// RSE = √(Σ(actual - predicted)² / Σ(actual - mean(actual))²)
///
/// Sources:
/// https://en.wikipedia.org/wiki/Relative_squared_error
/// https://www.sciencedirect.com/topics/engineering/relative-squared-error
///
/// Note: Values less than 1 indicate predictions better than using mean
/// </remarks>
public class Rse : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the RSE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Rse(int period)
{
if (period < 1)
@@ -18,6 +51,8 @@ public class Rse : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the RSE.</param>
public Rse(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +82,7 @@ public class Rse : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+36
View File
@@ -1,10 +1,43 @@
using System;
using System.Linq;
namespace QuanTAlib;
/// <summary>
/// R-squared: Coefficient of Determination
/// A statistical measure that represents the proportion of variance in the dependent
/// variable that is predictable from the independent variable. R-squared provides
/// a measure of how well the predictions approximate the actual data.
/// </summary>
/// <remarks>
/// The R-squared calculation process:
/// 1. Calculates total sum of squares (variance from mean)
/// 2. Calculates residual sum of squares (prediction errors)
/// 3. Computes 1 - (residual SS / total SS)
///
/// Key characteristics:
/// - Range is typically 0 to 1
/// - 1 indicates perfect prediction
/// - 0 indicates prediction no better than mean
/// - Scale-independent
/// - Widely used in regression analysis
///
/// Formula:
/// R² = 1 - (Σ(actual - predicted)² / Σ(actual - mean(actual))²)
///
/// Sources:
/// https://en.wikipedia.org/wiki/Coefficient_of_determination
/// https://www.statisticshowto.com/probability-and-statistics/coefficient-of-determination-r-squared/
///
/// Note: Can be negative if predictions are worse than using the mean
/// </remarks>
public class Rsquared : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the R-squared value.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Rsquared(int period)
{
if (period < 1)
@@ -18,6 +51,8 @@ public class Rsquared : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the R-squared value.</param>
public Rsquared(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +82,7 @@ public class Rsquared : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);
+35
View File
@@ -1,10 +1,42 @@
using System;
namespace QuanTAlib;
/// <summary>
/// SMAPE: Symmetric Mean Absolute Percentage Error
/// A variation of MAPE that treats positive and negative errors symmetrically.
/// SMAPE uses the average of actual and predicted values in the denominator,
/// making it more robust than MAPE for values close to zero.
/// </summary>
/// <remarks>
/// The SMAPE calculation process:
/// 1. Calculates absolute difference between actual and predicted
/// 2. Divides by sum of absolute actual and predicted values
/// 3. Averages these ratios and multiplies by 200%
///
/// Key characteristics:
/// - Symmetric treatment of errors
/// - Range is 0% to 200%
/// - More robust than MAPE near zero
/// - Scale-independent
/// - Handles both positive and negative values
///
/// Formula:
/// SMAPE = (200/n) * Σ|actual - predicted| / (|actual| + |predicted|)
///
/// Sources:
/// https://en.wikipedia.org/wiki/Symmetric_mean_absolute_percentage_error
/// https://www.sciencedirect.com/science/article/abs/pii/0169207085900059
///
/// Note: More stable than MAPE when actual values are close to zero
/// </remarks>
public class Smape : AbstractBase
{
private readonly CircularBuffer _actualBuffer;
private readonly CircularBuffer _predictedBuffer;
/// <param name="period">The number of points over which to calculate the SMAPE.</param>
/// <exception cref="ArgumentOutOfRangeException">Thrown when period is less than 1.</exception>
public Smape(int period)
{
if (period < 1)
@@ -18,6 +50,8 @@ public class Smape : AbstractBase
Init();
}
/// <param name="source">The data source object that publishes updates.</param>
/// <param name="period">The number of points over which to calculate the SMAPE.</param>
public Smape(object source, int period) : this(period)
{
var pubEvent = source.GetType().GetEvent("Pub");
@@ -47,6 +81,7 @@ public class Smape : AbstractBase
double actual = Input.Value;
_actualBuffer.Add(actual, Input.IsNew);
// If no predicted value provided, use mean of actual values
double predicted = double.IsNaN(Input2.Value) ? _actualBuffer.Average() : Input2.Value;
_predictedBuffer.Add(predicted, Input.IsNew);