# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
# --------------------------------------------------------------------------------------------
# - Generated by tools/entrypoint_compiler.py: do not edit by hand
"""
KMeansPlusPlus
"""

__all__ = ["KMeansPlusPlus"]


from sklearn.base import ClusterMixin

from ..base_predictor import BasePredictor
from ..internal.core.cluster.kmeansplusplus import KMeansPlusPlus as core
from ..internal.utils.utils import trace


class KMeansPlusPlus(core, BasePredictor, ClusterMixin):
    """

    Machine Learning KMeans clustering algorithm

    .. remarks::
        `K-means <https://en.wikipedia.org/wiki/K-means_clustering>`_ is a
        popular clustering algorithm. With `K-means++
        <https://en.wikipedia.org/wiki/K-means%2b%2b>`_, the data is
        clustered
        into a specified number of clusters in order to minimize the
        within-cluster sum of squares. K-means++ improves upon K-means by
        using
        a better method for choosing the initial cluster centers.


        **Reference**

            `https://www.microsoft.com/en-us/research/wp-
            content/uploads/2016/02/ding15.pdf <https://www.microsoft.com/en-
            us/research/wp-content/uploads/2016/02/ding15.pdf>`_


    :param feature: see `Columns </nimbusml/concepts/columns>`_.

    :param weight: see `Columns </nimbusml/concepts/columns>`_.

    :param normalize: Specifies the type of automatic normalization used:

        * ``"Auto"``: if normalization is needed, it is performed
          automatically. This is the default choice.
        * ``"No"``: no normalization is performed.
        * ``"Yes"``: normalization is performed.
        * ``"Warn"``: if normalization is needed, a warning
          message is displayed, but normalization is not performed.

        Normalization rescales disparate data ranges to a standard scale.
        Feature
        scaling insures the distances between data points are proportional
        and
        enables various optimization methods such as gradient descent to
        converge
        much faster. If normalization is performed, a ``MaxMin`` normalizer
        is
        used. It normalizes values in an interval [a, b] where ``-1 <= a <=
        0``
        and ``0 <= b <= 1`` and ``b - a = 1``. This normalizer preserves
        sparsity by mapping zero to zero.

    :param caching: Whether learner should cache input training data.

    :param n_clusters: The number of clusters.

    :param train_threads: Degree of lock-free parallelism. Defaults to
        automatic. Determinism not guaranteed.

    :param init_algorithm: Cluster initialization algorithm.

    :param opt_tol: Tolerance parameter for trainer convergence. Lower =
        slower, more accurate.

    :param max_iterations: Maximum number of iterations.

    :param accel_mem_budget_mb: Memory budget (in MBs) to use for KMeans
        acceleration.

    :param params: Additional arguments sent to compute engine.

    .. seealso::
        :py:func:`LogisticRegressionClassifier
        <nimbusml.linear_model.LogisticRegressionClassifier>`,
        :py:func:`AveragedPerceptronBinaryClassifier
        <nimbusml.linear_model.AveragedPerceptronBinaryClassifier>`

    .. index:: models, classification, stocastic, gradient, descent

    Example:
       .. literalinclude:: /../nimbusml/examples/KMeansPlusPlus.py
              :language: python
    """

    @trace
    def __init__(
            self,
            normalize='Auto',
            caching='Auto',
            n_clusters=5,
            train_threads=None,
            init_algorithm='KMeansParallel',
            opt_tol=1e-07,
            max_iterations=1000,
            accel_mem_budget_mb=4096,
            feature=None,
            weight=None,
            **params):

        if 'feature_column' in params:
            raise NameError(
                "'feature_column' must be renamed to 'feature'")
        if feature:
            params['feature_column'] = feature
        if 'weight_column' in params:
            raise NameError(
                "'weight_column' must be renamed to 'weight'")
        if weight:
            params['weight_column'] = weight
        BasePredictor.__init__(self, type='clusterer', **params)
        core.__init__(
            self,
            normalize=normalize,
            caching=caching,
            n_clusters=n_clusters,
            train_threads=train_threads,
            init_algorithm=init_algorithm,
            opt_tol=opt_tol,
            max_iterations=max_iterations,
            accel_mem_budget_mb=accel_mem_budget_mb,
            **params)
        self.feature = feature
        self.weight = weight

    def get_params(self, deep=False):
        """
        Get the parameters for this operator.
        """
        return core.get_params(self)
