1
1
"""The NGBoost Beta distribution and scores"""
2
- from scipy .stats import beta as dist
3
- from scipy .special import digamma , polygamma
4
2
import numpy as np
3
+ from scipy .special import digamma , polygamma
4
+ from scipy .stats import beta as dist
5
5
6
6
from ngboost .distns .distn import RegressionDistn
7
7
from ngboost .scores import LogScore
8
8
9
+
9
10
class BetaLogScore (LogScore ):
10
11
"""Log score for the Beta distribution."""
12
+
11
13
def score (self , Y ):
12
14
"""Calculate the log score for the Beta distribution."""
13
15
return - self .dist .logpdf (Y )
14
16
15
17
def d_score (self , Y ):
16
18
"""Calculate the derivative of the log score with respect to the parameters."""
17
- D = np .zeros ((len (Y ), 2 )) # first col is dS/d(log(a)), second col is dS/d(log(b))
18
- D [:, 0 ] = - self .a * ( digamma (self .a + self .b ) - digamma (self .a ) + np .log (Y ))
19
- D [:, 1 ] = - self .b * ( digamma (self .a + self .b ) - digamma (self .b ) + np .log (1 - Y ))
19
+ D = np .zeros (
20
+ (len (Y ), 2 )
21
+ ) # first col is dS/d(log(a)), second col is dS/d(log(b))
22
+ D [:, 0 ] = - self .a * (digamma (self .a + self .b ) - digamma (self .a ) + np .log (Y ))
23
+ D [:, 1 ] = - self .b * (digamma (self .a + self .b ) - digamma (self .b ) + np .log (1 - Y ))
20
24
return D
21
25
22
26
def metric (self ):
23
27
"""Return the Fisher Information matrix for the Beta distribution."""
24
28
FI = np .zeros ((self .a .shape [0 ], 2 , 2 ))
25
29
trigamma_a_b = polygamma (1 , self .a + self .b )
26
- FI [:, 0 , 0 ] = self .a ** 2 * ( polygamma (1 , self .a ) - trigamma_a_b )
30
+ FI [:, 0 , 0 ] = self .a ** 2 * (polygamma (1 , self .a ) - trigamma_a_b )
27
31
FI [:, 0 , 1 ] = - self .a * self .b * trigamma_a_b
28
32
FI [:, 1 , 0 ] = - self .a * self .b * trigamma_a_b
29
- FI [:, 1 , 1 ] = self .b ** 2 * ( polygamma (1 , self .b ) - trigamma_a_b )
33
+ FI [:, 1 , 1 ] = self .b ** 2 * (polygamma (1 , self .b ) - trigamma_a_b )
30
34
return FI
31
35
36
+
32
37
class Beta (RegressionDistn ):
33
38
"""
34
39
Implements the Beta distribution for NGBoost.
@@ -39,35 +44,39 @@ class Beta(RegressionDistn):
39
44
"""
40
45
41
46
n_params = 2
42
- scores = [BetaLogScore ] # will implement this later
47
+ scores = [BetaLogScore ] # will implement this later
43
48
49
+ # pylint: disable=super-init-not-called
44
50
def __init__ (self , params ):
45
51
self ._params = params
46
52
47
53
# create other objects that will be useful later
48
54
self .log_a = params [0 ]
49
55
self .log_b = params [1 ]
50
- self .a = np .exp (params [0 ]) # since params[0] is log(a)
51
- self .b = np .exp (params [1 ]) # since params[1] is log(b)
56
+ self .a = np .exp (params [0 ]) # since params[0] is log(a)
57
+ self .b = np .exp (params [1 ]) # since params[1] is log(b)
52
58
self .dist = dist (a = self .a , b = self .b )
53
59
54
60
@staticmethod
55
61
def fit (Y ):
56
62
"""Fit the distribution to the data."""
57
63
# Use scipy's beta distribution to fit the parameters
64
+ # pylint: disable=unused-variable
58
65
a , b , loc , scale = dist .fit (Y , floc = 0 , fscale = 1 )
59
66
return np .array ([np .log (a ), np .log (b )])
60
67
61
68
def sample (self , m ):
62
69
"""Sample from the distribution."""
63
70
return np .array ([self .dist .rvs () for i in range (m )])
64
71
65
- def __getattr__ (self , name ): # gives us access to Beta.mean() required for RegressionDist.predict()
72
+ def __getattr__ (
73
+ self , name
74
+ ): # gives us access to Beta.mean() required for RegressionDist.predict()
66
75
if name in dir (self .dist ):
67
76
return getattr (self .dist , name )
68
77
return None
69
78
70
79
@property
71
80
def params (self ):
72
81
"""Return the parameters of the Beta distribution."""
73
- return {'a' : self .a , 'b' : self .b }
82
+ return {"a" : self .a , "b" : self .b }
0 commit comments