def f1_score(y, yhat): """ The F_1 score is a metric for classification which tries to balance precision and recall, ie both true positives and true negatives. For F_1 score higher is better. :param y: The expected input (i.e. from dataset). :param yhat: The given input (i.e. from phenotype). :return: The f1 score. """ # if phen is a constant, eg 0.001 (doesn't refer to x), then yhat # will be a constant. that will break f1_score. so convert to a # constant array. if not isinstance(yhat, np.ndarray) or len(yhat.shape) < 1: yhat = np.ones_like(y) * yhat # convert real values to boolean with a zero threshold yhat = (yhat > 0) with warnings.catch_warnings(): # if we predict the same value for all samples (trivial # individuals will do so as described above) then f-score is # undefined, and sklearn will give a runtime warning and # return 0. We can ignore that warning and happily return 0. warnings.simplefilter("ignore") return sklearn_f1_score(y, yhat, average="weighted")
def f1_score(y, yhat): """ The F_1 score is a metric for classification which tries to balance precision and recall, ie both true positives and true negatives. For F_1 score higher is better. :param y: The expected input (i.e. from dataset). :param yhat: The given input (i.e. from phenotype). :return: The f1 score. """ # if phen is a constant, eg 0.001 (doesn't refer to x), then yhat # will be a constant. that will break f1_score. so convert to a # constant array. if not isinstance(yhat, np.ndarray) or len(yhat.shape) < 1: yhat = np.ones_like(y) * yhat # Deal with possibility of {-1, 1} or {0, 1} class label # convention. FIXME: would it be better to canonicalise the # convention elsewhere and/or create user parameter to control it? # See https://github.com/PonyGE/PonyGE2/issues/113. y_vals = set(y) # convert from {-1, 1} to {0, 1} if -1 in y_vals: y[y == -1] = 0 # We binarize with a threshold, so this cannot be used for multiclass assert len(y_vals) == 2 # convert real values to boolean {0, 1} with a zero threshold yhat = (yhat > 0) with warnings.catch_warnings(): # if we predict the same value for all samples (trivial # individuals will do so as described above) then f-score is # undefined, and sklearn will give a runtime warning and # return 0. We can ignore that warning and happily return 0. warnings.simplefilter("ignore") return sklearn_f1_score(y, yhat, average="weighted")