|
4 | 4 | import os
|
5 | 5 | import numbers
|
6 | 6 | from unittest.mock import Mock
|
| 7 | +from functools import partial |
7 | 8 |
|
8 | 9 | import numpy as np
|
9 | 10 | import pytest
|
|
29 | 30 | from sklearn.svm import LinearSVC
|
30 | 31 | from sklearn.pipeline import make_pipeline
|
31 | 32 | from sklearn.cluster import KMeans
|
32 |
| -from sklearn.linear_model import Ridge, LogisticRegression |
| 33 | +from sklearn.linear_model import Ridge, LogisticRegression, Perceptron |
33 | 34 | from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
|
34 | 35 | from sklearn.datasets import make_blobs
|
35 | 36 | from sklearn.datasets import make_classification
|
@@ -670,3 +671,51 @@ def test_multimetric_scorer_sanity_check():
|
670 | 671 | for key, value in result.items():
|
671 | 672 | score_name = scorers[key]
|
672 | 673 | assert_allclose(value, seperate_scores[score_name])
|
| 674 | + |
| 675 | + |
| 676 | +@pytest.mark.parametrize('scorer_name, metric', [ |
| 677 | + ('roc_auc_ovr', partial(roc_auc_score, multi_class='ovr')), |
| 678 | + ('roc_auc_ovo', partial(roc_auc_score, multi_class='ovo')), |
| 679 | + ('roc_auc_ovr_weighted', partial(roc_auc_score, multi_class='ovr', |
| 680 | + average='weighted')), |
| 681 | + ('roc_auc_ovo_weighted', partial(roc_auc_score, multi_class='ovo', |
| 682 | + average='weighted'))]) |
| 683 | +def test_multiclass_roc_proba_scorer(scorer_name, metric): |
| 684 | + scorer = get_scorer(scorer_name) |
| 685 | + X, y = make_classification(n_classes=3, n_informative=3, n_samples=20, |
| 686 | + random_state=0) |
| 687 | + lr = LogisticRegression(multi_class="multinomial").fit(X, y) |
| 688 | + y_proba = lr.predict_proba(X) |
| 689 | + expected_score = metric(y, y_proba) |
| 690 | + |
| 691 | + assert scorer(lr, X, y) == pytest.approx(expected_score) |
| 692 | + |
| 693 | + |
| 694 | +def test_multiclass_roc_proba_scorer_label(): |
| 695 | + scorer = make_scorer(roc_auc_score, multi_class='ovo', |
| 696 | + labels=[0, 1, 2], needs_proba=True) |
| 697 | + X, y = make_classification(n_classes=3, n_informative=3, n_samples=20, |
| 698 | + random_state=0) |
| 699 | + lr = LogisticRegression(multi_class="multinomial").fit(X, y) |
| 700 | + y_proba = lr.predict_proba(X) |
| 701 | + |
| 702 | + y_binary = y == 0 |
| 703 | + expected_score = roc_auc_score(y_binary, y_proba, |
| 704 | + multi_class='ovo', |
| 705 | + labels=[0, 1, 2]) |
| 706 | + |
| 707 | + assert scorer(lr, X, y_binary) == pytest.approx(expected_score) |
| 708 | + |
| 709 | + |
| 710 | +@pytest.mark.parametrize('scorer_name', [ |
| 711 | + 'roc_auc_ovr', 'roc_auc_ovo', |
| 712 | + 'roc_auc_ovr_weighted', 'roc_auc_ovo_weighted']) |
| 713 | +def test_multiclass_roc_no_proba_scorer_errors(scorer_name): |
| 714 | + # Perceptron has no predict_proba |
| 715 | + scorer = get_scorer(scorer_name) |
| 716 | + X, y = make_classification(n_classes=3, n_informative=3, n_samples=20, |
| 717 | + random_state=0) |
| 718 | + lr = Perceptron().fit(X, y) |
| 719 | + msg = "'Perceptron' object has no attribute 'predict_proba'" |
| 720 | + with pytest.raises(AttributeError, match=msg): |
| 721 | + scorer(lr, X, y) |
0 commit comments