Skip to content

Commit

Permalink
Moving utils to metrics.
Browse files Browse the repository at this point in the history
  • Loading branch information
xehivs committed Dec 19, 2019
1 parent bf74d01 commit 0adc027
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 39 deletions.
2 changes: 1 addition & 1 deletion examples/plot_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
stream = sl.streams.StreamGenerator(n_chunks=30, n_drifts=1)

# Select vector of metrics
metrics = [sl.utils.metrics.bac, sl.utils.metrics.f1_score]
metrics = [sl.metrics.bac, sl.metrics.f1_score]

# Initialize evaluator with given metrics
evaluator = sl.evaluators.TestThenTrain(metrics)
Expand Down
14 changes: 9 additions & 5 deletions examples/plot_simplest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,22 @@
"""

from sklearn.naive_bayes import GaussianNB

clf = GaussianNB()

from strlearn.streams import StreamGenerator

stream = StreamGenerator(n_chunks=30, n_drifts=1)


from sklearn.metrics import accuracy_score
from strlearn.utils.metrics import recall
from strlearn.metrics import recall

metrics = [accuracy_score, recall]


from strlearn.evaluators import TestThenTrain

evaluator = TestThenTrain(metrics)


Expand All @@ -37,16 +41,16 @@

import matplotlib.pyplot as plt

plt.figure(figsize=(6,3), dpi=400)
plt.figure(figsize=(6, 3), dpi=400)

for m, metric in enumerate(metrics):
plt.plot(evaluator.scores[0, :, m], label=metric.__name__)

plt.title("Basic example of stream processing")
plt.ylim(0, 1)
plt.ylabel('Quality')
plt.xlabel('Chunk')
plt.ylabel("Quality")
plt.xlabel("Chunk")

plt.legend()
plt.tight_layout()
plt.savefig('simplest.png', transparent=True)
plt.savefig("simplest.png", transparent=True)
2 changes: 1 addition & 1 deletion strlearn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
from . import ensembles
from . import evaluators
from . import streams
from . import utils
from . import metrics
2 changes: 1 addition & 1 deletion strlearn/evaluators/Prequential.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import numpy as np
from sklearn.metrics import accuracy_score
from ..utils import bac
from ..metrics import bac
from sklearn.base import ClassifierMixin


Expand Down
2 changes: 1 addition & 1 deletion strlearn/evaluators/TestThenTrain.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import numpy as np
from sklearn.metrics import accuracy_score
from ..utils import bac
from ..metrics import bac
from sklearn.base import ClassifierMixin


Expand Down
11 changes: 11 additions & 0 deletions strlearn/metrics/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .metrics import (
fbeta_score,
f1_score,
recall,
precision,
bac,
geometric_mean_score_1,
geometric_mean_score_2,
specificity,
binary_confusion_matrix,
)
24 changes: 16 additions & 8 deletions strlearn/utils/metrics.py → strlearn/metrics/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import numpy as np


def binary_confusion_matrix(y_true, y_pred):
# tn, fp, fn, tp
return tuple([np.sum((y_pred == i%2) * (y_true == i//2)) for i in range(4)])
return tuple([np.sum((y_pred == i % 2) * (y_true == i // 2)) for i in range(4)])


def specificity(y_true, y_pred):
"""
Expand All @@ -22,7 +24,7 @@ def specificity(y_true, y_pred):
specificity : float
"""
tn, fp, fn, tp = binary_confusion_matrix(y_true, y_pred)
return tn/(tn+fp)
return np.nan_to_num(tn / (tn + fp))


def recall(y_true, y_pred):
Expand All @@ -41,7 +43,8 @@ def recall(y_true, y_pred):
recall : float
"""
tn, fp, fn, tp = binary_confusion_matrix(y_true, y_pred)
return np.nan_to_num(tp/(tp+fn))
return np.nan_to_num(tp / (tp + fn))


def precision(y_true, y_pred):
"""
Expand All @@ -59,11 +62,14 @@ def precision(y_true, y_pred):
precision : float
"""
tn, fp, fn, tp = binary_confusion_matrix(y_true, y_pred)
return np.nan_to_num(tp/(tp+fp))
return np.nan_to_num(tp / (tp + fp))


def fbeta_score(y_true, y_pred, beta):
pre, rec = precision(y_true, y_pred), recall(y_true, y_pred)
return np.nan_to_num((1+np.power(beta,2)) * pre * rec / (np.power(beta,2) * pre + rec))
return np.nan_to_num(
(1 + np.power(beta, 2)) * pre * rec / (np.power(beta, 2) * pre + rec)
)


