🛡️ StatGuard: Estadistica Robusta e Integridad de Datos para PHP¶
StatGuard es una suite de analisis estadistico robusto para PHP enfocada en precision cientifica e integridad de datos. Compara estadistica clasica contra estadistica robusta para detectar sesgo, ruido y anomalias de medicion de forma automatica.
¿Por qué StatGuard?¶
Los valores atipicos son inevitables en telemetria, finanzas, deporte y laboratorios. Un solo valor extremo puede arrastrar la media aritmetica lejos de la masa central y sesgar las decisiones. StatGuard ofrece estimadores robustos (mediana, MAD, medias recortadas y winsorizadas, estimador M de Huber) que se mantienen estables bajo contaminacion, permitiendo confiar en los resumenes aun con datos ruidosos.
Destacados¶
- ClassicStats: Implementacion completa de estadistica descriptiva clasica.
- StatsComparator: Nucleo de analisis que evalua la fidelidad de los datos y emite un veredicto.
- ExportableTrait: Exportacion CSV y JSON para cada clase estadistica.
- Traits + Interfaces: Validacion integrada y arquitectura extensible.
- Motores independientes:
QuantileEngineyCentralTendencyEnginemantienen la matematica central aislada y reutilizable. - Paridad con R: Cuantiles y medias robustas validadas contra resultados de R.
Caracteristicas¶
- 9 tipos de cuantiles compatibles con R (Hyndman & Fan 1-9).
- Medias robustas: Huber, winsorizada y recortada.
Instalacion¶
Instalacion via Composer:
composer require cjuol/statguard
Uso¶
Estimadores Robustos (Inicio Rapido)¶
use Cjuol\StatGuard\RobustStats;
$stats = new RobustStats();
$data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1000];
$huber = $stats->getHuberMean($data);
$winsorized = $stats->getWinsorizedMean($data, 0.1);
$iqr = $stats->getIqr($data, RobustStats::TYPE_R_DEFAULT);
Los estimadores robustos se mantienen estables ante valores atipicos extremos:
| Metrica | Resultado | Comentario |
|---|---|---|
| Media aritmetica | 95.9091 | Sesgada por el valor atipico |
| Media de Huber | 6.0982 | Cerca de la masa central |
Ejemplo: Media de Huber¶
use Cjuol\StatGuard\RobustStats;
$robust = new RobustStats();
$data = [10, 12, 11, 15, 10, 1000];
$huber = $robust->getHuberMean($data, 1.345, 50, 0.001);
Ejemplo: Media Winsorizada (Tipo de Cuantil Compatible con R)¶
use Cjuol\StatGuard\RobustStats;
$robust = new RobustStats();
$data = [10, 12, 11, 15, 10, 1000];
// El tipo 7 coincide con el quantile() por defecto de R.
$winsorized = $robust->getWinsorizedMean($data, 0.1, 7);
Comparator (Deteccion de Sesgo)¶
use Cjuol\StatGuard\StatsComparator;
$comparator = new StatsComparator();
$data = [10, 12, 11, 15, 10, 1000];
$analysis = $comparator->analyze($data);
echo $analysis['verdict'];
// ALERTA: Los datos estan muy influidos por valores atipicos. Use metricas robustas.
Exportacion Instantanea¶
use Cjuol\StatGuard\RobustStats;
$robust = new RobustStats();
file_put_contents('report.csv', $robust->toCsv($data));
echo $robust->toJson($data);
Claves de Resumen (Clasico vs Robusto)¶
Claves clasicas:
[
'mean',
'median',
'stdDev',
'sampleVariance',
'cv',
'outliersZScore',
'count'
]
Claves robustas:
[
'mean',
'median',
'robustDeviation',
'robustVariance',
'robustCv',
'iqr',
'mad',
'outliers',
'confidenceIntervals',
'count'
]
Comparativa de Metricas¶
| Metrica | ClassicStats | RobustStats | Impacto del Valor Atipico |
|---|---|---|---|
| Centro | Media | Mediana | Alto en clasico |
| Dispersion | Desviacion estandar | MAD (escalado) | Extremo en clasico |
| Variabilidad | CV% | CV% robusto | Muy alto en clasico |
| Exportable | ✅ Si | ✅ Si | - |
Tipos de Cuantil R (1-9)¶
StatGuard replica las definiciones de cuantiles de R v4.x. La tabla resume los nueve tipos de Hyndman & Fan (1996) soportados por quantile().
| Tipo | \(p_k\) | \(a\) | \(b\) | Notas |
|---|---|---|---|---|
| 1 | \(k / n\) | 0 | 0 | Inversa de la CDF empirica (discontinua). |
| 2 | \(k / n\) | 0 | 0 | Promediado en discontinuidades. |
| 3 | \((k - 0.5) / n\) | -0.5 | 0 | Estadistico de orden mas cercano. |
| 4 | \(k / n\) | 0 | 1 | Interpolacion lineal de la CDF. |
| 5 | \((k - 0.5) / n\) | 0.5 | 0.5 | Hazen (1914). |
| 6 | \(k / (n + 1)\) | 0 | 1 | Weibull (1939). |
| 7 | \((k - 1) / (n - 1)\) | 1 | 1 | Por defecto de R, modo de \(F(x)\). |
| 8 | \((k - 1/3) / (n + 1/3)\) | 1/3 | 1/3 | Mediana-no-sesgado. |
| 9 | \((k - 3/8) / (n + 1/4)\) | 3/8 | 3/8 | Normal-no-sesgado. |
Metodos Implementados¶
ClassicStats¶
getMean(array $data): floatgetMedian(array $data): floatgetDeviation(array $data): floatgetStandardDeviation(array $data): floatgetCoefficientOfVariation(array $data): floatgetSampleVariance(array $data): floatgetPopulationVariance(array $data): floatgetOutliers(array $data): arraygetSummary(array $data, bool $sort = true, int $decimals = 2): arraytoJson(array $data, int $options = JSON_PRETTY_PRINT): stringtoCsv(array $data, string $delimiter = ","): string
RobustStats¶
getMean(array $data): floatgetMedian(array $data): floatgetDeviation(array $data): floatgetCoefficientOfVariation(array $data): floatgetRobustDeviation(array $data): floatgetRobustCv(array $data): floatgetRobustVariance(array $data): floatgetIqr(array $data): floatgetMad(array $data): floatgetOutliers(array $data): arraygetConfidenceIntervals(array $data): arraygetTrimmedMean(array $data, float $trimPercentage = 0.1): floatgetWinsorizedMean(array $data, float $trimPercentage = 0.1, int $type = 7): floatgetHuberMean(array $data, float $k = 1.345, int $maxIterations = 50, float $tolerance = 0.001): floatgetSummary(array $data, bool $sort = true, int $decimals = 2): arraytoJson(array $data, int $options = JSON_PRETTY_PRINT): stringtoCsv(array $data, string $delimiter = ","): string
StatsComparator¶
__construct(?RobustStats $robust = null, ?ClassicStats $classic = null)analyze(array $data, int $decimals = 2): array
Base Matematica¶
Desviacion Robusta Escalada¶
Para comparaciones justas, la MAD se escala para ser comparable con la desviacion estandar bajo distribuciones normales:
Coeficiente de Variacion Robusta (\(CV_r\))¶
Se calcula sobre la mediana para evitar que un valor extremo infle la volatilidad: