# `Scholar.NaiveBayes.Complement`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/naive_bayes/complement.ex#L1)

The Complement Naive Bayes classifier.

It was designed to correct the assumption of Multinomial Naive Bayes
that each class has roughly the same representation. It is particularly
suited for imbalanced data sets.

Time complexity is $O(K * N * C)$ where $N$ is the number of samples and $K$ is the number of features,
and $C$ is the number of classes.

Reference:

* [1] [Tackling the Poor Assumptions of Naive Bayes Text Classifiers](https://cdn.aaai.org/ICML/2003/ICML03-081.pdf)

# `fit`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/naive_bayes/complement.ex#L174)

Fits a complement naive Bayes classifier. The function assumes that the targets `y` are integers
between 0 and `num_classes` - 1 (inclusive). Otherwise, those samples will not
contribute to `class_count`.

## Options

* `:alpha` - Additive (Laplace/Lidstone) smoothing parameter
  (set alpha to 0.0 and force_alpha to true, for no smoothing). The default value is `1.0`.

* `:force_alpha` (`t:boolean/0`) - If False and alpha is less than 1e-10, it will set alpha to
  1e-10. If True, alpha will remain unchanged. This may cause
  numerical errors if alpha is too close to 0. The default value is `true`.

* `:fit_priors` (`t:boolean/0`) - Whether to learn class prior probabilities or not.
  If false, a uniform prior will be used. The default value is `true`.

* `:priors` - Prior probabilities of the classes. If specified, the priors are not
  adjusted according to the data.

* `:num_classes` (`t:pos_integer/0`) - Required. Number of different classes used in training.

* `:sample_weights` - List of `n_samples` elements.
  A list of 1.0 values is used if none is given.

* `:norm` (`t:boolean/0`) - Whether or not a second normalization of the weights is performed. The default value is `false`.

## Return Values

The function returns a struct with the following parameters:

  * `:feature_log_probability` - Empirical log probability of features
      given a class, ``P(x_i|y)``.

  * `:class_count` - Number of samples encountered for each class during fitting. This
      value is weighted by the sample weight when provided.

  * `:class_log_priors` - Smoothed empirical log probability for each class.

  * `:classes` - class labels known to the classifier.

  * `:feature_count` - Number of samples encountered for each (class, feature)
      during fitting. This value is weighted by the sample weight when
      provided.

  * `:feature_all` - Number of samples encountered for each feature during fitting.
      This value is weighted by the `sample_weights` when provided.

## Examples

    iex> x = Nx.iota({4, 3})
    iex> y = Nx.tensor([1, 2, 0, 2])
    iex> Scholar.NaiveBayes.Complement.fit(x, y, num_classes: 3)
    %Scholar.NaiveBayes.Complement{
      feature_log_probability: Nx.tensor(
        [
          [1.3062516450881958, 1.0986123085021973, 0.9267619848251343],
          [1.2452157735824585, 1.0986123085021973, 0.9707789421081543],
          [1.3499267101287842, 1.0986123085021973, 0.8979415893554688]
        ]
      ),
      class_count: Nx.tensor([1.0, 1.0, 2.0]),
      class_log_priors: Nx.tensor([-1.3862943649291992, -1.3862943649291992, -0.6931471824645996]),
      classes: Nx.tensor([0, 1, 2]),
      feature_count: Nx.tensor(
        [
          [6.0, 7.0, 8.0],
          [0.0, 1.0, 2.0],
          [12.0, 14.0, 16.0]
        ]
      ),
      feature_all: Nx.tensor([18.0, 22.0, 26.0])
    }
    iex> x = Nx.iota({4, 3})
    iex> y = Nx.tensor([1, 2, 0, 2])
    iex> Scholar.NaiveBayes.Complement.fit(x, y, num_classes: 3, sample_weights: [1, 6, 2, 3])
    %Scholar.NaiveBayes.Complement{
      feature_log_probability: Nx.tensor(
        [
          [1.2953225374221802, 1.0986123085021973, 0.9343092441558838],
          [1.2722758054733276, 1.0986123085021973, 0.9506921768188477],
          [1.3062516450881958, 1.0986123085021973, 0.9267619848251343]
        ]
      ),
      class_count: Nx.tensor([2.0, 1.0, 9.0]),
      class_log_priors: Nx.tensor([-1.7917594909667969, -2.4849066734313965, -0.28768205642700195]),
      classes: Nx.tensor([0, 1, 2]),
      feature_count: Nx.tensor(
        [
          [12.0, 14.0, 16.0],
          [0.0, 1.0, 2.0],
          [45.0, 54.0, 63.0]
        ]
      ),
      feature_all: Nx.tensor([57.0, 69.0, 81.0])
    }

# `predict`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/naive_bayes/complement.ex#L210)

Perform classification on an array of test vectors `x` using `model`.

## Examples

    iex> x = Nx.iota({4, 3})
    iex> y = Nx.tensor([1, 2, 0, 2])
    iex> model = Scholar.NaiveBayes.Complement.fit(x, y, num_classes: 3)
    iex> Scholar.NaiveBayes.Complement.predict(model, Nx.tensor([[6, 2, 4], [8, 5, 9]]))
    #Nx.Tensor<
      s32[2]
      [2, 2]
    >

# `predict_joint_log_probability`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/naive_bayes/complement.ex#L286)

Return joint log probability estimates for the test vector `x` using `model`.

## Examples

    iex> x = Nx.iota({4, 3})
    iex> y = Nx.tensor([1, 2, 0, 2])
    iex> model = Scholar.NaiveBayes.Complement.fit(x, y, num_classes: 3)
    iex> Scholar.NaiveBayes.Complement.predict_joint_log_probability(model, Nx.tensor([[6, 2, 4], [8, 5, 9]]))
    #Nx.Tensor<
      f32[2][3]
      [
        [13.741782188415527, 13.551634788513184, 13.888551712036133],
        [24.283931732177734, 24.19179916381836, 24.37394905090332]
      ]
    >

# `predict_log_probability`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/naive_bayes/complement.ex#L233)

Return log-probability estimates for the test vector `x` using `model`.

## Examples

    iex> x = Nx.iota({4, 3})
    iex> y = Nx.tensor([1, 2, 0, 2])
    iex> model = Scholar.NaiveBayes.Complement.fit(x, y, num_classes: 3)
    iex> Scholar.NaiveBayes.Complement.predict_log_probability(model, Nx.tensor([[6, 2, 4], [8, 5, 9]]))
    #Nx.Tensor<
      f32[2][3]
      [
        [-1.0935745239257812, -1.283721923828125, -0.9468050003051758],
        [-1.1006698608398438, -1.1928024291992188, -1.0106525421142578]
      ]
    >

# `predict_probability`
[🔗](https://github.com/elixir-nx/scholar/blob/main/lib/scholar/naive_bayes/complement.ex#L265)

Return probability estimates for the test vector `x` using `model`.

## Examples

    iex> x = Nx.iota({4, 3})
    iex> y = Nx.tensor([1, 2, 0, 2])
    iex> model = Scholar.NaiveBayes.Complement.fit(x, y, num_classes: 3)
    iex> Scholar.NaiveBayes.Complement.predict_probability(model, Nx.tensor([[6, 2, 4], [8, 5, 9]]))
    #Nx.Tensor<
      f32[2][3]
      [
        [0.33501681685447693, 0.2770043909549713, 0.3879786431789398],
        [0.3326481878757477, 0.3033699095249176, 0.3639813959598541]
      ]
    >

---

*Consult [api-reference.md](api-reference.md) for complete listing*
