Noviembre de 2015
Volumen 30, número 12
Ejecución de prueba: prueba T con C#
Por James McCaffrey
La prueba t es una de las formas más fundamentales de realizar análisis estadísticos. Su objetivo es determinar si las medias (el promedio) de dos conjuntos de números son iguales cuando solo haya muestras de los dos conjuntos. Se explica mejor esta idea a través de un ejemplo. Supongamos que investiga la capacidad matemática de los hombres y las mujeres de nivel de la secundaria en un distrito escolar de gran tamaño. El examen de capacidades es costoso y lleva mucho tiempo, por lo que no es posible que todos los alumnos lo rinden. En cambio, selecciona aleatoriamente una muestra de 10 hombres y 10 mujeres, y les hace rendir el examen de matemática. A partir de los resultados de la muestra, puede realizar una prueba t para ver si la puntuación media real de todos los hombres es igual a la puntuación media real de todas las mujeres.
Existen muchas herramientas independientes, por ejemplo Excel, que pueden realizar una prueba t. Sin embargo, si quiere integrar las funcionalidades de prueba t directamente en un sistema de software, el uso de herramientas independientes puede resultar incómodo o incluso imposible, y es posible que surjan problemas sobre copyright u otros asuntos legales. En este artículo se explica cómo realizar una prueba t con código C# sin formato (sin bibliotecas externas).
La mejor forma de comprobar en qué consiste la prueba t y ver el camino que va a tomar este artículo es echar un vistazo en el programa de demostración de la Figura 1. El primer conjunto de datos es { 88, 77, 78, 85, 90, 82, 88, 98, 90 }. Puede imaginar estos como las puntuaciones de los exámenes de 10 hombres, donde uno de los hombres abandonó por algún motivo, dejando tan solo nueve puntuaciones.
Figura 1 Demostración de pruebas t con C#
El segundo conjunto de datos es { 81, 72, 67, 81, 71, 70, 82, 81 }. Puede imaginar estos como las puntuaciones de los exámenes de 10 mujeres, donde dos de las mujeres abandonaron por algún motivo, dejando tan solo ocho puntuaciones. La media del primer conjunto de datos es 86,22 y la media del segundo conjunto de datos es 75,63, lo que sugiere que las medias de los dos grupos no son las mismas porque hay una diferencia de casi 11 puntos. Sin embargo, si las puntuaciones medias globales de los dos grupos (todos los hombres y todas las mujeres) fueron, en realidad, iguales, dado que solo se usan muestras, la diferencia en las medias de muestra podrían ser por casualidad.
Al usar los dos conjuntos de datos de muestra, el programa de demostración calcula una "estadística t" (t) con el valor 3,4233 y un valor de "grado de libertad" (con frecuencia abreviado a df o indicado por la letra griega en minúscula nu, v) de 14,937. Luego, usando los valores t y df, se calcula un valor de probabilidad (valor p) con el valor 0,00379. La prueba tiene varias formas. Quizás la más común se llama la prueba t de Student. La demostración usa una variación mejorada, llamada la prueba t Welch.
El valor p es la probabilidad de que las medias reales de las dos poblaciones (todos los hombres y todas las mujeres) sean, en realidad, iguales, dadas las puntuaciones de muestra y, por tanto, que la diferencia observada de 11 puntos se debía al azar. En este caso, el valor p es muy pequeño, por lo que se debería concluir que las medias reales de todos los hombres y todas las mujeres no son iguales. En la mayoría de los problemas, el valor p crítico para la comparación con el valor p calculado se define de manera arbitraria en 0,01 o 0,05.
En otras palabras, si las puntuaciones medias reales de todos los hombres y todas las mujeres fuesen iguales, la probabilidad de que vea la diferencia observada de casi 11 puntos en las dos medias de muestra de tamaño nueve y ocho es tan solo 0,00379 (muy poco probable).
En este artículo se supone que tiene al menos conocimientos intermedios en la programación, pero no se supone que sabe nada acerca de la prueba t. Esta demostración está codificada con C#, pero no debería tener demasiados problemas si desea refactorizar el código en otro lenguaje, como Visual Basic .NET o JavaScript.
Comprender la distribución T
La prueba t se basa en la distribución t. Asimismo, la distribución t está estrechamente relacionada con la distribución normal (también conocida como Gaussian o de forma de campana). La forma de un conjunto de datos de distribución normal depende de media y la desviación estándar de los datos. La desviación estándar es un valor que mide qué grado de extensión tienen los datos o cuán variables son. Un caso especial es cuando la media (a menudo indicada por la letra griega mu, µ) es 0 y la desviación estándar (a menudo abreviado en inglés como sd o indicada con la letra griega , σ) es 1. La distribución normal con la media = 0 y la sd = 1 se llama la distribución normal estándar. Su gráfico se muestra en la Figura 2.
Figura 2 Distribución normal estándar
En la Figura 2, la ecuación que define la distribución normal estándar se llama la función de densidad de probabilidad. La distribución t se parece estrechamente a la distribución normal. La forma de una distribución t depende de un valor único llamado "grados de libertad". La distribución t con df = 5 se muestra en la Figura 3.
En la Figura 3, la ecuación que define la distribución t implica la función Gamma, que se indica con la letra griega en mayúscula gamma (Γ). Para realizar una prueba t, hay que calcular y sumar dos áreas idénticas debajo la curva de la distribución t. Esta área combinada es el valor p. Por ejemplo, en la Figura 3, si el valor de t es 2,0, las áreas combinadas debajo de la curva que necesita son desde -infinidad a -2,0 y desde +2,0 a +infinidad. En este caso, el área combinada, que es el valor pe, es 0,101939. Para el programa de demostración, cuando t = 3,4233, el área combinada es 0,00379.
Figura 3 Distribución T
Bueno, pero ¿cómo se puede calcular el área debajo de la distribución t? Existen varios métodos para solucionar este problema. Sin embargo, la técnica más común es calcular una sola área asociada debajo de la curva de la distribución normal estándar y usarla para calcular el valor p. Por ejemplo, en la Figura 2, si z (el equivalente normal de t) tiene el valor -2,0, se puede calcular el área desde -infinidad a -2,0, que es 0,02275. Esta área debajo de la curva normal entonces se puede usar para calcular el área correspondiente debajo de la distribución t.
Para resumir, para realizar una prueba t, se debe calcular y luego sumar las dos áreas (iguales) debajo de una distribución t. Esta área se llama el valor p. Para ello, se puede calcular una sola área debajo de la distribución normal estándar y luego usar esa área para obtener el valor p.
Cálculo del área debajo de la distribución normal estándar
Hay varias formas de calcular el área debajo de la curva de distribución normal estándar. Esto es uno de los problemas más antiguos de la ciencia de la informática. Mi método preferido es usar lo que se llama el algoritmo ACM 209. La Association for Computing Machinery (ACM) ha publicado muchos algoritmos fundamentales para la informática numérica y estadística.
La implementación C del algoritmo 209 se presenta en la Figura 4 como una función Gauss. La función acepta un valor, z, entre -infinidad y +infinidad, y devuelve una aproximación cercana al área debajo de la distribución normal estándar desde -infinidad a z.
Figura 4 Cálculo del área debajo de la distribución normal estándar
public static double Gauss(double z)
{
// input = z-value (-inf to +inf)
// output = p under Standard Normal curve from -inf to z
// e.g., if z = 0.0, function returns 0.5000
// ACM Algorithm #209
double y; // 209 scratch variable
double p; // result. called 'z' in 209
double w; // 209 scratch variable
if (z == 0.0)
p = 0.0;
else
{
y = Math.Abs(z) / 2;
if (y >= 3.0)
{
p = 1.0;
}
else if (y < 1.0)
{
w = y * y;
p = ((((((((0.000124818987 * w
- 0.001075204047) * w + 0.005198775019) * w
- 0.019198292004) * w + 0.059054035642) * w
- 0.151968751364) * w + 0.319152932694) * w
- 0.531923007300) * w + 0.797884560593) * y * 2.0;
}
else
{
y = y - 2.0;
p = (((((((((((((-0.000045255659 * y
+ 0.000152529290) * y - 0.000019538132) * y
- 0.000676904986) * y + 0.001390604284) * y
- 0.000794620820) * y - 0.002034254874) * y
+ 0.006549791214) * y - 0.010557625006) * y
+ 0.011630447319) * y - 0.009279453341) * y
+ 0.005353579108) * y - 0.002141268741) * y
+ 0.000535310849) * y + 0.999936657524;
}
}
if (z > 0.0)
return (p + 1.0) / 2;
else
return (1.0 - p) / 2;
}
Incluso un vistazo del código de la Figura 4 debería convencerlo de que usar un algoritmo existente, tal como ACM 209, es mucho más fácil que codificar su propia implementación desde cero. Una alternativa a ACM 209 es usar una modificación ligera de la ecuación 7.1.26 de la publicación "Handbook of Mathematical Functions" de Milton Abramowitz e Irene A. Stegun (Dover Publications, 1965).
Cálculo del área debajo de la distribución t
Con una implementación de la función Gauss en manos, el área debajo de la distribución t también se puede calcular con al algoritmo ACM 395. La implementación C del algoritmo 395 se presenta en la Figura 5 como una función Student. La función acepta un valor t y un valor de df, y devuelve un área combinada desde -infinidad hasta t, más desde t a -infinidad.
Figura 5 Cálculo del área debajo de la distribución t
public static double Student(double t, double df)
{
// for large integer df or double df
// adapted from ACM algorithm 395
// returns 2-tail p-value
double n = df; // to sync with ACM parameter name
double a, b, y;
t = t * t;
y = t / n;
b = y + 1.0;
if (y > 1.0E-6) y = Math.Log(b);
a = n - 0.5;
b = 48.0 * a * a;
y = a * y;
y = (((((-0.4 * y - 3.3) * y - 24.0) * y - 85.5) /
(0.8 * y * y + 100.0 + b) + y + 3.0) / b + 1.0) *
Math.Sqrt(y);
return 2.0 * Gauss(-y); // ACM algorithm 209
}
El algoritmo 395 tiene dos formas. Una forma acepta el parámetro df como un valor entero y la segunda forma acepta df como un valor doble de tipo. En la mayoría de los problemas de estadísticas, los grados de libertad son un valor entero, pero la prueba t Welch usa un valor de doble de tipo.
El programa de demostración
Para crear el programa de demostración, inicié Visual Studio, creé una nueva aplicación de consola de C# y la llamé TTest. La demostración no tiene ninguna dependencia significativa de la versión de .NET, por lo que debería funcionar con cualquier versión de Visual Studio. Después de cargar el código de plantilla en el editor, eliminé todas las sentencias using, excepto la única referencia al espacio de nombres del sistema de nivel superior. En la ventana del Explorador de soluciones, cambié el nombre del archivo Program.cs a TTestProgram.cs, y permití que Visual Studio cambie automáticamente el nombre de la clase Program.
El programa de demostración es demasiado largo para presentarlo aquí en su totalidad, pero el código fuente completo está disponible en la descarga que acompaña este artículo. El método Main comienza por la configuración y visualización de los dos conjuntos de datos de muestra:
Console.WriteLine("\nBegin Welch's t-test using C# demo\n");
var x = new double[] { 88, 77, 78, 85, 90, 82, 88, 98, 90 };
var y = new double[] { 81, 72, 67, 81, 71, 70, 82, 81 };
Console.WriteLine("\nThe first data set (x) is:\n");
ShowVector(x, 0);
Console.WriteLine("\nThe second data set (y) is:\n");
ShowVector(y, 0);
Todo el trabajo se realiza en un método denominado TTest:
Console.WriteLine("\nStarting Welch's t-test using C#\n");
TTest(x, y);
Console.WriteLine("\nEnd t-test demo\n");
Console.ReadLine();
La definición del método TTest comienza por la suma de los valores de cada conjunto de datos:
public static void TTest(double[] x, double[] y)
{
double sumX = 0.0;
double sumY = 0.0;
for (int i = 0; i < x.Length; ++i)
sumX += x[i];
for (int i = 0; i < y.Length; ++i)
sumY += y[i];
...
A continuación, las sumas se usan para calcular las dos medias de muestra:
int n1 = x.Length;
int n2 = y.Length;
double meanX = sumX / n1;
double meanY = sumY / n2;
A continuación, las dos medias se usan para calcular las dos varianzas de muestra:
double sumXminusMeanSquared = 0.0; // Calculate variances
double sumYminusMeanSquared = 0.0;
for (int i = 0; i < n1; ++i)
sumXminusMeanSquared += (x[i] - meanX) * (x[i] - meanX);
for (int i = 0; i < n2; ++i)
sumYminusMeanSquared += (y[i] - meanY) * (y[i] - meanY);
double varX = sumXminusMeanSquared / (n1 - 1);
double varY = sumYminusMeanSquared / (n2 - 1);
La varianza de un conjunto de datos es el cuadrado de la desviación estándar, por lo que la desviación estándar es la raíz cuadrada de la varianza y la prueba t funciona con varianzas. A continuación, se calcula la estadística t:
double top = (meanX - meanY);
double bot = Math.Sqrt((varX / n1) + (varY / n2));
double t = top / bot;
En palabras, la estadística t es la diferencia entre las dos medias de muestra, dividida por la raíz cuadrada de la suma de varianzas dividida por sus tamaños de muestra asociados. A continuación, se calculan los grados de libertad:
double num = ((varX / n1) + (varY / n2)) *
((varX / n1) + (varY / n2));
double denomLeft = ((varX / n1) * (varX / n1)) / (n1 - 1);
double denomRight = ((varY / n2) * (varY / n2)) / (n2 - 1);
double denom = denomLeft + denomRight;
double df = num / denom;
El cálculo de los grados de libertad de la prueba t Welch es algo complicado y la ecuación no es tan obvia. Afortunadamente, nunca hará falta modificar este cálculo. El método TTest concluye con el cálculo del valor p y la visualización de todos los valores calculados:
...
double p = Student(t, df); // Cumulative two-tail density
Console.WriteLine("mean of x = " + meanX.ToString("F2"));
Console.WriteLine("mean of y = " + meanY.ToString("F2"));
Console.WriteLine("t = " + t.ToString("F4"));
Console.WriteLine("df = " + df.ToString("F3"));
Console.WriteLine("p-value = " + p.ToString("F5"));
Explain();
}
El método definido por el programa, llamado Explain, muestra información que explica la interpretación del valor p, tal como se muestra en la Figura 1.
Algunos comentarios
En realidad, hay varios tipos diferentes de problemas de estadísticas que implican la prueba t. El tipo de problema que se describe en este artículo a veces se llama prueba t sin par porque no existe ninguna conexión conceptual entre los valores de datos y cada conjunto de datos de muestra. Otro tipo de prueba t se llama prueba de muestra con par, que podría usarse cuando disponga de algún tipo de datos de antes y después, tal como una puntuación de examen antes de una instrucción seguida de una puntuación de examen después de la instrucción. Aquí, cada par de puntuaciones está conceptualmente relacionada.
La prueba t Welch que se presenta aquí es superior a la prueba t Student más común en la mayoría de los escenarios. Por lo general, la prueba t Student requiere un número igual de puntos de datos en cada uno de los dos conjuntos de datos de muestra y requiere que las varianzas de las dos muestras sean aproximadamente iguales. La prueba t Welch puede funcionar con tamaños de muestra desiguales y es una opción sólida incluso cuando las varianzas de muestra difieren.
El tipo de prueba t que se explica en este artículo se llama una prueba de dos extremos. Esto es más o menos sinónimo con un problema en el que el objetivo es determinar si dos medias de grupo son iguales. Una prueba t de un extremo se puede usar in situaciones en las que el objetivo es determinar si la media de un grupo es mayor que la media del otro grupo. Al realizar una prueba t de un extremo, el valor p de dos extremos se divide por 2.
Debería ser muy conservador a la hora de interpretar los resultados de una prueba t. Una conclusión tipo "según un valor p de prueba t calculado de 0,008, concluyo que es poco probable que las medias reales de la población de hombres y mujeres sean iguales" es mucho mejor que "el valor p de 0,008 significa que las puntaciones medias de los hombres son mayores que las de las mujeres".
Una alternativa a la prueba t se llama la prueba Mann-Whitney U. Ambas técnicas infieren si dos medias de una población son iguales o no basándose en muestras. Sin embargo, la prueba Mann-Whitney U hace menos suposiciones estadísticas, lo que lleva a conclusiones más conservadoras (hay menos probabilidad de que concluya que las medias investigadas sean diferentes).
La prueba t se limita a situaciones en las que existen dos grupos. Para los problemas en los que se examinan las medias de tres grupos o más, se usaría un análisis llamado prueba f.
Dr. James McCaffreytrabaja para Microsoft Research en Redmond, Washington. Ha colaborado en el desarrollo de varios productos de Microsoft como, por ejemplo, Internet Explorer y Bing. Dr. Puede ponerse en contacto James en jammc@microsoft.com.
Gracias al siguiente experto técnico de Microsoft Research por revisar este artículo: Kirk Olynyk