#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import sys
from abc import abstractmethod, ABCMeta
from typing import Any, Dict, Optional, TYPE_CHECKING

from pyspark import since, keyword_only
from pyspark.ml.wrapper import JavaParams
from pyspark.ml.param import Param, Params, TypeConverters
from pyspark.ml.param.shared import (
    HasLabelCol,
    HasPredictionCol,
    HasProbabilityCol,
    HasRawPredictionCol,
    HasFeaturesCol,
    HasWeightCol,
)
from pyspark.ml.common import inherit_doc
from pyspark.ml.util import JavaMLReadable, JavaMLWritable, try_remote_evaluate
from pyspark.sql.dataframe import DataFrame

if TYPE_CHECKING:
    from pyspark.ml._typing import (
        ParamMap,
        BinaryClassificationEvaluatorMetricType,
        ClusteringEvaluatorDistanceMeasureType,
        ClusteringEvaluatorMetricType,
        MulticlassClassificationEvaluatorMetricType,
        MultilabelClassificationEvaluatorMetricType,
        RankingEvaluatorMetricType,
        RegressionEvaluatorMetricType,
    )


__all__ = [
    "Evaluator",
    "BinaryClassificationEvaluator",
    "RegressionEvaluator",
    "MulticlassClassificationEvaluator",
    "MultilabelClassificationEvaluator",
    "ClusteringEvaluator",
    "RankingEvaluator",
]


@inherit_doc
class Evaluator(Params, metaclass=ABCMeta):
    """
    Base class for evaluators that compute metrics from predictions.

    .. versionadded:: 1.4.0
    """

    @abstractmethod
    def _evaluate(self, dataset: DataFrame) -> float:
        """
        Evaluates the output.

        Parameters
        ----------
        dataset : :py:class:`pyspark.sql.DataFrame`
            a dataset that contains labels/observations and predictions

        Returns
        -------
        float
            metric
        """
        raise NotImplementedError()

    def evaluate(self, dataset: DataFrame, params: Optional["ParamMap"] = None) -> float:
        """
        Evaluates the output with optional parameters.

        .. versionadded:: 1.4.0

        Parameters
        ----------
        dataset : :py:class:`pyspark.sql.DataFrame`
            a dataset that contains labels/observations and predictions
        params : dict, optional
            an optional param map that overrides embedded params

        Returns
        -------
        float
            metric
        """
        if params is None:
            params = dict()
        if isinstance(params, dict):
            if params:
                return self.copy(params)._evaluate(dataset)
            else:
                return self._evaluate(dataset)
        else:
            raise TypeError("Params must be a param map but got %s." % type(params))

    @since("1.5.0")
    def isLargerBetter(self) -> bool:
        """
        Indicates whether the metric returned by :py:meth:`evaluate` should be maximized
        (True, default) or minimized (False).
        A given evaluator may support multiple metrics which may be maximized or minimized.
        """
        return True


@inherit_doc
class JavaEvaluator(JavaParams, Evaluator, metaclass=ABCMeta):
    """
    Base class for :py:class:`Evaluator`s that wrap Java/Scala
    implementations.
    """

    @try_remote_evaluate
    def _evaluate(self, dataset: DataFrame) -> float:
        """
        Evaluates the output.

        Parameters
        ----------
        dataset : :py:class:`pyspark.sql.DataFrame`
            a dataset that contains labels/observations and predictions

        Returns
        -------
        float
            evaluation metric
        """
        self._transfer_params_to_java()
        assert self._java_obj is not None
        return self._java_obj.evaluate(dataset._jdf)

    def isLargerBetter(self) -> bool:
        self._transfer_params_to_java()
        assert self._java_obj is not None
        return self._java_obj.isLargerBetter()


