Skip to content

Commit 8bd7cec

Browse files
authored
Merge pull request #27 from INGEOTEC/develop
Version - 0.1.13
2 parents 4b28ebe + 1acc151 commit 8bd7cec

File tree

3 files changed

+178
-3
lines changed

3 files changed

+178
-3
lines changed

CompStats/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
__version__ = '0.1.12'
14+
__version__ = '0.1.13'
1515
from CompStats.bootstrap import StatisticSamples
1616
from CompStats.measurements import CI, SE, difference_p_value
1717
from CompStats.performance import performance, difference, all_differences, plot_performance, plot_difference

CompStats/metrics.py

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414
from functools import wraps
1515
from sklearn import metrics
16+
from scipy import stats
1617
from CompStats.interface import Perf
1718
from CompStats.utils import metrics_docs
1819

@@ -302,6 +303,81 @@ def inner(y, hy):
302303
**kwargs)
303304

304305

306+
def macro_f1(y_true, *y_pred, labels=None,
307+
sample_weight=None, zero_division='warn',
308+
num_samples: int=500, n_jobs: int=-1, use_tqdm=True,
309+
**kwargs):
310+
""":py:class:`~CompStats.interface.Perf` with :py:func:`~sklearn.metrics.f1_score` (as :py:attr:`score_func`) with the parameteres needed to compute the macro score. The parameters not described can be found in :py:func:`~sklearn.metrics.macro_f1`
311+
312+
:param y_true: True measurement or could be a pandas.DataFrame where column label 'y' corresponds to the true measurement.
313+
:type y_true: numpy.ndarray or pandas.DataFrame
314+
:param y_pred: Predictions, the algorithms will be identified with alg-k where k=1 is the first argument included in :py:attr:`y_pred.`
315+
:type y_pred: numpy.ndarray
316+
:param kwargs: Predictions, the algorithms will be identified using the keyword
317+
:type kwargs: numpy.ndarray
318+
:param num_samples: Number of bootstrap samples, default=500.
319+
:type num_samples: int
320+
:param n_jobs: Number of jobs to compute the statistic, default=-1 corresponding to use all threads.
321+
:type n_jobs: int
322+
:param use_tqdm: Whether to use tqdm.tqdm to visualize the progress, default=True
323+
:type use_tqdm: bool
324+
"""
325+
return f1_score(y_true, *y_pred, labels=labels, average='macro',
326+
sample_weight=sample_weight, zero_division=zero_division,
327+
num_samples=num_samples, n_jobs=n_jobs,
328+
use_tqdm=use_tqdm, **kwargs)
329+
330+
331+
def macro_recall(y_true, *y_pred, labels=None,
332+
sample_weight=None, zero_division='warn',
333+
num_samples: int=500, n_jobs: int=-1, use_tqdm=True,
334+
**kwargs):
335+
""":py:class:`~CompStats.interface.Perf` with :py:func:`~sklearn.metrics.recall_score` (as :py:attr:`score_func`) with the parameteres needed to compute the macro score. The parameters not described can be found in :py:func:`~sklearn.metrics.macro_recall`
336+
337+
:param y_true: True measurement or could be a pandas.DataFrame where column label 'y' corresponds to the true measurement.
338+
:type y_true: numpy.ndarray or pandas.DataFrame
339+
:param y_pred: Predictions, the algorithms will be identified with alg-k where k=1 is the first argument included in :py:attr:`y_pred.`
340+
:type y_pred: numpy.ndarray
341+
:param kwargs: Predictions, the algorithms will be identified using the keyword
342+
:type kwargs: numpy.ndarray
343+
:param num_samples: Number of bootstrap samples, default=500.
344+
:type num_samples: int
345+
:param n_jobs: Number of jobs to compute the statistic, default=-1 corresponding to use all threads.
346+
:type n_jobs: int
347+
:param use_tqdm: Whether to use tqdm.tqdm to visualize the progress, default=True
348+
:type use_tqdm: bool
349+
"""
350+
return recall_score(y_true, *y_pred, labels=labels, average='macro',
351+
sample_weight=sample_weight, zero_division=zero_division,
352+
num_samples=num_samples, n_jobs=n_jobs,
353+
use_tqdm=use_tqdm, **kwargs)
354+
355+
356+
def macro_precision(y_true, *y_pred, labels=None,
357+
sample_weight=None, zero_division='warn',
358+
num_samples: int=500, n_jobs: int=-1, use_tqdm=True,
359+
**kwargs):
360+
""":py:class:`~CompStats.interface.Perf` with :py:func:`~sklearn.metrics.precision_score` (as :py:attr:`score_func`) with the parameteres needed to compute the macro score. The parameters not described can be found in :py:func:`~sklearn.metrics.macro_precision`
361+
362+
:param y_true: True measurement or could be a pandas.DataFrame where column label 'y' corresponds to the true measurement.
363+
:type y_true: numpy.ndarray or pandas.DataFrame
364+
:param y_pred: Predictions, the algorithms will be identified with alg-k where k=1 is the first argument included in :py:attr:`y_pred.`
365+
:type y_pred: numpy.ndarray
366+
:param kwargs: Predictions, the algorithms will be identified using the keyword
367+
:type kwargs: numpy.ndarray
368+
:param num_samples: Number of bootstrap samples, default=500.
369+
:type num_samples: int
370+
:param n_jobs: Number of jobs to compute the statistic, default=-1 corresponding to use all threads.
371+
:type n_jobs: int
372+
:param use_tqdm: Whether to use tqdm.tqdm to visualize the progress, default=True
373+
:type use_tqdm: bool
374+
"""
375+
return precision_score(y_true, *y_pred, labels=labels, average='macro',
376+
sample_weight=sample_weight, zero_division=zero_division,
377+
num_samples=num_samples, n_jobs=n_jobs,
378+
use_tqdm=use_tqdm, **kwargs)
379+
380+
305381
########################################################
306382
#################### Regression ########################
307383
########################################################
@@ -576,7 +652,6 @@ def inner(y, hy):
576652
**kwargs)
577653

