o
    yi?,                     @   s  d dl mZ d dlZd dlmZ d dlmZ d dlmZmZm	Z	m
Z
mZmZmZmZ d dedeed  d	efd
dZ			d!dedee deed  d	dfddZ				d"dedededeed  dee ded	efddZ		d#dedee deed  d	dfddZ			d$dedededeed  dee ded	efddZ					d%dededed dedee deed  dee ded	efddZdS )&    )OptionalN)Tensor)Literal)'_binary_confusion_matrix_arg_validation_binary_confusion_matrix_format*_binary_confusion_matrix_tensor_validation_binary_confusion_matrix_update+_multiclass_confusion_matrix_arg_validation#_multiclass_confusion_matrix_format._multiclass_confusion_matrix_tensor_validation#_multiclass_confusion_matrix_updateconfmatweights)linear	quadraticnonereturnc                 C   s  |   s|  n| } | jd }| jddd}| jddd}|| |  }|du s-|dkrDt|  }d|dd|d < |||}n4|dv rpt| }|tj	||j
|jd7 }|d	krft||j }nt||j d
}ntd| dt||  t||  }d| S )zdReduce an un-normalized confusion matrix of shape (n_classes, n_classes) into the cohen kappa score.r   T)dimkeepdim   Nr   )r   r   )dtypedevicer   g       @z	Received zL for argument ``weights`` but should be either None, 'linear' or 'quadratic')is_floating_pointfloatshapesumtorch	ones_likeflattenreshape
zeros_likearanger   r   absTpow
ValueError)r   r   	n_classessum0sum1expectedw_matk r,   f/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/functional/classification/cohen_kappa.py_cohen_kappa_reduce    s(   


r.         ?	thresholdignore_indexc                 C   4   t | |dd d}||vrtd| d| ddS )zValidate non tensor input.

    - ``threshold`` has to be a float in the [0,1] range
    - ``ignore_index`` has to be None or int
    - ``weights`` has to be "linear" | "quadratic" | "none" | None
    N	normalizer   r   r   N(Expected argument `weight` to be one of 
, but got .)r   r%   )r0   r1   r   allowed_weightsr,   r,   r-   "_binary_cohen_kappa_arg_validation;   
   r:   Tpredstargetvalidate_argsc                 C   sB   |rt ||| t| || t| |||\} }t| |}t||S )a  Calculates `Cohen's kappa score`_ that measures inter-annotator agreement for binary tasks. It is defined
    as.

    .. math::
        \kappa = (p_o - p_e) / (1 - p_e)

    where :math:`p_o` is the empirical probability of agreement and :math:`p_e` is
    the expected agreement when both annotators assign labels randomly. Note that
    :math:`p_e` is estimated using a per-annotator empirical prior over the
    class labels.

    Accepts the following input tensors:

    - ``preds`` (int or float tensor): ``(N, ...)``. If preds is a floating point tensor with values outside
      [0,1] range we consider the input to be logits and will auto apply sigmoid per element. Addtionally,
      we convert to int tensor with thresholding using the value in ``threshold``.
    - ``target`` (int tensor): ``(N, ...)``

    Additional dimension ``...`` will be flattened into the batch dimension.

    Args:
        preds: Tensor with predictions
        target: Tensor with true labels
        threshold: Threshold for transforming probability to binary (0,1) predictions
        weights: Weighting type to calculate the score. Choose from:

            - ``None`` or ``'none'``: no weighting
            - ``'linear'``: linear weighting
            - ``'quadratic'``: quadratic weighting
        ignore_index:
            Specifies a target value that is ignored and does not contribute to the metric calculation
        validate_args: bool indicating if input arguments and tensors should be validated for correctness.
            Set to ``False`` for faster computations.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example (preds is int tensor):
        >>> from torchmetrics.functional.classification import binary_cohen_kappa
        >>> target = torch.tensor([1, 1, 0, 0])
        >>> preds = torch.tensor([0, 1, 0, 0])
        >>> binary_cohen_kappa(preds, target)
        tensor(0.5000)

    Example (preds is float tensor):
        >>> from torchmetrics.functional.classification import binary_cohen_kappa
        >>> target = torch.tensor([1, 1, 0, 0])
        >>> preds = torch.tensor([0.35, 0.85, 0.48, 0.01])
        >>> binary_cohen_kappa(preds, target)
        tensor(0.5000)
    )r:   r   r   r   r.   )r<   r=   r0   r   r1   r>   r   r,   r,   r-   binary_cohen_kappaL   s   9

