chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
# coding:utf-8
|
||||
from .metrics import *
|
||||
@@ -0,0 +1,25 @@
|
||||
# coding:utf-8
|
||||
import numpy as np
|
||||
|
||||
|
||||
def check_data(a, b):
|
||||
if not isinstance(a, np.ndarray):
|
||||
a = np.array(a)
|
||||
|
||||
if not isinstance(b, np.ndarray):
|
||||
b = np.array(b)
|
||||
|
||||
if type(a) != type(b):
|
||||
raise ValueError("Type mismatch: %s and %s" % (type(a), type(b)))
|
||||
|
||||
if a.size != b.size:
|
||||
raise ValueError("Arrays must be equal in length.")
|
||||
return a, b
|
||||
|
||||
|
||||
def validate_input(function):
|
||||
def wrapper(a, b):
|
||||
a, b = check_data(a, b)
|
||||
return function(a, b)
|
||||
|
||||
return wrapper
|
||||
@@ -0,0 +1,17 @@
|
||||
# coding:utf-8
|
||||
import math
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
def euclidean_distance(a, b):
|
||||
if isinstance(a, list) and isinstance(b, list):
|
||||
a = np.array(a)
|
||||
b = np.array(b)
|
||||
|
||||
return math.sqrt(sum((a - b) ** 2))
|
||||
|
||||
|
||||
def l2_distance(X):
|
||||
sum_X = np.sum(X * X, axis=1)
|
||||
return (-2 * np.dot(X, X.T) + sum_X).T + sum_X
|
||||
@@ -0,0 +1,90 @@
|
||||
# coding:utf-8
|
||||
import autograd.numpy as np
|
||||
|
||||
EPS = 1e-15
|
||||
|
||||
|
||||
def unhot(function):
|
||||
"""Convert one-hot representation into one column."""
|
||||
|
||||
def wrapper(actual, predicted):
|
||||
if len(actual.shape) > 1 and actual.shape[1] > 1:
|
||||
actual = actual.argmax(axis=1)
|
||||
if len(predicted.shape) > 1 and predicted.shape[1] > 1:
|
||||
predicted = predicted.argmax(axis=1)
|
||||
return function(actual, predicted)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def absolute_error(actual, predicted):
|
||||
return np.abs(actual - predicted)
|
||||
|
||||
|
||||
@unhot
|
||||
def classification_error(actual, predicted):
|
||||
return (actual != predicted).sum() / float(actual.shape[0])
|
||||
|
||||
|
||||
@unhot
|
||||
def accuracy(actual, predicted):
|
||||
return 1.0 - classification_error(actual, predicted)
|
||||
|
||||
|
||||
def mean_absolute_error(actual, predicted):
|
||||
return np.mean(absolute_error(actual, predicted))
|
||||
|
||||
|
||||
def squared_error(actual, predicted):
|
||||
return (actual - predicted) ** 2
|
||||
|
||||
|
||||
def squared_log_error(actual, predicted):
|
||||
return (np.log(np.array(actual) + 1) - np.log(np.array(predicted) + 1)) ** 2
|
||||
|
||||
|
||||
def mean_squared_log_error(actual, predicted):
|
||||
return np.mean(squared_log_error(actual, predicted))
|
||||
|
||||
|
||||
def mean_squared_error(actual, predicted):
|
||||
return np.mean(squared_error(actual, predicted))
|
||||
|
||||
|
||||
def root_mean_squared_error(actual, predicted):
|
||||
return np.sqrt(mean_squared_error(actual, predicted))
|
||||
|
||||
|
||||
def root_mean_squared_log_error(actual, predicted):
|
||||
return np.sqrt(mean_squared_log_error(actual, predicted))
|
||||
|
||||
|
||||
def logloss(actual, predicted):
|
||||
predicted = np.clip(predicted, EPS, 1 - EPS)
|
||||
loss = -np.sum(actual * np.log(predicted))
|
||||
return loss / float(actual.shape[0])
|
||||
|
||||
|
||||
def hinge(actual, predicted):
|
||||
return np.mean(np.max(1.0 - actual * predicted, 0.0))
|
||||
|
||||
|
||||
def binary_crossentropy(actual, predicted):
|
||||
predicted = np.clip(predicted, EPS, 1 - EPS)
|
||||
return np.mean(
|
||||
-np.sum(actual * np.log(predicted) + (1 - actual) * np.log(1 - predicted))
|
||||
)
|
||||
|
||||
|
||||
# aliases
|
||||
mse = mean_squared_error
|
||||
rmse = root_mean_squared_error
|
||||
mae = mean_absolute_error
|
||||
|
||||
|
||||
def get_metric(name):
|
||||
"""Return metric function by name"""
|
||||
try:
|
||||
return globals()[name]
|
||||
except Exception:
|
||||
raise ValueError("Invalid metric function.")
|
||||
@@ -0,0 +1 @@
|
||||
# coding:utf-8
|
||||
@@ -0,0 +1,88 @@
|
||||
from __future__ import division
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
from numpy.testing import assert_almost_equal
|
||||
|
||||
from mla.metrics.base import check_data, validate_input
|
||||
from mla.metrics.metrics import get_metric
|
||||
|
||||
|
||||
def test_data_validation():
|
||||
with pytest.raises(ValueError):
|
||||
check_data([], 1)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
check_data([1, 2, 3], [3, 2])
|
||||
|
||||
a, b = check_data([1, 2, 3], [3, 2, 1])
|
||||
|
||||
assert np.all(a == np.array([1, 2, 3]))
|
||||
assert np.all(b == np.array([3, 2, 1]))
|
||||
|
||||
|
||||
def metric(name):
|
||||
return validate_input(get_metric(name))
|
||||
|
||||
|
||||
def test_classification_error():
|
||||
f = metric("classification_error")
|
||||
assert f([1, 2, 3, 4], [1, 2, 3, 4]) == 0
|
||||
assert f([1, 2, 3, 4], [1, 2, 3, 5]) == 0.25
|
||||
assert f([1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 0, 0]) == (1.0 / 6)
|
||||
|
||||
|
||||
def test_absolute_error():
|
||||
f = metric("absolute_error")
|
||||
assert f([3], [5]) == [2]
|
||||
assert f([-1], [-4]) == [3]
|
||||
|
||||
|
||||
def test_mean_absolute_error():
|
||||
f = metric("mean_absolute_error")
|
||||
assert f([1, 2, 3], [1, 2, 3]) == 0
|
||||
assert f([1, 2, 3], [3, 2, 1]) == 4 / 3
|
||||
|
||||
|
||||
def test_squared_error():
|
||||
f = metric("squared_error")
|
||||
assert f([1], [1]) == [0]
|
||||
assert f([3], [1]) == [4]
|
||||
|
||||
|
||||
def test_squared_log_error():
|
||||
f = metric("squared_log_error")
|
||||
assert f([1], [1]) == [0]
|
||||
assert f([3], [1]) == [np.log(2) ** 2]
|
||||
assert f([np.exp(2) - 1], [np.exp(1) - 1]) == [1.0]
|
||||
|
||||
|
||||
def test_mean_squared_log_error():
|
||||
f = metric("mean_squared_log_error")
|
||||
assert f([1, 2, 3], [1, 2, 3]) == 0
|
||||
assert f([1, 2, 3, np.exp(1) - 1], [1, 2, 3, np.exp(2) - 1]) == 0.25
|
||||
|
||||
|
||||
def test_root_mean_squared_log_error():
|
||||
f = metric("root_mean_squared_log_error")
|
||||
assert f([1, 2, 3], [1, 2, 3]) == 0
|
||||
assert f([1, 2, 3, np.exp(1) - 1], [1, 2, 3, np.exp(2) - 1]) == 0.5
|
||||
|
||||
|
||||
def test_mean_squared_error():
|
||||
f = metric("mean_squared_error")
|
||||
assert f([1, 2, 3], [1, 2, 3]) == 0
|
||||
assert f(range(1, 5), [1, 2, 3, 6]) == 1
|
||||
|
||||
|
||||
def test_root_mean_squared_error():
|
||||
f = metric("root_mean_squared_error")
|
||||
assert f([1, 2, 3], [1, 2, 3]) == 0
|
||||
assert f(range(1, 5), [1, 2, 3, 5]) == 0.5
|
||||
|
||||
|
||||
def test_multiclass_logloss():
|
||||
f = metric("logloss")
|
||||
assert_almost_equal(f([1], [1]), 0)
|
||||
assert_almost_equal(f([1, 1], [1, 1]), 0)
|
||||
assert_almost_equal(f([1], [0.5]), -np.log(0.5))
|
||||
Reference in New Issue
Block a user