@inherit_doc
class BinaryClassificationEvaluator(
    JavaEvaluator,
    HasLabelCol,
    HasRawPredictionCol,
    HasWeightCol,
    JavaMLReadable["BinaryClassificationEvaluator"],
    JavaMLWritable,
):
    """
    Evaluator for binary classification, which expects input columns rawPrediction, label
    and an optional weight column.
    The rawPrediction column can be of type double (binary 0/1 prediction, or probability of label
    1) or of type vector (length-2 vector of raw predictions, scores, or label probabilities).

    .. versionadded:: 1.4.0

    Examples
    --------
    >>> from pyspark.ml.linalg import Vectors
    >>> scoreAndLabels = map(lambda x: (Vectors.dense([1.0 - x[0], x[0]]), x[1]),
    ...    [(0.1, 0.0), (0.1, 1.0), (0.4, 0.0), (0.6, 0.0), (0.6, 1.0), (0.6, 1.0), (0.8, 1.0)])
    >>> dataset = spark.createDataFrame(scoreAndLabels, ["raw", "label"])
    ...
    >>> evaluator = BinaryClassificationEvaluator()
    >>> evaluator.setRawPredictionCol("raw")
    BinaryClassificationEvaluator...
    >>> evaluator.evaluate(dataset)
    0.70...
    >>> evaluator.evaluate(dataset, {evaluator.metricName: "areaUnderPR"})
    0.83...
    >>> bce_path = temp_path + "/bce"
    >>> evaluator.save(bce_path)
    >>> evaluator2 = BinaryClassificationEvaluator.load(bce_path)
    >>> str(evaluator2.getRawPredictionCol())
    'raw'
    >>> scoreAndLabelsAndWeight = map(lambda x: (Vectors.dense([1.0 - x[0], x[0]]), x[1], x[2]),
    ...    [(0.1, 0.0, 1.0), (0.1, 1.0, 0.9), (0.4, 0.0, 0.7), (0.6, 0.0, 0.9),
    ...     (0.6, 1.0, 1.0), (0.6, 1.0, 0.3), (0.8, 1.0, 1.0)])
    >>> dataset = spark.createDataFrame(scoreAndLabelsAndWeight, ["raw", "label", "weight"])
    ...
    >>> evaluator = BinaryClassificationEvaluator(rawPredictionCol="raw", weightCol="weight")
    >>> evaluator.evaluate(dataset)
    0.70...
    >>> evaluator.evaluate(dataset, {evaluator.metricName: "areaUnderPR"})
    0.82...
    >>> evaluator.getNumBins()
    1000
    """

    metricName: Param["BinaryClassificationEvaluatorMetricType"] = Param(
        Params._dummy(),
        "metricName",
        "metric name in evaluation (areaUnderROC|areaUnderPR)",
        typeConverter=TypeConverters.toString,  # type: ignore[arg-type]
    )

    numBins: Param[int] = Param(
        Params._dummy(),
        "numBins",
        "Number of bins to down-sample the curves "
        "(ROC curve, PR curve) in area computation. If 0, no down-sampling will "
        "occur. Must be >= 0.",
        typeConverter=TypeConverters.toInt,
    )

    _input_kwargs: Dict[str, Any]

    @keyword_only
    def __init__(
        self,
        *,
        rawPredictionCol: str = "rawPrediction",
        labelCol: str = "label",
        metricName: "BinaryClassificationEvaluatorMetricType" = "areaUnderROC",
        weightCol: Optional[str] = None,
        numBins: int = 1000,
    ):
        """
        __init__(self, \\*, rawPredictionCol="rawPrediction", labelCol="label", \
                 metricName="areaUnderROC", weightCol=None, numBins=1000)
        """
        super(BinaryClassificationEvaluator, self).__init__()
        self._java_obj = self._new_java_obj(
            "org.apache.spark.ml.evaluation.BinaryClassificationEvaluator", self.uid
        )
        self._setDefault(metricName="areaUnderROC", numBins=1000)
        kwargs = self._input_kwargs
        self._set(**kwargs)

    @since("1.4.0")
    def setMetricName(
        self, value: "BinaryClassificationEvaluatorMetricType"
    ) -> "BinaryClassificationEvaluator":
        """
        Sets the value of :py:attr:`metricName`.
        """
        return self._set(metricName=value)

    @since("1.4.0")
    def getMetricName(self) -> str:
        """
        Gets the value of metricName or its default value.
        """
        return self.getOrDefault(self.metricName)

    @since("3.0.0")
    def setNumBins(self, value: int) -> "BinaryClassificationEvaluator":
        """
        Sets the value of :py:attr:`numBins`.
        """
        return self._set(numBins=value)

    @since("3.0.0")
    def getNumBins(self) -> int:
        """
        Gets the value of numBins or its default value.
        """
        return self.getOrDefault(self.numBins)

    def setLabelCol(self, value: str) -> "BinaryClassificationEvaluator":
        """
        Sets the value of :py:attr:`labelCol`.
        """
        return self._set(labelCol=value)

    def setRawPredictionCol(self, value: str) -> "BinaryClassificationEvaluator":
        """
        Sets the value of :py:attr:`rawPredictionCol`.
        """
        return self._set(rawPredictionCol=value)

    @since("3.0.0")
    def setWeightCol(self, value: str) -> "BinaryClassificationEvaluator":
        """
        Sets the value of :py:attr:`weightCol`.
        """
        return self._set(weightCol=value)

    @keyword_only
    @since("1.4.0")
    def setParams(
        self,
        *,
        rawPredictionCol: str = "rawPrediction",
        labelCol: str = "label",
        metricName: "BinaryClassificationEvaluatorMetricType" = "areaUnderROC",
        weightCol: Optional[str] = None,
        numBins: int = 1000,
    ) -> "BinaryClassificationEvaluator":
        """
        setParams(self, \\*, rawPredictionCol="rawPrediction", labelCol="label", \
                  metricName="areaUnderROC", weightCol=None, numBins=1000)
        Sets params for binary classification evaluator.
        """
        kwargs = self._input_kwargs
        return self._set(**kwargs)

    def isLargerBetter(self) -> bool:
        """Override this function to make it run on connect"""
        return True