578654

579-
@metrics_docs(hy_name='y_pred', attr_name='score_func')
580655
def d2_absolute_error_score(y_true,
581656
*y_pred,
582657
sample_weight=None,
@@ -597,3 +672,37 @@ def inner(y, hy):
597672
num_samples=num_samples, n_jobs=n_jobs,
598673
use_tqdm=use_tqdm,
599674
**kwargs)
675+
676+
677+
def pearsonr(y_true, *y_pred,
678+
alternative='two-sided', method=None,
679+
num_samples: int=500,
680+
n_jobs: int=-1,
681+
use_tqdm=True,
682+
**kwargs):
683+
""":py:class:`~CompStats.interface.Perf` with :py:func:`~scipy.stats.pearsonr` as :py:attr:`score_func.`
684+
685+
:param y_true: True measurement or could be a pandas.DataFrame where column label 'y' corresponds to the true measurement.
686+
:type y_true: numpy.ndarray or pandas.DataFrame
687+
:param y_pred: Predictions, the algorithms will be identified with alg-k where k=1 is the first argument included in :py:attr:`y_pred.`
688+
:type y_pred: numpy.ndarray
689+
:param kwargs: Predictions, the algorithms will be identified using the keyword
690+
:type kwargs: numpy.ndarray
691+
:param num_samples: Number of bootstrap samples, default=500.
692+
:type num_samples: int
693+
:param n_jobs: Number of jobs to compute the statistic, default=-1 corresponding to use all threads.
694+
:type n_jobs: int
695+
:param use_tqdm: Whether to use tqdm.tqdm to visualize the progress, default=True
696+
:type use_tqdm: bool
697+
"""
698+
699+
@wraps(stats.pearsonr)
700+
def inner(y, hy):
701+
return stats.pearsonr(y, hy,
702+
alternative=alternative,
703+
method=method).statistic
704+
705+
return Perf(y_true, *y_pred, score_func=inner, error_func=None,
706+
num_samples=num_samples, n_jobs=n_jobs,
707+
use_tqdm=use_tqdm,
708+
**kwargs)

