1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#!/usr/bin/env python3
# Copyright (c) 2021 Marco Cerliani, MIT License <https://github.com/cerlymarco/linear-tree>
import numpy as np
SCORING = {
"linear": lambda y, yh: y - yh,
"square": lambda y, yh: np.square(y - yh),
"absolute": lambda y, yh: np.abs(y - yh),
"exponential": lambda y, yh: 1 - np.exp(-np.abs(y - yh)),
"poisson": lambda y, yh: yh.clip(1e-6) - y * np.log(yh.clip(1e-6)),
"hamming": lambda y, yh, classes: (y != yh).astype(int),
"entropy": lambda y, yh, classes: np.sum(
list(
map(
lambda c: -(y == c[1]).astype(int) * np.log(yh[:, c[0]]),
enumerate(classes),
)
),
axis=0,
),
}
def _normalize_score(scores, weights=None):
"""Normalize scores according to weights"""
if weights is None:
return scores.mean()
else:
return np.mean(np.dot(scores.T, weights) / weights.sum())
def mse(model, X, y, weights=None, **largs):
"""Mean Squared Error"""
pred = model.predict(X)
scores = SCORING["square"](y, pred)
return _normalize_score(scores, weights)
def rmse(model, X, y, weights=None, **largs):
"""Root Mean Squared Error"""
return np.sqrt(mse(model, X, y, weights, **largs))
def mae(model, X, y, weights=None, **largs):
"""Mean Absolute Error"""
pred = model.predict(X)
scores = SCORING["absolute"](y, pred)
return _normalize_score(scores, weights)
def poisson(model, X, y, weights=None, **largs):
"""Poisson Loss"""
if np.any(y < 0):
raise ValueError(
"Some value(s) of y are negative which is"
" not allowed for Poisson regression."
)
pred = model.predict(X)
scores = SCORING["poisson"](y, pred)
return _normalize_score(scores, weights)
def hamming(model, X, y, weights=None, **largs):
"""Hamming Loss"""
pred = model.predict(X)
scores = SCORING["hamming"](y, pred, None)
return _normalize_score(scores, weights)
def crossentropy(model, X, y, classes, weights=None, **largs):
"""Cross Entropy Loss"""
pred = model.predict_proba(X).clip(1e-5, 1 - 1e-5)
scores = SCORING["entropy"](y, pred, classes)
return _normalize_score(scores, weights)
|