@inherit_doc
class RegressionEvaluator(
    JavaEvaluator,
    HasLabelCol,
    HasPredictionCol,
    HasWeightCol,
    JavaMLReadable["RegressionEvaluator"],
    JavaMLWritable,
):
    """
    Evaluator for Regression, which expects input columns prediction, label
    and an optional weight column.

    .. versionadded:: 1.4.0

    Examples
    --------
    >>> scoreAndLabels = [(-28.98343821, -27.0), (20.21491975, 21.5),
    ...   (-25.98418959, -22.0), (30.69731842, 33.0), (74.69283752, 71.0)]
    >>> dataset = spark.createDataFrame(scoreAndLabels, ["raw", "label"])
    ...
    >>> evaluator = RegressionEvaluator()
    >>> evaluator.setPredictionCol("raw")
    RegressionEvaluator...
    >>> evaluator.evaluate(dataset)
    2.842...
    >>> evaluator.evaluate(dataset, {evaluator.metricName: "r2"})
    0.993...
    >>> evaluator.evaluate(dataset, {evaluator.metricName: "mae"})
    2.649...
    >>> re_path = temp_path + "/re"
    >>> evaluator.save(re_path)
    >>> evaluator2 = RegressionEvaluator.load(re_path)
    >>> str(evaluator2.getPredictionCol())
    'raw'
    >>> scoreAndLabelsAndWeight = [(-28.98343821, -27.0, 1.0), (20.21491975, 21.5, 0.8),
    ...   (-25.98418959, -22.0, 1.0), (30.69731842, 33.0, 0.6), (74.69283752, 71.0, 0.2)]
    >>> dataset = spark.createDataFrame(scoreAndLabelsAndWeight, ["raw", "label", "weight"])
    ...
    >>> evaluator = RegressionEvaluator(predictionCol="raw", weightCol="weight")
    >>> evaluator.evaluate(dataset)
    2.740...
    >>> evaluator.getThroughOrigin()
    False
    """

    metricName: Param["RegressionEvaluatorMetricType"] = Param(
        Params._dummy(),
        "metricName",
        """metric name in evaluation - one of:
                       rmse - root mean squared error (default)
                       mse - mean squared error
                       r2 - r^2 metric
                       mae - mean absolute error
                       var - explained variance.""",
        typeConverter=TypeConverters.toString,  # type: ignore[arg-type]
    )

    throughOrigin: Param[bool] = Param(
        Params._dummy(),
        "throughOrigin",
        "whether the regression is through the origin.",
        typeConverter=TypeConverters.toBoolean,
    )

    _input_kwargs: Dict[str, Any]

    @keyword_only
    def __init__(
        self,
        *,
        predictionCol: str = "prediction",
        labelCol: str = "label",
        metricName: "RegressionEvaluatorMetricType" = "rmse",
        weightCol: Optional[str] = None,
        throughOrigin: bool = False,
    ):
        """
        __init__(self, \\*, predictionCol="prediction", labelCol="label", \
                 metricName="rmse", weightCol=None, throughOrigin=False)
        """
        super(RegressionEvaluator, self).__init__()
        self._java_obj = self._new_java_obj(
            "org.apache.spark.ml.evaluation.RegressionEvaluator", self.uid
        )
        self._setDefault(metricName="rmse", throughOrigin=False)
        kwargs = self._input_kwargs
        self._set(**kwargs)

    @since("1.4.0")
    def setMetricName(self, value: "RegressionEvaluatorMetricType") -> "RegressionEvaluator":
        """
        Sets the value of :py:attr:`metricName`.
        """
        return self._set(metricName=value)

    @since("1.4.0")
    def getMetricName(self) -> "RegressionEvaluatorMetricType":
        """
        Gets the value of metricName or its default value.
        """
        return self.getOrDefault(self.metricName)

    @since("3.0.0")
    def setThroughOrigin(self, value: bool) -> "RegressionEvaluator":
        """
        Sets the value of :py:attr:`throughOrigin`.
        """
        return self._set(throughOrigin=value)

    @since("3.0.0")
    def getThroughOrigin(self) -> bool:
        """
        Gets the value of throughOrigin or its default value.
        """
        return self.getOrDefault(self.throughOrigin)

    def setLabelCol(self, value: str) -> "RegressionEvaluator":
        """
        Sets the value of :py:attr:`labelCol`.
        """
        return self._set(labelCol=value)

    def setPredictionCol(self, value: str) -> "RegressionEvaluator":
        """
        Sets the value of :py:attr:`predictionCol`.
        """
        return self._set(predictionCol=value)

    @since("3.0.0")
    def setWeightCol(self, value: str) -> "RegressionEvaluator":
        """
        Sets the value of :py:attr:`weightCol`.
        """
        return self._set(weightCol=value)

    @keyword_only
    @since("1.4.0")
    def setParams(
        self,
        *,
        predictionCol: str = "prediction",
        labelCol: str = "label",
        metricName: "RegressionEvaluatorMetricType" = "rmse",
        weightCol: Optional[str] = None,
        throughOrigin: bool = False,
    ) -> "RegressionEvaluator":
        """
        setParams(self, \\*, predictionCol="prediction", labelCol="label", \
                  metricName="rmse", weightCol=None, throughOrigin=False)
        Sets params for regression evaluator.
        """
        kwargs = self._input_kwargs
        return self._set(**kwargs)

    def isLargerBetter(self) -> bool:
        """Override this function to make it run on connect"""
        return self.getMetricName() in ["r2", "var"]