r?   num_classesc                 C   r2   )zValidate non tensor input.

    - ``num_classes`` has to be a int larger than 1
    - ``ignore_index`` has to be None or int
    - ``weights`` has to be "linear" | "quadratic" | "none" | None
    Nr3   r5   r6   r7   r8   )r	   r%   )r@   r1   r   r9   r,   r,   r-   &_multiclass_cohen_kappa_arg_validation   r;   rA   c                 C   sD   |rt ||| t| ||| t| ||\} }t| ||}t||S )a	  Calculates `Cohen's kappa score`_ that measures inter-annotator agreement for multiclass tasks. It is
    defined as.

    .. math::
        \kappa = (p_o - p_e) / (1 - p_e)

    where :math:`p_o` is the empirical probability of agreement and :math:`p_e` is
    the expected agreement when both annotators assign labels randomly. Note that
    :math:`p_e` is estimated using a per-annotator empirical prior over the
    class labels.

    Accepts the following input tensors:

    - ``preds``: ``(N, ...)`` (int tensor) or ``(N, C, ..)`` (float tensor). If preds is a floating point
      we apply ``torch.argmax`` along the ``C`` dimension to automatically convert probabilities/logits into
      an int tensor.
    - ``target`` (int tensor): ``(N, ...)``

    Additional dimension ``...`` will be flattened into the batch dimension.

    Args:
        preds: Tensor with predictions
        target: Tensor with true labels
        num_classes: Integer specifing the number of classes
        weights: Weighting type to calculate the score. Choose from:

            - ``None`` or ``'none'``: no weighting
            - ``'linear'``: linear weighting
            - ``'quadratic'``: quadratic weighting


        ignore_index:
            Specifies a target value that is ignored and does not contribute to the metric calculation
        validate_args: bool indicating if input arguments and tensors should be validated for correctness.
            Set to ``False`` for faster computations.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example (pred is integer tensor):
        >>> from torchmetrics.functional.classification import multiclass_cohen_kappa
        >>> target = torch.tensor([2, 1, 0, 0])
        >>> preds = torch.tensor([2, 1, 0, 1])
        >>> multiclass_cohen_kappa(preds, target, num_classes=3)
        tensor(0.6364)

    Example (pred is float tensor):
        >>> from torchmetrics.functional.classification import multiclass_cohen_kappa
        >>> target = torch.tensor([2, 1, 0, 0])
        >>> preds = torch.tensor([
        ...   [0.16, 0.26, 0.58],
        ...   [0.22, 0.61, 0.17],
        ...   [0.71, 0.09, 0.20],
        ...   [0.05, 0.82, 0.13],
        ... ])
        >>> multiclass_cohen_kappa(preds, target, num_classes=3)
        tensor(0.6364)
    )rA   r   r
   r   r.   )r<   r=   r@   r   r1   r>   r   r,   r,   r-   multiclass_cohen_kappa   s   @
rB   task)binary
multiclassc                 C   sP   |dkrt | |||||S |dkr!t|tsJ t| |||||S td| )a  Calculates `Cohen's kappa score`_ that measures inter-annotator agreement. It is defined as.

    .. math::
        \kappa = (p_o - p_e) / (1 - p_e)

    where :math:`p_o` is the empirical probability of agreement and :math:`p_e` is
    the expected agreement when both annotators assign labels randomly. Note that
    :math:`p_e` is estimated using a per-annotator empirical prior over the
    class labels.

    This function is a simple wrapper to get the task specific versions of this metric, which is done by setting the
    ``task`` argument to either ``'binary'`` or ``'multiclass'``. See the documentation of
    :func:`binary_cohen_kappa` and :func:`multiclass_cohen_kappa` for the specific details of
    each argument influence and examples.

    Legacy Example:
        >>> target = torch.tensor([1, 1, 0, 0])
        >>> preds = torch.tensor([0, 1, 0, 0])
        >>> cohen_kappa(preds, target, task="multiclass", num_classes=2)
        tensor(0.5000)
    rD   rE   zKExpected argument `task` to either be `'binary'` or `'multiclass'` but got )r?   
isinstanceintrB   r%   )r<   r=   rC   r0   r@   r   r1   r>   r,   r,   r-   cohen_kappa   s   rH   )N)r/   NN)r/   NNT)NN)NNT)r/   NNNT)typingr   r   r   typing_extensionsr   7torchmetrics.functional.classification.confusion_matrixr   r   r   r   r	   r
   r   r   r.   r   rG   r:   boolr?   rA   rB   rH   r,   r,   r,   r-   <module>   s   ( 



C



L
	