Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat> Co-authored-by: Warp <agent@warp.dev>
4.8 KiB
ME: Mean Error (Mean Bias Error)
"Sometimes you need to know not just how wrong you are, but which direction you're wrong in."
Mean Error (ME), also known as Mean Bias Error, measures the average error between actual and predicted values while preserving the sign. Unlike MAE, ME reveals systematic bias in predictions: whether a model consistently over-predicts or under-predicts.
Historical Context
ME is one of the fundamental error metrics in statistics and forecasting. While MAE and MSE focus on error magnitude, ME fills the critical role of detecting directional bias. A model could have low MAE but significant ME, indicating consistent over or under-prediction that cancels out when measuring magnitude alone.
Architecture & Physics
ME preserves the sign of errors, allowing positive and negative errors to cancel each other. This makes it ideal for detecting systematic bias but unsuitable for measuring prediction accuracy alone.
Properties
- Can be negative: ME can be positive, negative, or zero
- Positive ME: Model under-predicts (actual > predicted on average)
- Negative ME: Model over-predicts (actual < predicted on average)
- Zero ME: No systematic bias (but not necessarily accurate)
- Same units: ME is in the same units as the original data
- Cancellation: Errors can cancel out, hiding large individual errors
Mathematical Foundation
1. Error Calculation
For each observation, calculate the signed difference between actual and predicted values:
e_i = y_i - \hat{y}_i
Where:
y_i= actual value\hat{y}_i= predicted value
2. Mean Calculation
Average the errors over the period:
ME = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)
3. Running Update (O(1))
QuanTAlib uses a ring buffer with running sum for O(1) updates:
S_{new} = S_{old} - e_{oldest} + e_{newest}
ME = \frac{S_{new}}{n}
Implementation Details
Usage Patterns
// Streaming mode - update with each new observation
var me = new Me(period: 20);
var result = me.Update(actualValue, predictedValue);
// Batch mode - calculate for entire series
var results = Me.Calculate(actualSeries, predictedSeries, period: 20);
// Span mode - zero-allocation for high performance
Me.Batch(actualSpan, predictedSpan, outputSpan, period: 20);
Parameters
| Parameter | Type | Description |
|---|---|---|
| period | int | Lookback window for averaging (must be > 0) |
Properties
| Property | Type | Description |
|---|---|---|
| Last | TValue | Most recent ME value |
| IsHot | bool | True when buffer is full |
| Name | string | Indicator name (e.g., "Me(20)") |
| WarmupPeriod | int | Number of periods before valid output |
Performance Profile
| Metric | Score | Notes |
|---|---|---|
| Throughput | ~10 ns/bar | O(1) update complexity |
| Allocations | 0 | Uses pre-allocated ring buffer |
| Complexity | O(1) | Constant time per update |
| Accuracy | 10/10 | Exact calculation |
| Timeliness | 9/10 | No lag beyond the period |
| Smoothness | 7/10 | Moderate smoothing |
Interpretation
| ME Value | Interpretation |
|---|---|
| ME > 0 | Systematic under-prediction (actual > predicted) |
| ME = 0 | No systematic bias |
| ME < 0 | Systematic over-prediction (actual < predicted) |
Comparison with Other Metrics
| Metric | Shows Bias | Units | Use Case |
|---|---|---|---|
| ME | Yes | Same as data | Detect systematic bias |
| MAE | No | Same as data | Average error magnitude |
| MSE | No | Squared units | Penalize large errors |
| MPE | Yes | Percentage | Relative bias |
Common Use Cases
- Bias Detection: Identify if a model consistently over or under-predicts
- Model Calibration: Use ME to adjust model outputs
- Forecast Evaluation: Distinguish between random errors and systematic bias
- Trading Signals: Detect directional bias in price predictions
Warning: Cancellation Problem
ME can be misleading when errors cancel out:
var me = new Me(4);
me.Update(110, 100); // Error: +10
me.Update(90, 100); // Error: -10
me.Update(110, 100); // Error: +10
me.Update(90, 100); // Error: -10
// ME = 0, but individual errors are large!
Always use ME alongside MAE or MSE to get a complete picture.
Edge Cases
- Identical Values: Returns 0 when actual equals predicted
- NaN Handling: Uses last valid value substitution
- Single Input: Not supported (requires two series)
- Period = 1: Returns current signed error
- Balanced Errors: Can return 0 even with large individual errors