@inherit_doc
class MulticlassClassificationEvaluator(
    JavaEvaluator,
    HasLabelCol,
    HasPredictionCol,
    HasWeightCol,
    HasProbabilityCol,
    JavaMLReadable["MulticlassClassificationEvaluator"],
    JavaMLWritable,
):
    """
    Evaluator for Multiclass Classification, which expects input
    columns: prediction, label, weight (optional) and probabilityCol (only for logLoss).

    .. versionadded:: 1.5.0

    Examples
    --------
    >>> scoreAndLabels = [(0.0, 0.0), (0.0, 1.0), (0.0, 0.0),
    ...     (1.0, 0.0), (1.0, 1.0), (1.0, 1.0), (1.0, 1.0), (2.0, 2.0), (2.0, 0.0)]
    >>> dataset = spark.createDataFrame(scoreAndLabels, ["prediction", "label"])
    >>> evaluator = MulticlassClassificationEvaluator()
    >>> evaluator.setPredictionCol("prediction")
    MulticlassClassificationEvaluator...
    >>> evaluator.evaluate(dataset)
    0.66...
    >>> evaluator.evaluate(dataset, {evaluator.metricName: "accuracy"})
    0.66...
    >>> evaluator.evaluate(dataset, {evaluator.metricName: "truePositiveRateByLabel",
    ...     evaluator.metricLabel: 1.0})
    0.75...
    >>> evaluator.setMetricName("hammingLoss")
    MulticlassClassificationEvaluator...
    >>> evaluator.evaluate(dataset)
    0.33...
    >>> mce_path = temp_path + "/mce"
    >>> evaluator.save(mce_path)
    >>> evaluator2 = MulticlassClassificationEvaluator.load(mce_path)
    >>> str(evaluator2.getPredictionCol())
    'prediction'
    >>> scoreAndLabelsAndWeight = [(0.0, 0.0, 1.0), (0.0, 1.0, 1.0), (0.0, 0.0, 1.0),
    ...     (1.0, 0.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0), (1.0, 1.0, 1.0),
    ...     (2.0, 2.0, 1.0), (2.0, 0.0, 1.0)]
    >>> dataset = spark.createDataFrame(scoreAndLabelsAndWeight, ["prediction", "label", "weight"])
    >>> evaluator = MulticlassClassificationEvaluator(predictionCol="prediction",
    ...     weightCol="weight")
    >>> evaluator.evaluate(dataset)
    0.66...
    >>> evaluator.evaluate(dataset, {evaluator.metricName: "accuracy"})
    0.66...
    >>> predictionAndLabelsWithProbabilities = [
    ...      (1.0, 1.0, 1.0, [0.1, 0.8, 0.1]), (0.0, 2.0, 1.0, [0.9, 0.05, 0.05]),
    ...      (0.0, 0.0, 1.0, [0.8, 0.2, 0.0]), (1.0, 1.0, 1.0, [0.3, 0.65, 0.05])]
    >>> dataset = spark.createDataFrame(predictionAndLabelsWithProbabilities, ["prediction",
    ...     "label", "weight", "probability"])
    >>> evaluator = MulticlassClassificationEvaluator(predictionCol="prediction",
    ...     probabilityCol="probability")
    >>> evaluator.setMetricName("logLoss")
    MulticlassClassificationEvaluator...
    >>> evaluator.evaluate(dataset)
    0.9682...
    """

    metricName: Param["MulticlassClassificationEvaluatorMetricType"] = Param(
        Params._dummy(),
        "metricName",
        "metric name in evaluation "
        "(f1|accuracy|weightedPrecision|weightedRecall|weightedTruePositiveRate| "
        "weightedFalsePositiveRate|weightedFMeasure|truePositiveRateByLabel| "
        "falsePositiveRateByLabel|precisionByLabel|recallByLabel|fMeasureByLabel| "
        "logLoss|hammingLoss)",
        typeConverter=TypeConverters.toString,  # type: ignore[arg-type]
    )
    metricLabel: Param[float] = Param(
        Params._dummy(),
        "metricLabel",
        "The class whose metric will be computed in truePositiveRateByLabel|"
        "falsePositiveRateByLabel|precisionByLabel|recallByLabel|fMeasureByLabel."
        " Must be >= 0. The default value is 0.",
        typeConverter=TypeConverters.toFloat,
    )
    beta: Param[float] = Param(
        Params._dummy(),
        "beta",
        "The beta value used in weightedFMeasure|fMeasureByLabel."
        " Must be > 0. The default value is 1.",
        typeConverter=TypeConverters.toFloat,
    )
    eps: Param[float] = Param(
        Params._dummy(),
        "eps",
        "log-loss is undefined for p=0 or p=1, so probabilities are clipped to "
        "max(eps, min(1 - eps, p)). "
        "Must be in range (0, 0.5). The default value is 1e-15.",
        typeConverter=TypeConverters.toFloat,
    )

    _input_kwargs: Dict[str, Any]

    @keyword_only
    def __init__(
        self,
        *,
        predictionCol: str = "prediction",
        labelCol: str = "label",
        metricName: "MulticlassClassificationEvaluatorMetricType" = "f1",
        weightCol: Optional[str] = None,
        metricLabel: float = 0.0,
        beta: float = 1.0,
        probabilityCol: str = "probability",
        eps: float = 1e-15,
    ):
        """
        __init__(self, \\*, predictionCol="prediction", labelCol="label", \
                 metricName="f1", weightCol=None, metricLabel=0.0, beta=1.0, \
                 probabilityCol="probability", eps=1e-15)
        """
        super(MulticlassClassificationEvaluator, self).__init__()
        self._java_obj = self._new_java_obj(
            "org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator", self.uid
        )
        self._setDefault(metricName="f1", metricLabel=0.0, beta=1.0, eps=1e-15)
        kwargs = self._input_kwargs
        self._set(**kwargs)

    @since("1.5.0")
    def setMetricName(
        self, value: "MulticlassClassificationEvaluatorMetricType"
    ) -> "MulticlassClassificationEvaluator":
        """
        Sets the value of :py:attr:`metricName`.
        """
        return self._set(metricName=value)

    @since("1.5.0")
    def getMetricName(self) -> "MulticlassClassificationEvaluatorMetricType":
        """
        Gets the value of metricName or its default value.
        """
        return self.getOrDefault(self.metricName)

    @since("3.0.0")
    def setMetricLabel(self, value: float) -> "MulticlassClassificationEvaluator":
        """
        Sets the value of :py:attr:`metricLabel`.
        """
        return self._set(metricLabel=value)

    @since("3.0.0")
    def getMetricLabel(self) -> float:
        """
        Gets the value of metricLabel or its default value.
        """
        return self.getOrDefault(self.metricLabel)

    @since("3.0.0")
    def setBeta(self, value: float) -> "MulticlassClassificationEvaluator":
        """
        Sets the value of :py:attr:`beta`.
        """
        return self._set(beta=value)

    @since("3.0.0")
    def getBeta(self) -> float:
        """
        Gets the value of beta or its default value.
        """
        return self.getOrDefault(self.beta)

    @since("3.0.0")
    def setEps(self, value: float) -> "MulticlassClassificationEvaluator":
        """
        Sets the value of :py:attr:`eps`.
        """
        return self._set(eps=value)

    @since("3.0.0")
    def getEps(self) -> float:
        """
        Gets the value of eps or its default value.
        """
        return self.getOrDefault(self.eps)

    def setLabelCol(self, value: str) -> "MulticlassClassificationEvaluator":
        """
        Sets the value of :py:attr:`labelCol`.
        """
        return self._set(labelCol=value)

    def setPredictionCol(self, value: str) -> "MulticlassClassificationEvaluator":
        """
        Sets the value of :py:attr:`predictionCol`.
        """
        return self._set(predictionCol=value)

    @since("3.0.0")
    def setProbabilityCol(self, value: str) -> "MulticlassClassificationEvaluator":
        """
        Sets the value of :py:attr:`probabilityCol`.
        """
        return self._set(probabilityCol=value)

    @since("3.0.0")
    def setWeightCol(self, value: str) -> "MulticlassClassificationEvaluator":
        """
        Sets the value of :py:attr:`weightCol`.
        """
        return self._set(weightCol=value)

    @keyword_only
    @since("1.5.0")
    def setParams(
        self,
        *,
        predictionCol: str = "prediction",
        labelCol: str = "label",
        metricName: "MulticlassClassificationEvaluatorMetricType" = "f1",
        weightCol: Optional[str] = None,
        metricLabel: float = 0.0,
        beta: float = 1.0,
        probabilityCol: str = "probability",
        eps: float = 1e-15,
    ) -> "MulticlassClassificationEvaluator":
        """
        setParams(self, \\*, predictionCol="prediction", labelCol="label", \
                  metricName="f1", weightCol=None, metricLabel=0.0, beta=1.0, \
                  probabilityCol="probability", eps=1e-15)
        Sets params for multiclass classification evaluator.
        """
        kwargs = self._input_kwargs
        return self._set(**kwargs)

    def isLargerBetter(self) -> bool:
        """Override this function to make it run on connect"""
        return not self.getMetricName() in [
            "weightedFalsePositiveRate",
            "falsePositiveRateByLabel",
            "logLoss",
            "hammingLoss",
        ]


