{"record":{"id":"a22b04b56403b78f","repo":"keras-team/keras","slug":"argument-specificity-must-be-in-the-range-0-1","errorCode":null,"errorMessage":"Argument `specificity` must be in the range [0, 1]. Received: specificity={specificity}","messagePattern":"Argument `specificity` must be in the range \\[0, 1\\]\\. Received: specificity=(.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/metrics/confusion_metrics.py","lineNumber":743,"sourceCode":"\n    ```python\n    model.compile(\n        optimizer='sgd',\n        loss='binary_crossentropy',\n        metrics=[keras.metrics.SensitivityAtSpecificity(specificity=0.5)])\n    ```\n    \"\"\"\n\n    def __init__(\n        self,\n        specificity,\n        num_thresholds=200,\n        class_id=None,\n        name=None,\n        dtype=None,\n    ):\n        if specificity < 0 or specificity > 1:\n            raise ValueError(\n                \"Argument `specificity` must be in the range [0, 1]. \"\n                f\"Received: specificity={specificity}\"\n            )\n        self.specificity = specificity\n        self.num_thresholds = num_thresholds\n        super().__init__(\n            specificity,\n            num_thresholds=num_thresholds,\n            class_id=class_id,\n            name=name,\n            dtype=dtype,\n        )\n\n    def result(self):\n        sensitivities = ops.divide_no_nan(\n            self.true_positives,\n            ops.add(self.true_positives, self.false_negatives),\n        )","sourceCodeStart":725,"sourceCodeEnd":761,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/metrics/confusion_metrics.py#L725-L761","documentation":"Raised in the constructor of keras.metrics.SpecificityAtSpecificity when the specificity argument falls outside [0, 1]. Specificity is a probability-like quantity (true negative rate), so Keros rejects out-of-range values immediately at construction time.","triggerScenarios":"keras.metrics.SpecificityAtSpecificity(specificity=1.2) or (-0.1); passing a percentage like 90 instead of 0.9; unclamped computed values.","commonSituations":"Percent-vs-fraction confusion; values from unnormalized expressions; floating-point drift slightly above 1.0.","solutions":["Pass a fraction in [0, 1], e.g. 0.9 instead of 90.","Validate computed values: assert 0 <= v <= 1.","Clamp drifting floats with min(max(v, 0.0), 1.0)."],"exampleFix":"# before\nm = keras.metrics.SpecificityAtSpecificity(specificity=90)\n\n# after\nm = keras.metrics.SpecificityAtSpecificity(specificity=0.9)","handlingStrategy":"validation","validationCode":"if not (0.0 <= specificity <= 1.0):\n    raise ValueError(f'specificity must be in [0,1], got {specificity}')","typeGuard":"def is_probability(v) -> bool:\n    return isinstance(v, (int, float)) and 0.0 <= v <= 1.0","tryCatchPattern":null,"preventionTips":["Store targets as fractions, never percentages.","Clamp computed ratios before passing to metrics."],"tags":["keras","metrics","specificity","range-validation"],"backgroundTag":"probability-out-of-range","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}