|
9 | 9 |
|
10 | 10 | from sklearn.utils import check_random_state
|
11 | 11 | from sklearn.utils.stats import _weighted_percentile
|
12 |
| -from sklearn.ensemble._gb_losses import BinomialDeviance |
13 | 12 | from sklearn.ensemble._gb_losses import RegressionLossFunction
|
14 | 13 | from sklearn.ensemble._gb_losses import LeastSquaresError
|
| 14 | +from sklearn.ensemble._gb_losses import LeastAbsoluteError |
| 15 | +from sklearn.ensemble._gb_losses import HuberLossFunction |
15 | 16 | from sklearn.ensemble._gb_losses import QuantileLossFunction
|
| 17 | +from sklearn.ensemble._gb_losses import BinomialDeviance |
| 18 | +from sklearn.ensemble._gb_losses import MultinomialDeviance |
| 19 | +from sklearn.ensemble._gb_losses import ExponentialLoss |
16 | 20 | from sklearn.ensemble._gb_losses import LOSS_FUNCTIONS
|
17 | 21 |
|
18 | 22 |
|
@@ -170,3 +174,123 @@ def test_sample_weight_deviance():
|
170 | 174 | deviance_w_w = loss(y, p, sample_weight)
|
171 | 175 | deviance_wo_w = loss(y, p)
|
172 | 176 | assert deviance_wo_w == deviance_w_w
|
| 177 | + |
| 178 | + |
| 179 | +def test_init_raw_predictions_shapes(): |
| 180 | + # Make sure get_init_raw_predictions returns float64 arrays with shape |
| 181 | + # (n_samples, K) where K is 1 for binary classification and regression, and |
| 182 | + # K = n_classes for multiclass classification |
| 183 | + rng = np.random.RandomState(0) |
| 184 | + |
| 185 | + n_samples = 100 |
| 186 | + X = rng.normal(size=(n_samples, 5)) |
| 187 | + y = rng.normal(size=n_samples) |
| 188 | + for loss in (LeastSquaresError(n_classes=1), |
| 189 | + LeastAbsoluteError(n_classes=1), |
| 190 | + QuantileLossFunction(n_classes=1), |
| 191 | + HuberLossFunction(n_classes=1)): |
| 192 | + init_estimator = loss.init_estimator().fit(X, y) |
| 193 | + raw_predictions = loss.get_init_raw_predictions(y, init_estimator) |
| 194 | + assert raw_predictions.shape == (n_samples, 1) |
| 195 | + assert raw_predictions.dtype == np.float64 |
| 196 | + |
| 197 | + y = rng.randint(0, 2, size=n_samples) |
| 198 | + for loss in (BinomialDeviance(n_classes=2), |
| 199 | + ExponentialLoss(n_classes=2)): |
| 200 | + init_estimator = loss.init_estimator().fit(X, y) |
| 201 | + raw_predictions = loss.get_init_raw_predictions(y, init_estimator) |
| 202 | + assert raw_predictions.shape == (n_samples, 1) |
| 203 | + assert raw_predictions.dtype == np.float64 |
| 204 | + |
| 205 | + for n_classes in range(3, 5): |
| 206 | + y = rng.randint(0, n_classes, size=n_samples) |
| 207 | + loss = MultinomialDeviance(n_classes=n_classes) |
| 208 | + init_estimator = loss.init_estimator().fit(X, y) |
| 209 | + raw_predictions = loss.get_init_raw_predictions(y, init_estimator) |
| 210 | + assert raw_predictions.shape == (n_samples, n_classes) |
| 211 | + assert raw_predictions.dtype == np.float64 |
| 212 | + |
| 213 | + |
| 214 | +def test_init_raw_predictions_values(): |
| 215 | + # Make sure the get_init_raw_predictions() returns the expected values for |
| 216 | + # each loss. |
| 217 | + rng = np.random.RandomState
57AE
(0) |
| 218 | + |
| 219 | + n_samples = 100 |
| 220 | + X = rng.normal(size=(n_samples, 5)) |
| 221 | + y = rng.normal(size=n_samples) |
| 222 | + |
| 223 | + # Least squares loss |
| 224 | + loss = LeastSquaresError(n_classes=1) |
| 225 | + init_estimator = loss.init_estimator().fit(X, y) |
| 226 | + raw_predictions = loss.get_init_raw_predictions(y, init_estimator) |
| 227 | + # Make sure baseline prediction is the mean of all targets |
| 228 | + assert_almost_equal(raw_predictions, y.mean()) |
| 229 | + |
| 230 | + # Least absolute and huber loss |
| 231 | + for Loss in (LeastAbsoluteError, HuberLossFunction): |
| 232 | + loss = Loss(n_classes=1) |
| 233 | + init_estimator = loss.init_estimator().fit(X, y) |
| 234 | + raw_predictions = loss.get_init_raw_predictions(y, init_estimator) |
| 235 | + # Make sure baseline prediction is the median of all targets |
| 236 | + assert_almost_equal(raw_predictions, np.median(y)) |
| 237 | + |
| 238 | + # Quantile loss |
| 239 | + for alpha in (.1, .5, .9): |
| 240 | + loss = QuantileLossFunction(n_classes=1, alpha=alpha) |
| 241 | + init_estimator = loss.init_estimator().fit(X, y) |
| 242 | + raw_predictions = loss.get_init_raw_predictions(y, init_estimator) |
| 243 | + # Make sure baseline prediction is the alpha-quantile of all targets |
| 244 | + assert_almost_equal(raw_predictions, np.percentile(y, alpha * 100)) |
| 245 | + |
| 246 | + y = rng.randint(0, 2, size=n_samples) |
| 247 | + |
| 248 | + # Binomial deviance |
| 249 | + loss = BinomialDeviance(n_classes=2) |
| 250 | + init_estimator = loss.init_estimator().fit(X, y) |
| 251 | + # Make sure baseline prediction is equal to link_function(p), where p |
| 252 | + # is the proba of the positive class. We want predict_proba() to return p, |
| 253 | + # and by definition |
| 254 | + # p = inverse_link_function(raw_prediction) = sigmoid(raw_prediction) |
| 255 | + # So we want raw_prediction = link_function(p) = log(p / (1 - p)) |
| 256 | + raw_predictions = loss.get_init_raw_predictions(y, init_estimator) |
| 257 | + p = y.mean() |
| 258 | + assert_almost_equal(raw_predictions, np.log(p / (1 - p))) |
| 259 | + |
| 260 | + # FIXME: uncomment this and fix |
| 261 | + # for y_unstable in (np.zeros(shape=n_samples), np.ones(shape=n_samples)): |
| 262 | + # init_estimator = loss.init_estimator().fit(X, y_unstable) |
| 263 | + # raw_predictions = loss.get_init_raw_predictions(y_unstable, |
| 264 | + # init_estimator) |
| 265 | + # assert_all_finite(raw_predictions) |
| 266 | + |
| 267 | + # Exponential loss |
| 268 | + loss = ExponentialLoss(n_classes=2) |
| 269 | + init_estimator = loss.init_estimator().fit(X, y) |
| 270 | + raw_predictions = loss.get_init_raw_predictions(y, init_estimator) |
| 271 | + p = y.mean() |
| 272 | + assert_almost_equal(raw_predictions, .5 * np.log(p / (1 - p))) |
| 273 | + |
| 274 | + # FIXME: uncomment this and fix |
| 275 | + # for y_unstable in (np.zeros(shape=n_samples), np.ones(shape=n_samples)): |
| 276 | + # init_estimator = loss.init_estimator().fit(X, y_unstable) |
| 277 | + # raw_predictions = loss.get_init_raw_predictions(y_unstable, |
| 278 | + # init_estimator) |
| 279 | + # assert_all_finite(raw_predictions) |
| 280 | + |
| 281 | + # Multinomial deviance loss |
| 282 | + for n_classes in range(3, 5): |
| 283 | + y = rng.randint(0, n_classes, size=n_samples) |
| 284 | + loss = MultinomialDeviance(n_classes=n_classes) |
| 285 | + init_estimator = loss.init_estimator().fit(X, y) |
| 286 | + raw_predictions = loss.get_init_raw_predictions(y, init_estimator) |
| 287 | + for k in range(n_classes): |
| 288 | + p = (y == k).mean() |
| 289 | + assert_almost_equal(raw_predictions[:, k], np.log(p)) |
| 290 | + |
| 291 | + # FIXME: uncomment this and fix |
| 292 | + # for y_unstable in (np.zeros(shape=n_samples), np.ones(shape=n_samples)): |
| 293 | + # init_estimator = loss.init_estimator().fit(X, y_unstable) |
| 294 | + # raw_predictions = loss.get_init_raw_predictions(y_unstable, |
| 295 | + # init_estimator) |
| 296 | + # assert_all_finite(raw_predictions) |
0 commit comments