@inherit_doc
class MultilabelClassificationEvaluator(
    JavaEvaluator,
    HasLabelCol,
    HasPredictionCol,
    JavaMLReadable["MultilabelClassificationEvaluator"],
    JavaMLWritable,
):
    """
    Evaluator for Multilabel Classification, which expects two input
    columns: prediction and label.

    .. versionadded:: 3.0.0

    Notes
    -----
    Experimental

    Examples
    --------
    >>> scoreAndLabels = [([0.0, 1.0], [0.0, 2.0]), ([0.0, 2.0], [0.0, 1.0]),
    ...     ([], [0.0]), ([2.0], [2.0]), ([2.0, 0.0], [2.0, 0.0]),
    ...     ([0.0, 1.0, 2.0], [0.0, 1.0]), ([1.0], [1.0, 2.0])]
    >>> dataset = spark.createDataFrame(scoreAndLabels, ["prediction", "label"])
    ...
    >>> evaluator = MultilabelClassificationEvaluator()
    >>> evaluator.setPredictionCol("prediction")
    MultilabelClassificationEvaluator...
    >>> evaluator.evaluate(dataset)
    0.63...
    >>> evaluator.evaluate(dataset, {evaluator.metricName: "accuracy"})
    0.54...
    >>> mlce_path = temp_path + "/mlce"
    >>> evaluator.save(mlce_path)
    >>> evaluator2 = MultilabelClassificationEvaluator.load(mlce_path)
    >>> str(evaluator2.getPredictionCol())
    'prediction'
    """

    metricName: Param["MultilabelClassificationEvaluatorMetricType"] = Param(
        Params._dummy(),
        "metricName",
        "metric name in evaluation "
        "(subsetAccuracy|accuracy|hammingLoss|precision|recall|f1Measure|"
        "precisionByLabel|recallByLabel|f1MeasureByLabel|microPrecision|"
        "microRecall|microF1Measure)",
        typeConverter=TypeConverters.toString,  # type: ignore[arg-type]
    )
    metricLabel: Param[float] = Param(
        Params._dummy(),
        "metricLabel",
        "The class whose metric will be computed in precisionByLabel|"
        "recallByLabel|f1MeasureByLabel. "
        "Must be >= 0. The default value is 0.",
        typeConverter=TypeConverters.toFloat,
    )

    _input_kwargs: Dict[str, Any]

    @keyword_only
    def __init__(
        self,
        *,
        predictionCol: str = "prediction",
        labelCol: str = "label",
        metricName: "MultilabelClassificationEvaluatorMetricType" = "f1Measure",
        metricLabel: float = 0.0,
    ) -> None:
        """
        __init__(self, \\*, predictionCol="prediction", labelCol="label", \
                 metricName="f1Measure", metricLabel=0.0)
        """
        super(MultilabelClassificationEvaluator, self).__init__()
        self._java_obj = self._new_java_obj(
            "org.apache.spark.ml.evaluation.MultilabelClassificationEvaluator", self.uid
        )
        self._setDefault(metricName="f1Measure", metricLabel=0.0)
        kwargs = self._input_kwargs
        self._set(**kwargs)

    @since("3.0.0")
    def setMetricName(
        self, value: "MultilabelClassificationEvaluatorMetricType"
    ) -> "MultilabelClassificationEvaluator":
        """
        Sets the value of :py:attr:`metricName`.
        """
        return self._set(metricName=value)

    @since("3.0.0")
    def getMetricName(self) -> "MultilabelClassificationEvaluatorMetricType":
        """
        Gets the value of metricName or its default value.
        """
        return self.getOrDefault(self.metricName)

    @since("3.0.0")
    def setMetricLabel(self, value: float) -> "MultilabelClassificationEvaluator":
        """
        Sets the value of :py:attr:`metricLabel`.
        """
        return self._set(metricLabel=value)

    @since("3.0.0")
    def getMetricLabel(self) -> float:
        """
        Gets the value of metricLabel or its default value.
        """
        return self.getOrDefault(self.metricLabel)

    @since("3.0.0")
    def setLabelCol(self, value: str) -> "MultilabelClassificationEvaluator":
        """
        Sets the value of :py:attr:`labelCol`.
        """
        return self._set(labelCol=value)

    @since("3.0.0")
    def setPredictionCol(self, value: str) -> "MultilabelClassificationEvaluator":
        """
        Sets the value of :py:attr:`predictionCol`.
        """
        return self._set(predictionCol=value)

    @keyword_only
    @since("3.0.0")
    def setParams(
        self,
        *,
        predictionCol: str = "prediction",
        labelCol: str = "label",
        metricName: "MultilabelClassificationEvaluatorMetricType" = "f1Measure",
        metricLabel: float = 0.0,
    ) -> "MultilabelClassificationEvaluator":
        """
        setParams(self, \\*, predictionCol="prediction", labelCol="label", \
                  metricName="f1Measure", metricLabel=0.0)
        Sets params for multilabel classification evaluator.
        """
        kwargs = self._input_kwargs
        return self._set(**kwargs)

    def isLargerBetter(self) -> bool:
        """Override this function to make it run on connect"""
        return self.getMetricName() != "hammingLoss"


