Multinomial

La distribución multinomial es una generalización de la distribución binomial a más de dos categorías. Se utiliza para modelar conteos en experimentos donde cada observación pertenece a una de \(k\) categorías.


Distribución Multinomial

Sea un vector de probabilidades:

\[ \mathbf{p} = (p_1, p_2, \dots, p_k), \quad \text{con } \sum_{i=1}^k p_i = 1 \]

y un número de ensayos \(n\).

Si \(\mathbf{X} = (X_1, X_2, \dots, X_k)\) sigue una distribución multinomial:

\[ \mathbf{X} \sim \text{Multinomial}(n, \mathbf{p}) \]

entonces su función de probabilidad es:

\[ P(X_1 = x_1, \dots, X_k = x_k) = \frac{n!}{x_1! x_2! \cdots x_k!} \prod_{i=1}^k p_i^{x_i} \]

con:

\[ \sum_{i=1}^k x_i = n \]


Propiedades


Enfoque Bayesiano

Prior: Distribución Dirichlet

Se utiliza como prior conjugado:

\[ \mathbf{p} \sim \text{Dirichlet}(\alpha_1, \dots, \alpha_k) \]

con densidad:

\[ f(\mathbf{p}) \propto \prod_{i=1}^k p_i^{\alpha_i - 1} \]


Posterior

Si observamos datos:

\[ \mathbf{x} = (x_1, \dots, x_k) \]

entonces la posterior es:

\[ \mathbf{p} \mid \mathbf{x} \sim \text{Dirichlet}(\alpha_1 + x_1, \dots, \alpha_k + x_k) \]


Implementación en R

Función Dirichlet

rdirichlet <- function(alpha, n) {
  k <- length(alpha)
  dirichlet <- matrix(NA, n, k)

  for (j in 1:n) {
    x <- numeric(k)
    remaining <- 1

    for (i in 1:(k - 1)) {
      x[i] <- rbeta(1, alpha[i], sum(alpha[(i + 1):k]))
      x[i] <- x[i] * remaining
      remaining <- remaining - x[i]
    }

    x[k] <- remaining
    dirichlet[j, ] <- x
  }

  return(dirichlet)
}

Simulación

set.seed(123)

alpha <- c(4, 3, 5)
muestras <- rdirichlet(alpha, 10000)

colMeans(muestras)
## [1] 0.3322533 0.2494047 0.4183420
alpha / sum(alpha)
## [1] 0.3333333 0.2500000 0.4166667

Ejemplo Bayesiano

# Datos observados
conteos <- c(30, 25, 45)

# Prior
alpha_prior <- c(4, 3, 5)

# Posterior
alpha_post <- alpha_prior + conteos

# Simulación posterior
posterior <- rdirichlet(alpha_post, 10000)

colMeans(posterior)
## [1] 0.3035964 0.2499628 0.4464408

Gráficos

Histogramas

par(mfrow = c(1,3))

hist(posterior[,1], col="skyblue", main="p1")
hist(posterior[,2], col="salmon", main="p2")
hist(posterior[,3], col="lightgreen", main="p3")


Comparación Prior vs Posterior

prior <- rdirichlet(alpha_prior, 10000)

par(mfrow = c(1,3))

for(i in 1:3){
  hist(prior[,i], col=rgb(1,0,0,0.4), freq=FALSE)
  hist(posterior[,i], col=rgb(0,0,1,0.4), add=TRUE)
}


Gráfico Ternario

# install.packages("ggtern")
library(ggtern)
## Warning: package 'ggtern' was built under R version 4.5.3
## Cargando paquete requerido: ggplot2
## --
## Remember to cite, run citation(package = 'ggtern') for further info.
## --
## 
## Adjuntando el paquete: 'ggtern'
## The following objects are masked from 'package:ggplot2':
## 
##     aes, annotate, ggplot, ggplot_build, ggplot_gtable, ggplotGrob,
##     ggsave, layer_data, theme_bw, theme_classic, theme_dark,
##     theme_gray, theme_light, theme_linedraw, theme_minimal, theme_void
df <- data.frame(posterior)
colnames(df) <- c("p1","p2","p3")

ggtern(data=df, aes(x=p1, y=p2, z=p3)) +
  geom_point(alpha=0.3, color="blue") +
  theme_minimal()

rdirichlet <- function(alpha, n) {
  k <- length(alpha)
  dirichlet <- matrix(NA, n, k)

  for (j in 1:n) {
    x <- numeric(k)
    remaining <- 1

    for (i in 1:(k - 1)) {
      x[i] <- rbeta(1, alpha[i], sum(alpha[(i + 1):k]))
      x[i] <- x[i] * remaining
      remaining <- remaining - x[i]
    }

    x[k] <- remaining
    dirichlet[j, ] <- x
  }

  return(dirichlet)
}
alpha <- c(4, 3, 5)
set.seed(12)

muestras <- rdirichlet(alpha, 100000)

colMeans(muestras)
## [1] 0.3341678 0.2498460 0.4159863
alpha / sum(alpha)
## [1] 0.3333333 0.2500000 0.4166667
# Datos observados
conteos <- c(30, 25, 45)

# Prior
alpha_prior <- c(4, 3, 5)

# Posterior
alpha_post <- alpha_prior + conteos

