Reputation: 339
So I want to catch different types of warnings on the following code:
score = cross_val_score(DecisionTreeClassifier(), X, y, scoring=f2_measure, cv=cv)
From running the code, I got two warnings:
UserWarning: The least populated class in y has only 1 members, which is less than n_splits=2.
% (min_groups, self.n_splits)), UserWarning)
UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 due to no true nor predicted samples.
Use `zero_division` parameter to control this behavior.
I'd like to catch both type of warnings and then handle them separately, I tried using the following:
with warnings.catch_warnings():
warnings.filterwarnings('error', category=UserWarning)
warnings.filterwarnings('error', category=UndefinedMetricWarning)
try:
score = cross_val_score(DecisionTreeClassifier(), X, y, scoring=f2_measure, cv=cv).mean()
except (UndefinedMetricWarning, UserWarning) as e:
print(type(e))
But all of the warnings are then raised as a UserWarning
, and there's no UndefinedMetricWarning
. (I'm not quite sure but I think this problem might be caused by UndefinedMetricWarning
is inherited from UserWarning
).
How to identify and handle these two type of warnings separately?
Upvotes: 3
Views: 642
Reputation: 51
You can use two different except
s after your try
. The second except
will catch only the exceptions that are not caught by the first except
. So you can make the first except
catch the subclass UndefinedMetricWarning
and then the second except
can effectively catch only the UserWarning
warnings that are not also an UndefinedMetricWarning
:
with warnings.catch_warnings():
warnings.filterwarnings('error', category=UserWarning)
warnings.filterwarnings('error', category=UndefinedMetricWarning)
try:
score = cross_val_score(DecisionTreeClassifier(), X, y, scoring=f2_measure, cv=cv).mean()
except UndefinedMetricWarning as e:
print(type(e))
except UserWarning as e:
print(type(e))
Here is a minimal working example:
import warnings
class MyWarning(UserWarning):
pass
def a(flag):
if flag:
warnings.warn("hello", MyWarning)
else:
warnings.warn("bye")
def b(flag):
with warnings.catch_warnings():
warnings.filterwarnings("error", category=UserWarning)
warnings.filterwarnings("error", category=MyWarning)
try:
a(flag)
except MyWarning as e:
print(type(e))
except UserWarning as e:
print(type(e))
b(True)
b(False)
See: https://docs.python.org/3/tutorial/errors.html
Upvotes: 2