def f1_score(y_true, y_pred):
Expand All @@ -83,6 +89,7 @@ def f1_score(y_true, y_pred):
"""
return fbeta_score(y_true, y_pred, 1)


def bac(y_true, y_pred):
"""
Calculates the balanced accuracy score.
Expand All @@ -99,7 +106,8 @@ def bac(y_true, y_pred):
bac : float
"""
spe, rec = specificity(y_true, y_pred), recall(y_true, y_pred)
return np.nan_to_num((rec+spe)/2)
return np.nan_to_num((rec + spe) / 2)


def geometric_mean_score_1(y_true, y_pred):
"""
Expand All @@ -117,7 +125,7 @@ def geometric_mean_score_1(y_true, y_pred):
gmean : float
"""
spe, rec = specificity(y_true, y_pred), recall(y_true, y_pred)
return np.nan_to_num(np.sqrt(rec*spe))
return np.nan_to_num(np.sqrt(rec * spe))


def geometric_mean_score_2(y_true, y_pred):
Expand All @@ -136,4 +144,4 @@ def geometric_mean_score_2(y_true, y_pred):
gmean : float
"""
pre, rec = precision(y_true, y_pred), recall(y_true, y_pred)
return np.nan_to_num(np.sqrt(rec*pre))
return np.nan_to_num(np.sqrt(rec * pre))
10 changes: 4 additions & 6 deletions strlearn/tests/test_evaluators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
import strlearn as sl
from sklearn.metrics import accuracy_score, roc_auc_score
from ..utils import bac, f1_score, geometric_mean_score_1
from ..metrics import bac, f1_score, geometric_mean_score_1

sys.path.insert(0, "../..")

Expand All @@ -30,6 +30,7 @@ def test_TTT_custom_metrics():

assert evaluator.scores.shape == (1, stream.n_chunks - 1, len(metrics))


def test_TTT_one_metric():
stream = get_stream()
clf = sl.classifiers.AccumulatedSamplesClassifier()
Expand Down Expand Up @@ -68,14 +69,11 @@ def test_P_multiple_clfs():
len(metrics),
)


def test_P_one_metric():
stream = get_stream()
clf = sl.classifiers.AccumulatedSamplesClassifier()
evaluator = sl.evaluators.Prequential(metrics=accuracy_score)
evaluator.process(stream, clf, interval=100)

assert evaluator.scores.shape == (
1,
(stream.n_chunks - 1) * 2,
1,
)
assert evaluator.scores.shape == (1, (stream.n_chunks - 1) * 2, 1,)
25 changes: 13 additions & 12 deletions strlearn/tests/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,32 @@


def test_precision_recall():
'Calculating matrics'
"Calculating matrics"
chunk_size = 100
n_chunks = 10
X, y = make_classification(n_samples=chunk_size * n_chunks,
n_features=5,
n_classes=2,
random_state=1410)
X, y = make_classification(
n_samples=chunk_size * n_chunks, n_features=5, n_classes=2, random_state=1410
)

clf = sl.classifiers.AccumulatedSamplesClassifier()

previous_chunk = None
for chunk_id in range(n_chunks):
print("Chunk ", chunk_id)
chunk = (X[chunk_size * chunk_id:chunk_size * chunk_id + chunk_size],
y[chunk_size * chunk_id:chunk_size * chunk_id + chunk_size])
chunk = (
X[chunk_size * chunk_id : chunk_size * chunk_id + chunk_size],
y[chunk_size * chunk_id : chunk_size * chunk_id + chunk_size],
)

if previous_chunk is not None:
X_test, y_test = previous_chunk
y_pred = clf.predict(X_test)

precision = sl.utils.metrics.precision(y_test, y_pred)
recall = sl.utils.metrics.recall(y_test, y_pred)
gmean1 = sl.utils.metrics.geometric_mean_score_1(y_test, y_pred)
gmean2 = sl.utils.metrics.geometric_mean_score_2(y_test, y_pred)
f1 = sl.utils.metrics.f1_score(y_test, y_pred)
precision = sl.metrics.precision(y_test, y_pred)
recall = sl.metrics.recall(y_test, y_pred)
gmean1 = sl.metrics.geometric_mean_score_1(y_test, y_pred)
gmean2 = sl.metrics.geometric_mean_score_2(y_test, y_pred)
f1 = sl.metrics.f1_score(y_test, y_pred)

clf.partial_fit(chunk[0], chunk[1])

Expand Down
4 changes: 0 additions & 4 deletions strlearn/utils/__init__.py

This file was deleted.

0 comments on commit 0adc027

Please sign in to comment.