@@ -3,27 +3,46 @@ export RobustLoss,
3
3
BisquareRho, Bisquare, LogisticRho, Logistic,
4
4
FairRho, Fair, TalwarRho, Talwar, QuantileRho, Quantile
5
5
6
+ #=
7
+ In the non-penalised case:
8
+
9
+ β⋆ = arg min ∑ ρ(yᵢ - ⟨xᵢ, β⟩)
10
+
11
+ where ρ is a weighing function such as, for instance, the pinball loss for
12
+ the quantile regression.
13
+
14
+ It is useful to define the following quantities:
15
+
16
+ ψ(r) = ρ'(r) (first derivative)
17
+ ϕ(r) = ψ'(r) (second derivative)
18
+ ω(r) = ψ(r)/r (weighing function used for IWLS), a threshold can be passed
19
+ to clip weights
20
+
21
+ Some refs:
22
+ - https://josephsalmon.eu/enseignement/UW/STAT593/QuantileRegression.pdf
23
+ =#
24
+
6
25
abstract type RobustRho end
7
26
8
- abstract type RobustRho1P{δ} <: RobustRho end # one parameter
27
+ # robust rho with only one parameter
28
+ abstract type RobustRho1P{δ} <: RobustRho end
9
29
10
30
struct RobustLoss{ρ} <: AtomicLoss where ρ <: RobustRho
11
31
rho: :ρ
12
32
end
13
33
14
- (rl:: RobustLoss )(x :: AVR , y:: AVR ) = rl (x .- y )
15
- (rl:: RobustLoss )(r:: AVR ) = rl. rho (r)
34
+ (rl:: RobustLoss )(Xβ :: AVR , y:: AVR ) = rl (y .- Xβ )
35
+ (rl:: RobustLoss )(r:: AVR ) = rl. rho (r)
16
36
17
- # ψ(r) = ρ'(r) (first derivative)
18
- # ω(r) = ψ(r)/r (weighing function) a thresh can be passed to clip weights
19
- # ϕ(r) = ψ'(r) (second derivative)
20
37
21
38
"""
22
39
$TYPEDEF
23
40
24
41
Huber weighing of the residuals corresponding to
25
42
26
43
``ρ(z) = z²/2`` if `|z|≤δ` and `ρ(z)=δ(|z|-δ/2)` otherwise.
44
+
45
+ Note: symmetric weighing.
27
46
"""
28
47
struct HuberRho{δ} <: RobustRho1P{δ}
29
48
HuberRho (δ:: Real = 1.0 ; delta:: Real = δ) = new {delta} ()
@@ -33,7 +52,7 @@ Huber(δ::Real=1.0; delta::Real=δ) = HuberRho(delta)
33
52
(:: HuberRho{δ} )(r:: AVR ) where δ = begin
34
53
ar = abs .(r)
35
54
w = ar .<= δ
36
- return sum ( r . ^2 / 2 .* w .+ δ . * (ar . - δ/ 2 ) .* . ! w )
55
+ return sum ( @. ifelse (w, r ^ 2 / 2 , δ * (ar - δ/ 2 ) ) )
37
56
end
38
57
39
58
ψ (:: Type{HuberRho{δ}} ) where δ = (r, w) -> r * w + δ * sign (r) * (1.0 - w)
@@ -47,6 +66,8 @@ $TYPEDEF
47
66
Andrews weighing of the residuals corresponding to
48
67
49
68
``ρ(z) = -cos(πz/δ)/(π/δ)²`` if `|z|≤δ` and `ρ(δ)` otherwise.
69
+
70
+ Note: symmetric weighing.
50
71
"""
51
72
struct AndrewsRho{δ} <: RobustRho1P{δ}
52
73
AndrewsRho (δ:: Real = 1.0 ; delta:: Real = δ) = new {delta} ()
@@ -58,7 +79,7 @@ Andrews(δ::Real=1.0; delta::Real=δ) = AndrewsRho(delta)
58
79
w = ar .<= δ
59
80
c = π/ δ
60
81
κ = (δ/ π)^ 2
61
- return sum ( - cos . (c . * r) . * κ .* w .+ κ .* . ! w )
82
+ return sum ( @. ifelse (w, - cos (c * r) * κ, κ) )
62
83
end
63
84
64
85
# Note, sinc(x) = sin(πx)/πx, well defined everywhere
@@ -74,6 +95,8 @@ $TYPEDEF
74
95
Bisquare weighing of the residuals corresponding to
75
96
76
97
``ρ(z) = δ²/6 (1-(1-(z/δ)²)³)`` if `|z|≤δ` and `δ²/6` otherwise.
98
+
99
+ Note: symmetric weighing.
77
100
"""
78
101
struct BisquareRho{δ} <: RobustRho1P{δ}
79
102
BisquareRho (δ:: Real = 1.0 ; delta:: Real = δ) = new {delta} ()
@@ -84,7 +107,7 @@ Bisquare(δ::Real=1.0; delta::Real=δ) = BisquareRho(delta)
84
107
ar = abs .(r)
85
108
w = ar .<= δ
86
109
κ = δ^ 2 / 6
87
- return sum ( κ * (1.0 . - (1.0 . - (r . / δ). ^ 2 ). ^ 3 ) .* w + κ .* . ! w )
110
+ return sum ( @. ifelse (w, κ * (1 - (1 - (r / δ)^ 2 )^ 3 ), κ) )
88
111
end
89
112
90
113
ψ (:: Type{BisquareRho{δ}} ) where δ = (r, w) -> w * r * (1.0 - (r / δ)^ 2 )^ 2
@@ -97,14 +120,16 @@ $TYPEDEF
97
120
Logistic weighing of the residuals corresponding to
98
121
99
122
``ρ(z) = δ² log(cosh(z/δ))``
123
+
124
+ Note: symmetric weighing.
100
125
"""
101
126
struct LogisticRho{δ} <: RobustRho1P{δ}
102
127
LogisticRho (δ:: Real = 1.0 ; delta:: Real = δ) = new {delta} ()
103
128
end
104
129
Logistic (δ:: Real = 1.0 ; delta:: Real = δ) = LogisticRho (delta)
105
130
106
131
(:: LogisticRho{δ} )(r:: AVR ) where δ = begin
107
- return sum ( δ^ 2 . * log . (cosh . (r . / δ)) )
132
+ return sum ( @. δ^ 2 * log (cosh (r / δ)) )
108
133
end
109
134
110
135
# similar to sinc, to avoid NaNs if tanh(0)/0 (lim is 1.0)
@@ -121,15 +146,17 @@ $TYPEDEF
121
146
Fair weighing of the residuals corresponding to
122
147
123
148
``ρ(z) = δ² (|z|/δ - log(1+|z|/δ))``
149
+
150
+ Note: symmetric weighing.
124
151
"""
125
152
struct FairRho{δ} <: RobustRho1P{δ}
126
153
FairRho (δ:: Real = 1.0 ; delta:: Real = δ) = new {delta} ()
127
154
end
128
155
Fair (δ:: Real = 1.0 ; delta:: Real = δ) = FairRho (delta)
129
156
130
157
(:: FairRho{δ} )(r:: AVR ) where δ = begin
131
- sr = abs . (r) . / δ
132
- return sum ( δ^ 2 . * (sr . - log1p . (sr)) )
158
+ sr = @. abs (r) / δ
159
+ return sum ( @. δ^ 2 * (sr - log1p (sr)) )
133
160
end
134
161
135
162
ψ (:: Type{FairRho{δ}} ) where δ = (r, _) -> δ * r / (abs (r) + δ)
@@ -143,15 +170,17 @@ $TYPEDEF
143
170
Talwar weighing of the residuals corresponding to
144
171
145
172
``ρ(z) = z²/2`` if `|z|≤δ` and `ρ(z)=ρ(δ)` otherwise.
173
+
174
+ Note: symmetric weighing.
146
175
"""
147
176
struct TalwarRho{δ} <: RobustRho1P{δ}
148
177
TalwarRho (δ:: Real = 1.0 ; delta:: Real = δ) = new {delta} ()
149
178
end
150
179
Talwar (δ:: Real = 1.0 ; delta:: Real = δ) = TalwarRho (delta)
151
180
152
181
(:: TalwarRho{δ} )(r:: AVR ) where δ = begin
153
- w = abs . (r) . <= δ
154
- return sum ( r . ^2 . / 2 .* w .+ δ^ 2 / 2 .* . ! w )
182
+ w = @. abs (r) <= δ
183
+ return sum ( @. ifelse (w, r ^ 2 / 2 , δ^ 2 / 2 ) )
155
184
end
156
185
157
186
ψ (:: Type{TalwarRho{δ}} ) where δ = (r, w) -> w * r
@@ -164,7 +193,11 @@ $TYPEDEF
164
193
165
194
Quantile regression weighing of the residuals corresponding to
166
195
167
- ``ρ(z) = z(δ - 1(z<0))``
196
+ ``ρ(z) = -z(δ - 1(z>=0))``
197
+
198
+ Note: asymetric weighing, the "-" sign is because similar libraries like
199
+ quantreg for instance define the residual as `y-Xθ` while we do the opposite
200
+ (out of convenience for gradients etc).
168
201
"""
169
202
struct QuantileRho{δ} <: RobustRho1P{δ}
170
203
QuantileRho (δ:: Real = 1.0 ; delta:: Real = δ) = new {delta} ()
173
206
Quantile (δ:: Real = 1.0 ; delta:: Real = δ) = QuantileRho (delta)
174
207
175
208
(:: QuantileRho{δ} )(r:: AVR ) where δ = begin
176
- return sum ( r . * (δ . - (r .<= 0. 0 )) )
209
+ return sum ( @. - r * (δ - (r >= 0 )) )
177
210
end
178
211
179
- ψ (:: Type{QuantileRho{δ}} ) where δ = (r, _) -> (δ - (r < = 0.0 ))
180
- ω (:: Type{QuantileRho{δ}} , τ) where δ = (r, _) -> (δ - (r < = 0.0 )) / clip (r, τ)
212
+ ψ (:: Type{QuantileRho{δ}} ) where δ = (r, _) -> ((r > = 0.0 ) - δ )
213
+ ω (:: Type{QuantileRho{δ}} , τ) where δ = (r, _) -> ((r > = 0.0 ) - δ ) / clip (- r, τ)
181
214
ϕ (:: Type{QuantileRho{δ}} ) where δ = (_, _) -> error (" Newton(CG) not available for Quantile Reg." )
0 commit comments