@inherit_doc
class ClusteringEvaluator(
    JavaEvaluator,
    HasPredictionCol,
    HasFeaturesCol,
    HasWeightCol,
    JavaMLReadable["ClusteringEvaluator"],
    JavaMLWritable,
):
    """
    Evaluator for Clustering results, which expects two input
    columns: prediction and features. The metric computes the Silhouette
    measure using the squared Euclidean distance.

    The Silhouette is a measure for the validation of the consistency
    within clusters. It ranges between 1 and -1, where a value close to
    1 means that the points in a cluster are close to the other points
    in the same cluster and far from the points of the other clusters.

    .. versionadded:: 2.3.0

    Examples
    --------
    >>> from pyspark.ml.linalg import Vectors
    >>> featureAndPredictions = map(lambda x: (Vectors.dense(x[0]), x[1]),
    ...     [([0.0, 0.5], 0.0), ([0.5, 0.0], 0.0), ([10.0, 11.0], 1.0),
    ...     ([10.5, 11.5], 1.0), ([1.0, 1.0], 0.0), ([8.0, 6.0], 1.0)])
    >>> dataset = spark.createDataFrame(featureAndPredictions, ["features", "prediction"])
    ...
    >>> evaluator = ClusteringEvaluator()
    >>> evaluator.setPredictionCol("prediction")
    ClusteringEvaluator...
    >>> evaluator.evaluate(dataset)
    0.9079...
    >>> featureAndPredictionsWithWeight = map(lambda x: (Vectors.dense(x[0]), x[1], x[2]),
    ...     [([0.0, 0.5], 0.0, 2.5), ([0.5, 0.0], 0.0, 2.5), ([10.0, 11.0], 1.0, 2.5),
    ...     ([10.5, 11.5], 1.0, 2.5), ([1.0, 1.0], 0.0, 2.5), ([8.0, 6.0], 1.0, 2.5)])
    >>> dataset = spark.createDataFrame(
    ...     featureAndPredictionsWithWeight, ["features", "prediction", "weight"])
    >>> evaluator = ClusteringEvaluator()
    >>> evaluator.setPredictionCol("prediction")
    ClusteringEvaluator...
    >>> evaluator.setWeightCol("weight")
    ClusteringEvaluator...
    >>> evaluator.evaluate(dataset)
    0.9079...
    >>> ce_path = temp_path + "/ce"
    >>> evaluator.save(ce_path)
    >>> evaluator2 = ClusteringEvaluator.load(ce_path)
    >>> str(evaluator2.getPredictionCol())
    'prediction'
    """

    metricName: Param["ClusteringEvaluatorMetricType"] = Param(
        Params._dummy(),
        "metricName",
        "metric name in evaluation (silhouette)",
        typeConverter=TypeConverters.toString,  # type: ignore[arg-type]
    )
    distanceMeasure: Param["ClusteringEvaluatorDistanceMeasureType"] = Param(
        Params._dummy(),
        "distanceMeasure",
        "The distance measure. " + "Supported options: 'squaredEuclidean' and 'cosine'.",
        typeConverter=TypeConverters.toString,  # type: ignore[arg-type]
    )

    _input_kwargs: Dict[str, Any]

    @keyword_only
    def __init__(
        self,
        *,
        predictionCol: str = "prediction",
        featuresCol: str = "features",
        metricName: "ClusteringEvaluatorMetricType" = "silhouette",
        distanceMeasure: str = "squaredEuclidean",
        weightCol: Optional[str] = None,
    ):
        """
        __init__(self, \\*, predictionCol="prediction", featuresCol="features", \
                 metricName="silhouette", distanceMeasure="squaredEuclidean", weightCol=None)
        """
        super(ClusteringEvaluator, self).__init__()
        self._java_obj = self._new_java_obj(
            "org.apache.spark.ml.evaluation.ClusteringEvaluator", self.uid
        )
        self._setDefault(metricName="silhouette", distanceMeasure="squaredEuclidean")
        kwargs = self._input_kwargs
        self._set(**kwargs)

    @keyword_only
    @since("2.3.0")
    def setParams(
        self,
        *,
        predictionCol: str = "prediction",
        featuresCol: str = "features",
        metricName: "ClusteringEvaluatorMetricType" = "silhouette",
        distanceMeasure: str = "squaredEuclidean",
        weightCol: Optional[str] = None,
    ) -> "ClusteringEvaluator":
        """
        setParams(self, \\*, predictionCol="prediction", featuresCol="features", \
                  metricName="silhouette", distanceMeasure="squaredEuclidean", weightCol=None)
        Sets params for clustering evaluator.
        """
        kwargs = self._input_kwargs
        return self._set(**kwargs)

    @since("2.3.0")
    def setMetricName(self, value: "ClusteringEvaluatorMetricType") -> "ClusteringEvaluator":
        """
        Sets the value of :py:attr:`metricName`.
        """
        return self._set(metricName=value)

    @since("2.3.0")
    def getMetricName(self) -> "ClusteringEvaluatorMetricType":
        """
        Gets the value of metricName or its default value.
        """
        return self.getOrDefault(self.metricName)

    @since("2.4.0")
    def setDistanceMeasure(
        self, value: "ClusteringEvaluatorDistanceMeasureType"
    ) -> "ClusteringEvaluator":
        """
        Sets the value of :py:attr:`distanceMeasure`.
        """
        return self._set(distanceMeasure=value)

    @since("2.4.0")
    def getDistanceMeasure(self) -> "ClusteringEvaluatorDistanceMeasureType":
        """
        Gets the value of `distanceMeasure`
        """
        return self.getOrDefault(self.distanceMeasure)

    def setFeaturesCol(self, value: "str") -> "ClusteringEvaluator":
        """
        Sets the value of :py:attr:`featuresCol`.
        """
        return self._set(featuresCol=value)

    def setPredictionCol(self, value: str) -> "ClusteringEvaluator":
        """
        Sets the value of :py:attr:`predictionCol`.
        """
        return self._set(predictionCol=value)

    @since("3.1.0")
    def setWeightCol(self, value: str) -> "ClusteringEvaluator":
        """
        Sets the value of :py:attr:`weightCol`.
        """
        return self._set(weightCol=value)

    def isLargerBetter(self) -> bool:
        """Override this function to make it run on connect"""
        return True