# Simulación posterior
set.seed(123)
posterior_samples <- rdirichlet(alpha_post, 10000)

# Media posterior
colMeans(posterior_samples)
## [1] 0.3027724 0.2503038 0.4469238
par(mfrow = c(1,3))

hist(posterior_samples[,1], col="skyblue", main="p1", xlab="Probabilidad")
hist(posterior_samples[,2], col="salmon", main="p2", xlab="Probabilidad")
hist(posterior_samples[,3], col="lightgreen", main="p3", xlab="Probabilidad")

prior_samples <- rdirichlet(alpha_prior, 10000)

par(mfrow = c(1,3))

for(i in 1:3){
  hist(prior_samples[,i], col=rgb(1,0,0,0.4), freq=FALSE,
       main=paste("Componente", i), xlab="p")
  hist(posterior_samples[,i], col=rgb(0,0,1,0.4), freq=FALSE, add=TRUE)
  legend("topright", legend=c("Prior", "Posterior"),
         fill=c(rgb(1,0,0,0.4), rgb(0,0,1,0.4)))
}

#install.packages("ggtern")
library(ggtern)

df <- data.frame(posterior_samples)
colnames(df) <- c("p1","p2","p3")

ggtern(data=df, aes(x=p1, y=p2, z=p3)) +
  geom_point(alpha=0.3, color="blue") +
  theme_minimal() +
  ggtitle("Distribución Posterior Dirichlet")

alpha_post = alpha_prior + conteos
alpha_post
## [1] 34 28 50

title: “Modelo Multinomial y Enfoque Bayesiano con Dirichlet” author: “Tu Nombre” date: “2026-04-17” output: html_document ———————

Introducción

La distribución multinomial es una generalización de la distribución binomial a más de dos categorías. Se utiliza para modelar conteos en experimentos donde cada observación pertenece a una de \(k\) categorías.


Distribución Multinomial

Sea un vector de probabilidades:

\[ \mathbf{p} = (p_1, p_2, \dots, p_k), \quad \text{con } \sum_{i=1}^k p_i = 1 \]

y un número de ensayos \(n\).

Si \(\mathbf{X} = (X_1, X_2, \dots, X_k)\) sigue una distribución multinomial:

\[ \mathbf{X} \sim \text{Multinomial}(n, \mathbf{p}) \]

entonces su función de probabilidad es:

\[ P(X_1 = x_1, \dots, X_k = x_k) = \frac{n!}{x_1! x_2! \cdots x_k!} \prod_{i=1}^k p_i^{x_i} \]

con:

\[ \sum_{i=1}^k x_i = n \]


Propiedades


Enfoque Bayesiano

Prior: Distribución Dirichlet

Se utiliza como prior conjugado:

\[ \mathbf{p} \sim \text{Dirichlet}(\alpha_1, \dots, \alpha_k) \]

con densidad:

\[ f(\mathbf{p}) \propto \prod_{i=1}^k p_i^{\alpha_i - 1} \]


Posterior

Si observamos datos:

\[ \mathbf{x} = (x_1, \dots, x_k) \]

entonces la posterior es:

\[ \mathbf{p} \mid \mathbf{x} \sim \text{Dirichlet}(\alpha_1 + x_1, \dots, \alpha_k + x_k) \]


Implementación en R

Función Dirichlet

rdirichlet <- function(alpha, n) {
  k <- length(alpha)
  dirichlet <- matrix(NA, n, k)

  for (j in 1:n) {
    x <- numeric(k)
    remaining <- 1

    for (i in 1:(k - 1)) {
      x[i] <- rbeta(1, alpha[i], sum(alpha[(i + 1):k]))
      x[i] <- x[i] * remaining
      remaining <- remaining - x[i]
    }

    x[k] <- remaining
    dirichlet[j, ] <- x
  }

  return(dirichlet)
}

Simulación

set.seed(123)

alpha <- c(4, 3, 5)
muestras <- rdirichlet(alpha, 10000)

colMeans(muestras)
## [1] 0.3322533 0.2494047 0.4183420
alpha / sum(alpha)
## [1] 0.3333333 0.2500000 0.4166667

Ejemplo Bayesiano

# Datos observados
conteos <- c(30, 25, 45)

# Prior
alpha_prior <- c(4, 3, 5)

# Posterior
alpha_post <- alpha_prior + conteos

# Simulación posterior
posterior <- rdirichlet(alpha_post, 10000)

colMeans(posterior)
## [1] 0.3035964 0.2499628 0.4464408

Gráficos

Histogramas

par(mfrow = c(1,3))

hist(posterior[,1], col="skyblue", main="p1")
hist(posterior[,2], col="salmon", main="p2")
hist(posterior[,3], col="lightgreen", main="p3")


Comparación Prior vs Posterior

prior <- rdirichlet(alpha_prior, 10000)

par(mfrow = c(1,3))

for(i in 1:3){
  hist(prior[,i], col=rgb(1,0,0,0.4), freq=FALSE)
  hist(posterior[,i], col=rgb(0,0,1,0.4), add=TRUE)
}


Gráfico Ternario

# install.packages("ggtern")
library(ggtern)

df <- data.frame(posterior)
colnames(df) <- c("p1","p2","p3")

ggtern(data=df, aes(x=p1, y=p2, z=p3)) +
  geom_point(alpha=0.3, color="blue") +
  theme_minimal()