Repository: scikit-learn/scikit-learn
File: sklearn/metrics/_classification.py (Python)

Code before:
        confusion = confusion_matrix(y1, y2, labels=labels, sample_weight=sample_weight)
    except ValueError as e:
        if "At least one label specified must be in y_true" in str(e):
            msg = (
                "At least one label in `labels` must be present in `y1` (even though "
                "`cohen_kappa_score` is otherwise agnostic to the order of `y1` and "
                "`y2`)."
            )
            raise ValueError(msg) from e
        raise

    n_classes = confusion.shape[0]
    sum0 = np.sum(confusion, axis=0)
    sum1 = np.sum(confusion, axis=1)

    mgs_changing_default = (
        "`np.nan` as the default return value of `cohen_kappa_score` in case of a "
        "division by zero has been deprecated in 1.7 and will be changed to 0.0 in "
        "version 1.9. Set `replace_undefined_by=0.0` to use the new default and to "
        "silence this Warning."
    )

    numerator = np.outer(sum0, sum1)
    denominator = np.sum(sum0)
    msg_zero_division = (
        "`y2` contains no labels that are presented in both `y1` and `labels`."
        "`cohen_kappa_score` is undefined and set to the value defined by "
        "the `replace_undefined_by` param, which defaults to `np.nan`."
    )
    if _check_zero_division(denominator, replace_undefined_by, msg_zero_division):
        return replace_undefined_by

    expected = numerator / denominator

    if weights is None:
        w_mat = np.ones([n_classes, n_classes], dtype=int)
        w_mat.flat[:: n_classes + 1] = 0
    else:  # "linear" or "quadratic"
        w_mat = np.zeros([n_classes, n_classes], dtype=int)
        w_mat += np.arange(n_classes)
        if weights == "linear":
            w_mat = np.abs(w_mat - w_mat.T)
        else:
            w_mat = (w_mat - w_mat.T) ** 2

    numerator = np.sum(w_mat * confusion)
    denominator = np.sum(w_mat * expected)
    msg_zero_division = (
        "`y1`, `y2` and `labels` have only one label in common. "
        "`cohen_kappa_score` is undefined and set to the value defined by the "
        "`replace_undefined_by` param, which defaults to `np.nan`."

Review comment (suggestion):
```suggestion
    denominator = np.sum(sum0)
    msg_zero_division = (
        "`y2` contains no labels that are present in both `y1` and `labels`."
        "`cohen_kappa_score` is undefined and set to the value defined by "
        "the `replace_undefined_by` param, which defaults to `np.nan`."
    )
    if _check_zero_division(denominator, replace_undefined_by, msg_zero_division):
        return replace_undefined_by
```

Code after:
        - a floating point value in the range of [-1.0, 1.0] to return a specific value

        .. versionadded:: 1.9

    Returns
    -------
    kappa : float
        The kappa statistic, which is a number between -1.0 and 1.0. The maximum value
        means complete agreement; the minimum value means complete disagreement; 0.0
        indicates no agreement beyond what would be expected by chance.

    References
    ----------
    .. [1] :doi:`J. Cohen (1960). "A coefficient of agreement for nominal scales".
           Educational and Psychological Measurement 20(1):37-46.
           <10.1177/001316446002000104>`
    .. [2] `R. Artstein and M. Poesio (2008). "Inter-coder agreement for
           computational linguistics". Computational Linguistics 34(4):555-596
           <https://www.mitpressjournals.org/doi/pdf/10.1162/coli.07-034-R2>`_.
    .. [3] `Wikipedia entry for the Cohen's kappa
            <https://en.wikipedia.org/wiki/Cohen%27s_kappa>`_.

    Examples
    --------
    >>> from sklearn.metrics import cohen_kappa_score
    >>> y1 = ["negative", "positive", "negative", "neutral", "positive"]
    >>> y2 = ["negative", "positive", "negative", "neutral", "negative"]
    >>> cohen_kappa_score(y1, y2)
    0.6875
    """
    try:
        confusion = confusion_matrix(y1, y2, labels=labels, sample_weight=sample_weight)
    except ValueError as e:
        if "At least one label specified must be in y_true" in str(e):
            msg = (
                "At least one label in `labels` must be present in `y1` (even though "
                "`cohen_kappa_score` is otherwise agnostic to the order of `y1` and "
                "`y2`)."
            )
            raise ValueError(msg) from e
        raise

    xp, _, device_ = get_namespace_and_device(y1, y2)
    n_classes = confusion.shape[0]
    # array_api_strict only supports floating point dtypes for __truediv__
    # which is used below to compute `expected` as well as `k`. Therefore
    # we use the maximum floating point dtype available for relevant arrays
    # to avoid running into this problem.
    max_float_dtype = _max_precision_float_dtype(xp, device=device_)
    confusion = xp.astype(confusion, max_float_dtype, copy=False)
    sum0 = xp.sum(confusion, axis=0)