@inherit_doc
class RankingEvaluator(
    JavaEvaluator, HasLabelCol, HasPredictionCol, JavaMLReadable["RankingEvaluator"], JavaMLWritable
):
    """
    Evaluator for Ranking, which expects two input
    columns: prediction and label.

    .. versionadded:: 3.0.0

    Notes
    -----
    Experimental

    Examples
    --------
    >>> scoreAndLabels = [([1.0, 6.0, 2.0, 7.0, 8.0, 3.0, 9.0, 10.0, 4.0, 5.0],
    ...     [1.0, 2.0, 3.0, 4.0, 5.0]),
    ...     ([4.0, 1.0, 5.0, 6.0, 2.0, 7.0, 3.0, 8.0, 9.0, 10.0], [1.0, 2.0, 3.0]),
    ...     ([1.0, 2.0, 3.0, 4.0, 5.0], [])]
    >>> dataset = spark.createDataFrame(scoreAndLabels, ["prediction", "label"])
    ...
    >>> evaluator = RankingEvaluator()
    >>> evaluator.setPredictionCol("prediction")
    RankingEvaluator...
    >>> evaluator.evaluate(dataset)
    0.35...
    >>> evaluator.evaluate(dataset, {evaluator.metricName: "precisionAtK", evaluator.k: 2})
    0.33...
    >>> ranke_path = temp_path + "/ranke"
    >>> evaluator.save(ranke_path)
    >>> evaluator2 = RankingEvaluator.load(ranke_path)
    >>> str(evaluator2.getPredictionCol())
    'prediction'
    """

    metricName: Param["RankingEvaluatorMetricType"] = Param(
        Params._dummy(),
        "metricName",
        "metric name in evaluation "
        "(meanAveragePrecision|meanAveragePrecisionAtK|"
        "precisionAtK|ndcgAtK|recallAtK)",
        typeConverter=TypeConverters.toString,  # type: ignore[arg-type]
    )
    k: Param[int] = Param(
        Params._dummy(),
        "k",
        "The ranking position value used in meanAveragePrecisionAtK|precisionAtK|"
        "ndcgAtK|recallAtK. Must be > 0. The default value is 10.",
        typeConverter=TypeConverters.toInt,
    )

    _input_kwargs: Dict[str, Any]

    @keyword_only
    def __init__(
        self,
        *,
        predictionCol: str = "prediction",
        labelCol: str = "label",
        metricName: "RankingEvaluatorMetricType" = "meanAveragePrecision",
        k: int = 10,
    ):
        """
        __init__(self, \\*, predictionCol="prediction", labelCol="label", \
                 metricName="meanAveragePrecision", k=10)
        """
        super(RankingEvaluator, self).__init__()
        self._java_obj = self._new_java_obj(
            "org.apache.spark.ml.evaluation.RankingEvaluator", self.uid
        )
        self._setDefault(metricName="meanAveragePrecision", k=10)
        kwargs = self._input_kwargs
        self._set(**kwargs)

    @since("3.0.0")
    def setMetricName(self, value: "RankingEvaluatorMetricType") -> "RankingEvaluator":
        """
        Sets the value of :py:attr:`metricName`.
        """
        return self._set(metricName=value)

    @since("3.0.0")
    def getMetricName(self) -> "RankingEvaluatorMetricType":
        """
        Gets the value of metricName or its default value.
        """
        return self.getOrDefault(self.metricName)

    @since("3.0.0")
    def setK(self, value: int) -> "RankingEvaluator":
        """
        Sets the value of :py:attr:`k`.
        """
        return self._set(k=value)

    @since("3.0.0")
    def getK(self) -> int:
        """
        Gets the value of k or its default value.
        """
        return self.getOrDefault(self.k)

    @since("3.0.0")
    def setLabelCol(self, value: str) -> "RankingEvaluator":
        """
        Sets the value of :py:attr:`labelCol`.
        """
        return self._set(labelCol=value)

    @since("3.0.0")
    def setPredictionCol(self, value: str) -> "RankingEvaluator":
        """
        Sets the value of :py:attr:`predictionCol`.
        """
        return self._set(predictionCol=value)

    @keyword_only
    @since("3.0.0")
    def setParams(
        self,
        *,
        predictionCol: str = "prediction",
        labelCol: str = "label",
        metricName: "RankingEvaluatorMetricType" = "meanAveragePrecision",
        k: int = 10,
    ) -> "RankingEvaluator":
        """
        setParams(self, \\*, predictionCol="prediction", labelCol="label", \
                  metricName="meanAveragePrecision", k=10)
        Sets params for ranking evaluator.
        """
        kwargs = self._input_kwargs
        return self._set(**kwargs)

    def isLargerBetter(self) -> bool:
        """Override this function to make it run on connect"""
        return True


if __name__ == "__main__":
    import doctest
    import tempfile
    import pyspark.ml.evaluation
    from pyspark.sql import SparkSession

    globs = pyspark.ml.evaluation.__dict__.copy()
    # The small batch size here ensures that we see multiple batches,
    # even in these small test examples:
    spark = SparkSession.builder.master("local[2]").appName("ml.evaluation tests").getOrCreate()
    globs["spark"] = spark
    temp_path = tempfile.mkdtemp()
    globs["temp_path"] = temp_path
    try:
        (failure_count, test_count) = doctest.testmod(globs=globs, optionflags=doctest.ELLIPSIS)
        spark.stop()
    finally:
        from shutil import rmtree

        try:
            rmtree(temp_path)
        except OSError:
            pass
    if failure_count:
        sys.exit(-1)