CompStats/tests/test_metrics.py

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,21 @@ def test_f1_score():
3939
assert str(perf) is not None
4040

4141

42+
def test_macro_f1_score():
43+
"""Test f1_score"""
44+
from CompStats.metrics import macro_f1
45+
46+
X, y = load_iris(return_X_y=True)
47+
_ = train_test_split(X, y, test_size=0.3)
48+
X_train, X_val, y_train, y_val = _
49+
ens = RandomForestClassifier().fit(X_train, y_train)
50+
hy = ens.predict(X_val)
51+
perf = macro_f1(y_val, forest=hy, num_samples=50)
52+
assert isinstance(perf.statistic, float)
53+
_ = metrics.f1_score(y_val, hy, average='macro')
54+
assert _ == perf.statistic
55+
56+
4257
def test_accuracy_score():
4358
"""Test f1_score"""
4459
from CompStats.metrics import accuracy_score
@@ -152,6 +167,23 @@ def test_precision_score():
152167
assert _ == perf.statistic
153168

154169

170+
def test_macro_precision():
171+
"""Test macro_precision"""
172+
from CompStats.metrics import macro_precision
173+
import numpy as np
174+
175+
X, y = load_iris(return_X_y=True)
176+
_ = train_test_split(X, y, test_size=0.3, stratify=y)
177+
X_train, X_val, y_train, y_val = _
178+
ens = RandomForestClassifier().fit(X_train, y_train)
179+
hy = ens.predict(X_val)
180+
perf = macro_precision(y_val,
181+
forest=hy,
182+
num_samples=50)
183+
_ = metrics.precision_score(y_val, hy, average='macro')
184+
assert _ == perf.statistic
185+
186+
155187
def test_recall_score():
156188
"""Test recall_score"""
157189
from CompStats.metrics import recall_score
@@ -169,6 +201,23 @@ def test_recall_score():
169201
assert _ == perf.statistic
170202

171203

204+
def test_macro_recall():
205+
"""Test macro_recall"""
206+
from CompStats.metrics import macro_recall
207+
import numpy as np
208+
209+
X, y = load_iris(return_X_y=True)
210+
_ = train_test_split(X, y, test_size=0.3, stratify=y)
211+
X_train, X_val, y_train, y_val = _
212+
ens = RandomForestClassifier().fit(X_train, y_train)
213+
hy = ens.predict(X_val)
214+
perf = macro_recall(y_val,
215+
forest=hy,
216+
num_samples=50)
217+
_ = metrics.recall_score(y_val, hy, average='macro')
218+
assert _ == perf.statistic
219+
220+
172221
def test_jaccard_score():
173222
"""jaccard_score"""
174223
from CompStats.metrics import jaccard_score
@@ -427,4 +476,21 @@ def test_d2_absolute_error_score():
427476
forest=hy,
428477
num_samples=50)
429478
_ = metrics.d2_absolute_error_score(y_val, hy)
430-
assert _ == perf.statistic
479+
assert _ == perf.statistic
480+
481+
482+
def test_pearsonr():
483+
"""test pearsonr"""
484+
from CompStats.metrics import pearsonr
485+
from scipy import stats
486+
487+
X, y = load_diabetes(return_X_y=True)
488+
_ = train_test_split(X, y, test_size=0.3)
489+
X_train, X_val, y_train, y_val = _
490+
ens = RandomForestRegressor().fit(X_train, y_train)
491+
hy = ens.predict(X_val)
492+
perf = pearsonr(y_val,
493+
forest=hy,
494+
num_samples=50)
495+
_ = stats.pearsonr(y_val, hy)
496+
assert _.statistic == perf.statistic

0 commit comments

Comments
 (0)