def test_binomial_deviance(): # Check binomial deviance loss. # Check against alternative definitions in ESLII. bd = BinomialDeviance(2) # pred has the same BD for y in {0, 1} assert (bd(np.array([0.0]), np.array([0.0])) == bd(np.array([1.0]), np.array([0.0]))) assert_almost_equal( bd(np.array([1.0, 1.0, 1.0]), np.array([100.0, 100.0, 100.0])), 0.0) assert_almost_equal( bd(np.array([1.0, 0.0, 0.0]), np.array([100.0, -100.0, -100.0])), 0) # check if same results as alternative definition of deviance (from ESLII) alt_dev = lambda y, pred: np.mean( np.logaddexp(0.0, -2.0 * (2.0 * y - 1) * pred)) test_data = [(np.array([1.0, 1.0, 1.0]), np.array([100.0, 100.0, 100.0])), (np.array([0.0, 0.0, 0.0]), np.array([100.0, 100.0, 100.0])), (np.array([0.0, 0.0, 0.0]), np.array([-100.0, -100.0, -100.0])), (np.array([1.0, 1.0, 1.0]), np.array([-100.0, -100.0, -100.0]))] for datum in test_data: assert_almost_equal(bd(*datum), alt_dev(*datum)) # check the gradient against the alt_ng = lambda y, pred: (2 * y - 1) / (1 + np.exp(2 * (2 * y - 1) * pred)) for datum in test_data: assert_almost_equal(bd.negative_gradient(*datum), alt_ng(*datum))
def test_binomial_deviance(): # Check binomial deviance loss. # Check against alternative definitions in ESLII. bd = BinomialDeviance(2) # pred has the same BD for y in {0, 1} assert_equal(bd(np.array([0.0]), np.array([0.0])), bd(np.array([1.0]), np.array([0.0]))) assert_almost_equal(bd(np.array([1.0, 1.0, 1.0]), np.array([100.0, 100.0, 100.0])), 0.0) assert_almost_equal(bd(np.array([1.0, 0.0, 0.0]), np.array([100.0, -100.0, -100.0])), 0) # check if same results as alternative definition of deviance (from ESLII) alt_dev = lambda y, pred: np.mean(np.logaddexp(0.0, -2.0 * (2.0 * y - 1) * pred)) test_data = [(np.array([1.0, 1.0, 1.0]), np.array([100.0, 100.0, 100.0])), (np.array([0.0, 0.0, 0.0]), np.array([100.0, 100.0, 100.0])), (np.array([0.0, 0.0, 0.0]), np.array([-100.0, -100.0, -100.0])), (np.array([1.0, 1.0, 1.0]), np.array([-100.0, -100.0, -100.0]))] for datum in test_data: assert_almost_equal(bd(*datum), alt_dev(*datum)) # check the gradient against the alt_ng = lambda y, pred: (2 * y - 1) / (1 + np.exp(2 * (2 * y - 1) * pred)) for datum in test_data: assert_almost_equal(bd.negative_gradient(*datum), alt_ng(*datum))
def test_binomial_deviance(): # Check binomial deviance loss. # Check against alternative definitions in ESLII. bd = BinomialDeviance(2) # pred has the same BD for y in {0, 1} assert bd(np.array([0.0]), np.array([0.0])) == bd(np.array([1.0]), np.array([0.0])) assert bd(np.array([1.0, 1, 1]), np.array([100.0, 100, 100])) == approx(0) assert bd(np.array([1.0, 0, 0]), np.array([100.0, -100, -100])) == approx(0) # check if same results as alternative definition of deviance, from ESLII # Eq. (10.18): -loglike = log(1 + exp(-2*z*f)) # Note: # - We use y = {0, 1}, ESL (10.18) uses z in {-1, 1}, hence y=2*y-1 # - ESL 2*f = pred_raw, hence the factor 2 of ESL disappears. # - Deviance = -2*loglike + .., hence a factor of 2 in front. def alt_dev(y, raw_pred): z = 2 * y - 1 return 2 * np.mean(np.log(1 + np.exp(-z * raw_pred))) test_data = product( (np.array([0.0, 0, 0]), np.array([1.0, 1, 1])), (np.array([-5.0, -5, -5]), np.array([3.0, 3, 3])), ) for datum in test_data: assert bd(*datum) == approx(alt_dev(*datum)) # check the negative gradient against altenative formula from ESLII # Note: negative_gradient is half the negative gradient. def alt_ng(y, raw_pred): z = 2 * y - 1 return z / (1 + np.exp(z * raw_pred)) for datum in test_data: assert bd.negative_gradient(*datum) == approx(alt_ng(*datum))