Skip to content

Instantly share code, notes, and snippets.

@robintux
Created January 18, 2026 20:53
Show Gist options
  • Select an option

  • Save robintux/7f85fb5af34e951ebbe75db4c03d0f65 to your computer and use it in GitHub Desktop.

Select an option

Save robintux/7f85fb5af34e951ebbe75db4c03d0f65 to your computer and use it in GitHub Desktop.
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
# Parámetros comunes
np.random.seed(42)
replicas = 10000
sample_sizes = [5, 30, 100]
# --- Distribución Uniforme U(0,1) ---
# Media y varianza teóricas
mu_unif = 0.5
var_unif = 1/12
uniform_means = {}
for n in sample_sizes:
samples = np.random.uniform(0, 1, size=(replicas, n))
uniform_means[n] = np.mean(samples, axis=1)
# --- Distribución Lognormal (parámetros para log(X) ~ N(0,1)) ---
# Si log(X) ~ N(0,1), entonces X ~ Lognormal(0,1)
# Media y varianza teóricas de X
mu_log = np.exp(0.5) # ≈ 1.6487
var_log = (np.exp(1) - 1) * np.exp(1) # ≈ 4.6708
lognormal_means = {}
for n in sample_sizes:
samples = np.random.lognormal(mean=0, sigma=1, size=(replicas, n))
lognormal_means[n] = np.mean(samples, axis=1)
# --- Cálculo del error de Kolmogorov-Smirnov (KS) ---
# Este error mide la distancia máxima entre la CDF empírica y la CDF teórica normal.
ks_errors = {'Uniform': [], 'Lognormal': []}
for n in sample_sizes:
# Para la Uniforme
means_unif = uniform_means[n]
se_unif = np.sqrt(var_unif / n)
ks_unif, _ = stats.kstest(means_unif, 'norm', args=(mu_unif, se_unif))
ks_errors['Uniform'].append(ks_unif)
# Para la Lognormal
means_log = lognormal_means[n]
se_log = np.sqrt(var_log / n)
ks_log, _ = stats.kstest(means_log, 'norm', args=(mu_log, se_log))
ks_errors['Lognormal'].append(ks_log)
# --- Visualización ---
fig, axes = plt.subplots(2, 3, figsize=(18, 10))
# Gráficos de histogramas
for i, n in enumerate(sample_sizes):
# Uniforme
ax = axes[0, i]
ax.hist(uniform_means[n], bins=50, density=True, alpha=0.7, color='skyblue', edgecolor='black')
x = np.linspace(mu_unif - 4*np.sqrt(var_unif/n), mu_unif + 4*np.sqrt(var_unif/n), 200)
y = stats.norm.pdf(x, mu_unif, np.sqrt(var_unif/n))
ax.plot(x, y, 'r--', linewidth=2, label='Normal teórica')
ax.set_title(f'Uniforme: n = {n}\nError KS: {ks_errors["Uniform"][i]:.4f}')
ax.set_xlabel('Media muestral')
ax.set_ylabel('Densidad')
ax.legend()
# Lognormal
ax = axes[1, i]
# Para visualizar mejor, truncamos los valores extremos en el gráfico (no en los cálculos)
means_trunc = lognormal_means[n][lognormal_means[n] < np.percentile(lognormal_means[n], 99)]
ax.hist(means_trunc, bins=50, density=True, alpha=0.7, color='lightcoral', edgecolor='black')
x = np.linspace(mu_log - 4*np.sqrt(var_log/n), mu_log + 4*np.sqrt(var_log/n), 200)
y = stats.norm.pdf(x, mu_log, np.sqrt(var_log/n))
ax.plot(x, y, 'r--', linewidth=2, label='Normal teórica')
ax.set_title(f'Lognormal: n = {n}\nError KS: {ks_errors["Lognormal"][i]:.4f}')
ax.set_xlabel('Media muestral')
ax.set_ylabel('Densidad')
ax.legend()
plt.tight_layout()
plt.show()
# --- Tabla de comparación de errores KS ---
print("Comparación de velocidades de convergencia (Error de Kolmogorov-Smirnov):")
print("-" * 65)
print(f"{'Tamaño de muestra (n)':<20} {'Uniforme':<15} {'Lognormal':<15}")
print("-" * 65)
for i, n in enumerate(sample_sizes):
print(f"{n:<20} {ks_errors['Uniform'][i]:<15.4f} {ks_errors['Lognormal'][i]:<15.4f}")
print("-" * 65)
print("Un error KS más pequeño indica una convergencia más rápida a la normalidad.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment