{"id":239,"date":"2020-06-29T22:46:12","date_gmt":"2020-06-29T20:46:12","guid":{"rendered":"https:\/\/intsight.com\/?p=239"},"modified":"2021-01-21T17:15:34","modified_gmt":"2021-01-21T16:15:34","slug":"varianza","status":"publish","type":"post","link":"https:\/\/intsight.com\/index.php\/2020\/06\/29\/varianza\/","title":{"rendered":"Varianza"},"content":{"rendered":"<p><span style=\"font-variant: small-caps;\">Todo el mundo sabe<\/span> lo que es una media (me refiero a la media estad\u00edstica, por supuesto, no a las otras), por lo que no tiene mucho sentido escribir una entrada sobre medias. Conceptualmente, sin embargo, la media es el primer elemento de una serie de valores que caracterizan a las series aleatorias, y que se conocen como\u00a0<em>momentos<\/em>. Si nos saltamos el primer momento, aterrizamos en el segundo momento estad\u00edstico, que es la varianza o, cuando tenemos una distribuci\u00f3n multivariante, la matriz de covarianza.<\/p>\n<h4>Definici\u00f3n<\/h4>\n<p>Casi todo el mundo tiene tambi\u00e9n claro c\u00f3mo se define la varianza, pero refresqu\u00e9moslo, por si acaso. Supongamos que la media de una serie, o de una variable aleatoria, se representa como $\\mathbb{E}[X]$. Entonces, la varianza se puede definir as\u00ed:<br \/>\n$$<br \/>\nVar(X)=\\mathbb{E}[(X-\\mathbb{E}[X])^2]<br \/>\n$$S\u00ed, estamos usando la media dentro de otra media. Seg\u00fan esta definici\u00f3n, literalmente, tenemos primero que conocer la media de la variable aleatoria. Entonces, tenemos que ver cu\u00e1nto se desv\u00eda la variable aleatoria de esa media. Esto es, se mide el grado de \u00abdesparrame\u00bb de la variable. No podemos medir directamente la media de la resta que hemos mencionado, porque los valores negativos se compensar\u00edan con los valores positivos, y obtendr\u00edamos siempre cero. La manera de evitar esta compensaci\u00f3n es elevar la resta al cuadrado.<\/p>\n<p>Si masajeamos un poco la definici\u00f3n, podemos transformarla de esta manera:<br \/>\n$$<br \/>\nVar(X)=\\mathbb{E}[X^2] &#8211; \\mathbb{E}[X]^2<br \/>\n$$La transformaci\u00f3n es f\u00e1cil de realizar, y no la incluyo por brevedad. La nueva f\u00f3rmula viene a decir que la varianza es la diferencia entre la media del cuadrado y el cuadrado de la media. Enseguida veremos la gran utilidad de esta definici\u00f3n alternativa.<\/p>\n<p>Por cierto, a partir de la varianza se define la <em>desviaci\u00f3n est\u00e1ndar<\/em>, que es simplemente la ra\u00edz cuadrada de la varianza. \u00bfPara qu\u00e9 necesitamos la ra\u00edz cuadrada? Principalmente, por las unidades de medida. Si la variable aleatoria <em>X<\/em> representa euros, la media estar\u00e1 expresada como euros, pero la varianza estar\u00e1 en euros al cuadrado. La desviaci\u00f3n est\u00e1ndar, en cambio, vuelve a estar en euros. Probablemente tenga otros usos y beneficios, pero ahora mismo no los recuerdo.<\/p>\n<h4>M\u00e1s definiciones<\/h4>\n<p>Si un matem\u00e1tico leyese lo que acabo de escribir, seguramente me pegar\u00eda una somanta de palos. Y con raz\u00f3n. He manejado con demasiada alegr\u00eda los t\u00e9rminos \u00abmuestra aleatoria\u00bb y \u00abvariable aleatoria\u00bb, pero si hubiese sido m\u00e1s riguroso, la introducci\u00f3n habr\u00eda sido infinita. Ahora aclaro lo que hace falta aclarar desde el punto de vista pr\u00e1ctico.<\/p>\n<p>La diferencia que tenemos que conocer es la de \u00abvarianza\u00bb contra \u00abvarianza de una muestra\u00bb. La definici\u00f3n anterior es v\u00e1lida para una variable aleatoria definida anal\u00edticamente, o para fen\u00f3menos en los que disponemos de todos los datos. En la vida real, lo que solemos tener es una muestra de una serie, no todos los elementos. En ese caso, lo que podemos hacer pragm\u00e1ticamente es calcular un \u00abestimado\u00bb de la varianza a partir de la muestra.<\/p>\n<p>El ajuste, de todas maneras, es sencillo:<br \/>\n$$<br \/>\nVar_M[X] = Var(X) \\cdot N \/ (N &#8211; 1)<br \/>\n$$donde <em>N<\/em> es el tama\u00f1o de la muestra. Este es el motivo por el que Excel tiene dos funciones, VAR y VAR.P, para la varianza. La primera es la varianza de una muestra, y la segunda es la varianza \u00abcompleta\u00bb de una poblaci\u00f3n.<\/p>\n<h4>Implementaci\u00f3n<\/h4>\n<p>Escribo esta entrada, adem\u00e1s de para que sirva de referencia a entradas posteriores, porque quiero explicar un peque\u00f1o truco de implementaci\u00f3n que he visto pasar por alto muchas veces.<\/p>\n<p>Vamos a suponer que tenemos una muestra aleatoria en un array. Para calcular la media, hacemos un bucle y vamos sumando las entradas. Si utilizo la primera definici\u00f3n que hemos dado de la varianza, necesitamos hacer dos pasadas sobre el array. La primera, para calcular la media, y la segunda, para calcular la media de los cuadrados de las diferencias respecto a la media. \u00bfNo ser\u00eda mejor hacer una sola pasada? Si tenemos los datos en un array, no es tan acuciante, pero si los datos son grandes, o vienen de un enumerador, nos interesa hacerlo todo en una pasada.<\/p>\n<p>Es en estos casos en los que la segunda f\u00f3rmula equivalente es importante: podemos calcular simult\u00e1neamente, en una sola pasada, la media y la media de los cuadrados, y luego restar al segundo valor el cuadrado del primero. Algo as\u00ed:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">double sumX = 0, sumX2 = 0;\nint total = 0;\nforeach (double v in source)\n{\n    sumX += v;\n    sumX2 += v * v;\n    total++;\n}\ndouble mean = sumX \/ total;\ndouble variance = (sumX2 \/ total - mean * mean);<\/pre>\n<p>Si quisi\u00e9ramos la varianza de una muestra (es decir, si no tuvi\u00e9semos todos los valores de la poblaci\u00f3n) tendr\u00edamos que ajustar la varianza calculada multiplic\u00e1ndola por <code>total<\/code> y dividi\u00e9ndola por <code>total - 1<\/code>.<\/p>\n<p>De todos modos, el problema principal con el c\u00f3digo anterior es otro, mucho m\u00e1s sutil. Las variables <code>sumX<\/code> y <code>sumX2<\/code> pueden llegar a tener valores muy altos. Y al restar los dos valores se puede producir una cancelaci\u00f3n catastr\u00f3fica que nos haga perder la precisi\u00f3n del resultado. Ese problema no lo tiene el algoritmo en dos pasadas.<\/p>\n<p>La soluci\u00f3n, sin embargo, es muy sencilla. Resulta que:<br \/>\n$$<br \/>\nVar[X] = Var[X &#8211; a]<br \/>\n$$Es decir: si le restamos una constante arbitraria a la variable aleatoria, la \u00abdispersi\u00f3n\u00bb o varianza de la misma no var\u00eda. Lo ideal ser\u00eda que la constante en cuesti\u00f3n fuese la media de la muestra, pero para eso necesitar\u00edamos dos pasadas. Lo que haremos es llegar a un compromiso: como no podemos tener la media, nos conformaremos con un valor representativo de la muestra. \u00bfQu\u00e9 tal si elegimos el primero?<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">double sumX = 0, sumX2 = 0, mean = 0, first = 0;\nbool hasFirst = false;\nint total = 0;\nforeach (double v in source)\n{\n    if (!hasFirst)\n    {\n        hasFirst = true;\n        first = v;\n    }\n    else\n    {\n        double v1 = v - first;\n        sumX += v1;\n        sumX2 += v1 * v1;\n    }\n    mean += v; \n    total++;\n}\nmean \/= total;\ndouble variance = (sumX2 - sumX * sumX \/ total) \/ total;<\/pre>\n<p>He puesto un <strong>else<\/strong> dentro del bucle porque la primera suma no aporta nada a los acumuladores. Por esto, tambi\u00e9n he tenido que modificar el c\u00e1lculo de la media al final. Idealmente, el primer elemento de la muestra deber\u00eda estar lo m\u00e1s cercano posible a la media. Si sabemos que la media va a estar alrededor de cero, adem\u00e1s, podemos olvidar esta precauci\u00f3n.<\/p>\n<p>Quiz\u00e1s alguien crea que la instrucci\u00f3n condicional dentro del bucle lo puede ralentizar un poco. No lo he medido para ver si ocurre, pero si eso fuese importante, lo que podr\u00edamos hacer es desarrollar el bucle en dos trozos:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">var enumerator = source.GetEnumerator();\nif (enumerator.MoveNext()\n{\n    double first = enumerator.Current;\n    double sumX = 0, sumX2 = 0, mean = first;\n    int total = 1;\n    while (enumerator.MoveNext())\n    {\n        double v = enumerator.Current - first;\n        sumX += v;\n        sumX2 += v * v;\n        mean += enumerator.Current;\n        total++;\n    }\n    mean \/= total;\n    double variance = (sumX2 - sumX * sumX \/ total) \/ total;\n}<\/pre>\n<p>Me falta un <strong>else<\/strong> en el fragmento anterior, para cuando la secuencia est\u00e1 vac\u00eda, pero me da pereza ponerlo. Tambi\u00e9n habr\u00eda que llamar a <code>Dispose()<\/code>.<\/p>\n<h4>Concurrencia<\/h4>\n<p>Los otros trucos interesantes, que no voy a tratar en esta entrada, tienen que ver con la posibilidad de repartir el c\u00e1lculo entre varios hilos, cuando el tama\u00f1o de la serie lo amerite. No hay grandes complicaciones a la vista, pero hay que tener cuidado al mezclar los valores obtenidos en cada hilo. Si la serie est\u00e1 en un array, es quiz\u00e1s m\u00e1s sencillo, porque se pueden repartir a priori los rangos entre tareas. Lo recomendable, en cualquier caso, es utilizar una de las sobrecargas de <code>Parallel.ForEach<\/code> que permita el uso de variables de estados. Perm\u00edtame que me haga el sueco y pase de p\u00e1gina en este punto.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Todo el mundo sabe lo que es una media (me refiero a la media estad\u00edstica, por supuesto, no a las otras), por lo que no tiene mucho sentido escribir una entrada sobre medias. Conceptualmente, sin embargo, la media es el primer elemento de una serie de valores que caracterizan a las series aleatorias, y que [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":242,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[7],"tags":[15,19,28,30,29],"class_list":["post-239","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-fintech","tag-algorithms","tag-linear-algebra","tag-probabilities","tag-statistics","tag-variance"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/intsight.com\/wp-content\/uploads\/2020\/05\/covariance.png?fit=350%2C350&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/posts\/239","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/comments?post=239"}],"version-history":[{"count":40,"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/posts\/239\/revisions"}],"predecessor-version":[{"id":573,"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/posts\/239\/revisions\/573"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/media\/242"}],"wp:attachment":[{"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/media?parent=239"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/categories?post=239"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/intsight.com\/index.php\/wp-json\/wp\/v2\/tags?post=239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}