Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Closes DAS-1146: Sample weight metric calculations#3

Merged
ryan-deak-zefr merged 8 commits intomasterfrom
DAS-1146__sample_wt_cv
Feb 27, 2019
Merged

Closes DAS-1146: Sample weight metric calculations#3
ryan-deak-zefr merged 8 commits intomasterfrom
DAS-1146__sample_wt_cv

Conversation

@ryan-deak-zefr
Copy link
Copy Markdown

Summary

This PR address that dask_ml (like sklearn) doesn't use the importance weights when calculating metrics when scoring folds in cross validation. This affects all CV methods.

Changes

This PR only addresses the use of sample_weight in the metric calculations in cross fold validation and doesn't address the issue of combining the metrics across folds, which is currently done by simple averaging and not by weighted averaging using the sum of the sample weights for a fold as the weight.

Tests

test_sample_weight_in_metrics in tests/model_selection/dask_searchcv/test_model_selection.py.

This test is written to pass given the current way of combining metrics across folds (which is likely not the best / correct way to do it).

Copy link
Copy Markdown
Author

@ryan-deak-zefr ryan-deak-zefr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works to fix some of the issues but there are presumably much deeper methodological issues that might make this PR moot.

return train_sample_weight, test_sample_weight


def _apply_scorer(estimator, X, y, scorer, sample_weight):
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as in the sklearn PR for DAS-1145.

y_train,
scorer,
error_score,
test_sample_weight=None,
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ordering is consistent with the test then train parameter order established above.

scorer,
return_train_score,
):
if "sample_weight" in fit_params:
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the top since this is used in both branches.

#
# Each value in the fit_params dict is a 2-tuple where the
# data representation is in the second dimension (dim 1).
sample_weight = fit_params["sample_weight"][1]
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about getting this from some cache or something.

params=None,
fit_params=None,
return_train_score=True,
sample_weight=None,
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Place at the end and make it None by default to make it "backward compatible".

clf.fit(X, y)


@pytest.mark.parametrize(
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test kind of subsumes the test in the sklearn PR because it tests the situation with one fold metric calculation and multiple fold metric calculations that need to be combined. It does this by testing at the dcv.GridSearchCV level rather than at the level of functions in dask_ml/model_selection/methods.py.

),
],
)
def test_sample_weight_in_metrics(cv_ind, exp_acc):
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: If this test were used in the current master of dask_ml, it would fail because the metric returned by all tests is 0.5.

0.5 is definitely incorrect as it disregards sample_weight entirely.

Copy link
Copy Markdown

@zexuan-zhou zexuan-zhou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks all good to me

----------
sample_weight : array-like
sample weights. Should contain all sample weights needed for
training and testing. May be None.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it sensical for sample_weight to be None in a function called _get_fold_sample_weights?

train_sample_weight = None
test_sample_weight = None
else:
# "0" is the train split, "1" is the test split.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a convention somewhere else?

from itertools import product
from multiprocessing import cpu_count

# sklearn.metrics.make_scorer
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of these comments?

Copy link
Copy Markdown

@vecchp vecchp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 Let' just make sure we issue the sklearn pr first before this goes out.

@ryan-deak-zefr
Copy link
Copy Markdown
Author

This PR has the same tests as the scikit-learn PR: ZEFR-INC/scikit-learn#2 So it should be working very similarly.

@ryan-deak-zefr ryan-deak-zefr merged commit dec2c7f into master Feb 27, 2019
@ryan-deak-zefr ryan-deak-zefr deleted the DAS-1146__sample_wt_cv branch February 27, 2019 22:38
@zexuan-zhou zexuan-zhou restored the DAS-1146__sample_wt_cv branch August 13, 2019 18:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants