203 lines
5.7 KiB
Python
203 lines
5.7 KiB
Python
"""Unit tests for sientia metrics module."""
|
|
|
|
import pandas as pd
|
|
|
|
from model_manager.sientia.metrics import mae, mse, r2
|
|
|
|
|
|
def test_mse_perfect_predictions():
|
|
"""Test MSE with perfect predictions returns 0.0."""
|
|
real_data = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
predictions = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
|
|
result = mse(real_data, predictions)
|
|
|
|
assert result == 0.0
|
|
|
|
|
|
def test_mse_with_errors():
|
|
"""Test MSE calculation with prediction errors."""
|
|
real_data = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
predictions = pd.Series([1.5, 2.5, 3.5, 4.5, 5.5])
|
|
|
|
result = mse(real_data, predictions)
|
|
|
|
# MSE = mean((0.5^2, 0.5^2, 0.5^2, 0.5^2, 0.5^2)) = 0.25
|
|
assert result == 0.25
|
|
|
|
|
|
def test_mse_with_integer_input():
|
|
"""Test MSE handles integer input and converts to float64."""
|
|
real_data = pd.Series([1, 2, 3, 4, 5])
|
|
predictions = pd.Series([2, 3, 4, 5, 6])
|
|
|
|
result = mse(real_data, predictions)
|
|
|
|
# MSE = mean((1^2, 1^2, 1^2, 1^2, 1^2)) = 1.0
|
|
assert result == 1.0
|
|
|
|
|
|
def test_mse_with_large_errors():
|
|
"""Test MSE with large prediction errors."""
|
|
real_data = pd.Series([10.0, 20.0, 30.0])
|
|
predictions = pd.Series([5.0, 15.0, 25.0])
|
|
|
|
result = mse(real_data, predictions)
|
|
|
|
# MSE = mean((25, 25, 25)) = 25.0
|
|
assert result == 25.0
|
|
|
|
|
|
def test_mse_rounds_to_two_decimals():
|
|
"""Test MSE rounds result to 2 decimal places."""
|
|
real_data = pd.Series([1.111, 2.222, 3.333])
|
|
predictions = pd.Series([1.222, 2.333, 3.444])
|
|
|
|
result = mse(real_data, predictions)
|
|
|
|
# Result should be rounded to 2 decimals
|
|
assert isinstance(result, float)
|
|
assert len(str(result).split('.')[-1]) <= 2
|
|
|
|
|
|
def test_mae_perfect_predictions():
|
|
"""Test MAE with perfect predictions returns 0.0."""
|
|
real_data = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
predictions = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
|
|
result = mae(real_data, predictions)
|
|
|
|
assert result == 0.0
|
|
|
|
|
|
def test_mae_with_errors():
|
|
"""Test MAE calculation with prediction errors."""
|
|
real_data = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
predictions = pd.Series([1.5, 2.5, 3.5, 4.5, 5.5])
|
|
|
|
result = mae(real_data, predictions)
|
|
|
|
# MAE = mean(|0.5|, |0.5|, |0.5|, |0.5|, |0.5|) = 0.5
|
|
assert result == 0.5
|
|
|
|
|
|
def test_mae_with_integer_input():
|
|
"""Test MAE handles integer input and converts to float64."""
|
|
real_data = pd.Series([1, 2, 3, 4, 5])
|
|
predictions = pd.Series([2, 3, 4, 5, 6])
|
|
|
|
result = mae(real_data, predictions)
|
|
|
|
# MAE = mean(|1|, |1|, |1|, |1|, |1|) = 1.0
|
|
assert result == 1.0
|
|
|
|
|
|
def test_mae_with_negative_errors():
|
|
"""Test MAE with negative prediction errors (absolute value)."""
|
|
real_data = pd.Series([10.0, 20.0, 30.0])
|
|
predictions = pd.Series([15.0, 25.0, 35.0])
|
|
|
|
result = mae(real_data, predictions)
|
|
|
|
# MAE = mean(|5|, |5|, |5|) = 5.0
|
|
assert result == 5.0
|
|
|
|
|
|
def test_mae_rounds_to_two_decimals():
|
|
"""Test MAE rounds result to 2 decimal places."""
|
|
real_data = pd.Series([1.111, 2.222, 3.333])
|
|
predictions = pd.Series([1.222, 2.333, 3.444])
|
|
|
|
result = mae(real_data, predictions)
|
|
|
|
# Result should be rounded to 2 decimals
|
|
assert isinstance(result, float)
|
|
assert len(str(result).split('.')[-1]) <= 2
|
|
|
|
|
|
def test_r2_perfect_predictions():
|
|
"""Test R2 with perfect predictions returns 1.0."""
|
|
real_data = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
predictions = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
|
|
result = r2(real_data, predictions)
|
|
|
|
assert result == 1.0
|
|
|
|
|
|
def test_r2_with_good_predictions():
|
|
"""Test R2 calculation with good predictions."""
|
|
real_data = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
predictions = pd.Series([1.1, 2.1, 2.9, 4.1, 4.9])
|
|
|
|
result = r2(real_data, predictions)
|
|
|
|
# R2 should be close to 1.0 for good predictions
|
|
assert result > 0.9
|
|
assert result <= 1.0
|
|
|
|
|
|
def test_r2_with_integer_input():
|
|
"""Test R2 handles integer input and converts to float64."""
|
|
real_data = pd.Series([1, 2, 3, 4, 5])
|
|
predictions = pd.Series([1, 2, 3, 4, 5])
|
|
|
|
result = r2(real_data, predictions)
|
|
|
|
assert result == 1.0
|
|
|
|
|
|
def test_r2_with_poor_predictions():
|
|
"""Test R2 with poor predictions returns low score."""
|
|
real_data = pd.Series([1.0, 2.0, 3.0, 4.0, 5.0])
|
|
predictions = pd.Series([5.0, 4.0, 3.0, 2.0, 1.0])
|
|
|
|
result = r2(real_data, predictions)
|
|
|
|
# R2 should be negative for predictions worse than mean
|
|
assert result < 0
|
|
|
|
|
|
def test_r2_rounds_to_two_decimals():
|
|
"""Test R2 rounds result to 2 decimal places."""
|
|
real_data = pd.Series([1.111, 2.222, 3.333, 4.444, 5.555])
|
|
predictions = pd.Series([1.222, 2.333, 3.444, 4.555, 5.666])
|
|
|
|
result = r2(real_data, predictions)
|
|
|
|
# Result should be rounded to 2 decimals
|
|
assert isinstance(result, float)
|
|
assert len(str(result).split('.')[-1]) <= 2
|
|
|
|
|
|
def test_mse_with_mixed_positive_negative():
|
|
"""Test MSE with mixed positive and negative values."""
|
|
real_data = pd.Series([-5.0, -2.0, 0.0, 3.0, 7.0])
|
|
predictions = pd.Series([-4.0, -1.0, 1.0, 4.0, 8.0])
|
|
|
|
result = mse(real_data, predictions)
|
|
|
|
# MSE = mean((1^2, 1^2, 1^2, 1^2, 1^2)) = 1.0
|
|
assert result == 1.0
|
|
|
|
|
|
def test_mae_with_mixed_positive_negative():
|
|
"""Test MAE with mixed positive and negative values."""
|
|
real_data = pd.Series([-5.0, -2.0, 0.0, 3.0, 7.0])
|
|
predictions = pd.Series([-4.0, -1.0, 1.0, 4.0, 8.0])
|
|
|
|
result = mae(real_data, predictions)
|
|
|
|
# MAE = mean(|1|, |1|, |1|, |1|, |1|) = 1.0
|
|
assert result == 1.0
|
|
|
|
|
|
def test_r2_with_mixed_positive_negative():
|
|
"""Test R2 with mixed positive and negative values."""
|
|
real_data = pd.Series([-5.0, -2.0, 0.0, 3.0, 7.0])
|
|
predictions = pd.Series([-5.0, -2.0, 0.0, 3.0, 7.0])
|
|
|
|
result = r2(real_data, predictions)
|
|
|
|
assert result == 1.0
|