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.
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 \]
Esperanza: \[ E[X_i] = n p_i \]
Varianza: \[ \text{Var}(X_i) = n p_i (1 - p_i) \]
Covarianza: \[ \text{Cov}(X_i, X_j) = -n p_i p_j \quad (i \neq j) \]
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} \]
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) \]
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)
}
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
# 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
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")
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)
}
# 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 ———————
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.
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 \]
Esperanza: \[ E[X_i] = n p_i \]
Varianza: \[ \text{Var}(X_i) = n p_i (1 - p_i) \]
Covarianza: \[ \text{Cov}(X_i, X_j) = -n p_i p_j \quad (i \neq j) \]
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} \]
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) \]
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)
}
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
# 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
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")
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)
}
# 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()