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

Code before:
        -------
        self : object
        """
        if _refit:
            self.classes_ = None

        first_call = _check_partial_fit_first_call(self, classes)
        X, y = validate_data(self, X, y, reset=first_call)
        xp, _, device_ = get_namespace_and_device(X)
        if sample_weight is not None:
            sample_weight = xp.asarray(sample_weight, device=device_)
            sample_weight = _check_sample_weight(sample_weight, X)

        xp_y, _ = get_namespace(y)
        # If the ratio of data variance between dimensions is too small, it
        # will cause numerical errors. To address this, we artificially
        # boost the variance by epsilon, a small fraction of the standard
        # deviation of the largest dimension.
        self.epsilon_ = self.var_smoothing * xp.max(xp.var(X, axis=0))

        if first_call:
            # This is the first call to partial_fit:
            # initialize various cumulative counters
            n_features = X.shape[1]
            n_classes = self.classes_.shape[0]
            max_float_dtype = _max_precision_float_dtype(xp, device=device_)
            self.theta_ = xp.zeros(
                (n_classes, n_features), dtype=max_float_dtype, device=device_
            )
            self.var_ = xp.zeros(
                (n_classes, n_features), dtype=max_float_dtype, device=device_
            )

            self.class_count_ = xp.zeros(
                n_classes, dtype=max_float_dtype, device=device_
            )

            # Initialise the class prior
            # Take into account the priors
            if self.priors is not None:
                priors = xp.asarray(self.priors, dtype=max_float_dtype, device=device_)
                # Check that the provided prior matches the number of classes
                if priors.shape[0] != n_classes:
                    raise ValueError("Number of priors must match number of classes.")
                # Check that the sum is 1
                if not xpx.isclose(xp.sum(priors), 1.0):
                    raise ValueError("The sum of the priors should be 1.")
                # Check that the priors are non-negative
                if xp.any(priors < 0):
                    raise ValueError("Priors must be non-negative.")
                self.class_prior_ = priors

Review comment (suggestion):
I think we should use the dtype of `X` instead of attempting to allocating `float64` precision arrays in case where all the computation happens at `float32` in `_update_mean_variance`.

This change should be documented in the changelog and tests of for the dtypes of the fitted attributed should be updated/added.

Code after:
        -------
        self : object
        """
        if _refit:
            self.classes_ = None

        first_call = _check_partial_fit_first_call(self, classes)
        X, y = validate_data(self, X, y, reset=first_call)
        xp, _, device_ = get_namespace_and_device(X)
        float_dtype = _find_matching_floating_dtype(X, xp=xp)
        if sample_weight is not None:
            sample_weight = _check_sample_weight(sample_weight, X, dtype=float_dtype)

        xp_y, _ = get_namespace(y)
        # If the ratio of data variance between dimensions is too small, it
        # will cause numerical errors. To address this, we artificially
        # boost the variance by epsilon, a small fraction of the standard
        # deviation of the largest dimension.
        self.epsilon_ = self.var_smoothing * xp.max(xp.var(X, axis=0))

        if first_call:
            # This is the first call to partial_fit:
            # initialize various cumulative counters
            n_features = X.shape[1]
            n_classes = self.classes_.shape[0]
            self.theta_ = xp.zeros(
                (n_classes, n_features), dtype=float_dtype, device=device_
            )
            self.var_ = xp.zeros(
                (n_classes, n_features), dtype=float_dtype, device=device_
            )

            self.class_count_ = xp.zeros(n_classes, dtype=float_dtype, device=device_)

            # Initialise the class prior
            # Take into account the priors
            if self.priors is not None:
                priors = xp.asarray(self.priors, dtype=float_dtype, device=device_)
                # Check that the provided prior matches the number of classes
                if priors.shape[0] != n_classes:
                    raise ValueError("Number of priors must match number of classes.")
                # Check that the sum is 1
                if not xpx.isclose(xp.sum(priors), 1.0):
                    raise ValueError("The sum of the priors should be 1.")
                # Check that the priors are non-negative
                if xp.any(priors < 0):
                    raise ValueError("Priors must be non-negative.")
                self.class_prior_ = priors
            else:
                # Initialize the priors to zeros for each class
                self.class_prior_ = xp.zeros(