Esta notebook fue creada originalmente como un blog post por Raúl E. López Briega en Matemáticas, análisis de datos y python. El contenido esta bajo la licencia BSD.
"La información es la resolución de la incertidumbre"
"Lo que está en el corazón de cada ser vivo no es un fuego, ni un aliento cálido, ni una chispa de vida. Es información, palabras, instrucciones ... Si quieres entender la vida... piensa en la tecnología de la información"
Muchas veces hemos escuchado decir que vivimos en la era de la información. La información parece estar en todo los que nos rodea. Ya sea que consideremos a las computadoras, la evolución, la física, la inteligencia artificial, o nuestro cerebro; podemos llegar a la conclusión de que su comportamiento esta principalmente determinado por la forma en que procesan la información.
La idea de la información nació del antiguo arte de la codificación y decodificación de códigos. Los encargados de esconder los secretos de estado durante la segunda guerra mundial utilizaban, en esencia, métodos para ocultar información y transmitirla de un lugar a otro. Cuando el arte de quebrar estos códigos se combinó con la ciencia de la Termodinámica, la rama de la física encargada del estudio de la interacción entre el calor y otras manifestaciones de la energía; surgió lo que hoy conocemos como Teoría de la información. Esta teoría fue una idea revolucionaria que inmediatamente transformó el campo de las comunicaciones y preparó el camino para la era de las computadoras. Pero las ideas de la Teoría de la información no solo gobiernan las comunicaciones y los bits y bytes de las computadoras modernas; sino que también describen el comportamiento del mundo subatómico, e incluso de toda la vida en la Tierra.
Hasta no hace no tanto tiempo atrás, nuestro conocimiento de la información era bastante vago y limitado. En 1948, Claude Shannon publicó un artículo titulado "Una teoría matemática de la comunicación", el cual transformó para siempre la forma en que entendemos la información. La Teoría de la información de Shannon proporciona una definición matemática de información y describe con precisión cuánta información se puede comunicar entre los diferentes elementos de un sistema. La teoría de Shannon respalda nuestra comprensión de cómo se relacionan las señales y el ruido, y por qué existen límites definidos para la velocidad a la que se puede comunicar la información dentro de cualquier sistema, ya sea creado por el hombre o biológico. La habilidad de separar la señal del ruido, para extraer la información en los datos, se ha vuelto crucial en las telecomunicaciones modernas.
La Teoría de la información es tan poderosa porque la información es física. La información no es solo un concepto abstracto, y no solo son hechos o figuras, fechas o nombres. Es una propiedad concreta de la materia y la energía que es cuantificable y mensurable. Es tan real como el peso de un trozo de plomo o la energía almacenada en una ojiva atómica, y al igual que la masa y la energía, la información está sujeta a un conjunto de leyes físicas que dictan cómo puede comportarse, cómo la información puede ser manipulada, transferida, duplicada, borrada o destruida. Y todo en el universo debe obedecer las leyes de la información, porque todo en el universo está formado por la información que contiene.
Según la perspectiva de la información de Shannon, el significado no es importante, sino que lo que importa es cuánta información es transmitida por un mensaje. Una de las grandes intuiciones que tuvo Shannon fue darse cuenta que cualquier pregunta que tenga una respuesta finita puede ser respondida por una cadena de preguntas por sí o por no. Así es como surge el concepto de Bit.
Un Bit es la unidad fundamental en la que podemos medir la información y nos permite decidir entre dos alternativas igualmente probables. La palabra Bit deriva de binary digit, o sea dígito binario, los cuales son representados por 1s y 0s. Pero si bien la palabra Bit deriva de binary digit no debemos confundirlos, ya que representan entidades distintas. Un Bit representa una cantidad de información definitiva. En cambio, un dígito binario es el valor de una variable binaria, el cual, como ya dijimos, puede ser 0 o 1; pero un dígito binario no representa información en sí misma.
Ahora bien, volviendo a las preguntas por sí o por no que mencionamos antes; responder cada una de estas preguntas requiere un Bit de información. Sólo necesitamos un Bit para responder una pregunta como ¿sos un hombre o una mujer?; el 0 puede significar hombre y el 1 mujer. Con simplemente transmitir ese dígito en el mensaje, estamos transmitiendo la respuesta. Pero aquí viene otra de las grandes intuiciones de Shannon; tampoco importa la forma que tome el mensaje, puede ser una luz roja versus una luz verde; o una bandera blanca y otra roja; realmente no importa el medio que se utilice, el mensaje siempre contiene un Bit de información.
Y ¿qué pasa con otro tipo de preguntas? preguntas como adivinar un número entero entre 1 y 1000, o como, ¿cuál es la capital de Islandia? Estas preguntas también pueden ser respondidas con una cadena de Bits. El lenguaje no es más que una cadena de símbolos y cualquier símbolo puede ser representado con una cadena de Bits. Por lo tanto, cualquier respuesta que pueda ser escrita en un lenguaje puede ser representada con una cadena de Bits, de 1s y 0s. Los Bits son el medio fundamental de la información.
Esta realización, que cualquier información, cualquier respuesta, puede ser codificada en una cadena de Bits, nos abre la puerta para pensar que entonces debe existir una forma de medir cuánta información hay en un mensaje.¿Cuál es la mínima cantidad de Bits para codificar un mensaje? Por ejemplo, para responder la pregunta planteada anteriormente de adivinar un número entero entre 1 y 1000, no se necesitan más que 10 Bits!. Shannon encontró que una pregunta con $N$ posibles resultados puede ser respondida con una cadena de Bits de $log_2 N$ Bits; es decir que solo necesitamos $log_2 N$ Bits de información para distinguir entre $N$ posibilidades. Si no me creen, más abajo les dejo un botón para jugar a adivinar el número. (Si les consume más de 10 bits llegar a la respuesta correcta, no están utilizando la estrategia correcta!).
Todo esto último relacionado a cómo medir cuánta información contiene un mensaje nos lleva a otro de los conceptos fundamentales de la Teoría de la información, el concepto de Entropía.
La idea central de la Teoría de la información de Shannon es la Entropía. La información y la Entropía están intimimamente relacionadas, ya que esta última es en sí misma una medida de información. Cuando Shannon comenzó a desarrollar su teoría, encontró una formula que le permitía analizar la información en un mensaje en términos de Bits. Esta formula que encontró mide, a grandes rasgos, cuan poco predecible es una cadena de Bits. Mientras menos predecible, existen menos probabilidades de poder generar el mensaje completo desde una cadena más pequeña de Bits. Es decir, que al intentar medir cuan poco predecible es una cadena de Bits, Shannon esperaba poder encontrar cuánta información contenía el mensaje. Ahora bien, ¿cuál es la cadena de 0s y 1s menos probables? Pues aquella que sea completamente aleatoria, como cuando lanzamos una moneda al aire y tenemos 50% de probabilidades de obtener cara o seca. Mientras más aleatoria es una cadena de símbolos, es menos predecible y menos redundante; y por lo tiende a contener una mayor cantidad de información por símbolo. Si bien esto parece una paradoja, ¿cómo algo que es completamente aleatorio contiene más información que algo que no lo es? Acoso, ¿lo aleatorio no es no lo contrario de información? Parece ser contra intuitivo, pero en realidad no lo es. Se puede observar facílmente con un ejemplo. Supongamos que arrojamos una moneda al aire 16 veces y representamos a la cara con un 1 y a la seca con un 0. Podemos obtener una cadena como la siguiente: 1101001110001011. Esta cadena es aleatoria y por lo tanto no podemos encontrar ningún patrón en ella que nos diga cuál va a ser el próximo valor que podemos obtener más alla de la chance de 50% habitual, por tal motivo, no podemos comprimir la cadena y cada símbolo contiene un Bit de información. Ahora supongamos que la moneda esta sesgada y que siempre sale cara; en este caso nuestra cadena será la siguiente: 1111111111111111. Esta cadena es sumamente predecible, no nos aporta ninguna sorpresa y tenemos una probabilidad de 100% de adivinar que el siguiente dígito también será un 1. Es totalmente redundante y por lo tanto no nos aporta ninguna información. Cada símbolo contiene un Bit de información. Sin sorpresa, no hay información.
La fórmula matemática que encontró Shannon para medir la Entropía de un mensaje es muy similar a la que se utiliza en Termodinámica para medir el grado de desorden de un sistema. Es la siguiente:
$$ H(x) = - \sum_{i} p(i) log_2 p(i) $$Cuando Shannon se dio cuenta de que la Entropía de una secuencia de símbolos estaba relacionada con la cantidad de información que la cadena de símbolos tiende a contener, de repente tuvo una herramienta para cuantificar la información y la redundancia en un mensaje. Fue capaz de demostrar, matemáticamente, cuánta información puede transmitirse en cualquier medio y que existe un límite fundamental para la cantidad de información que puede transmitir con un equipo determinado.
Veamos algunos ejemplos de como calcular la Entropía con la ayuda de Python:
In [1]:
# <!-- collapse=True -->
import matplotlib.pyplot as plt
import numpy as np
import warnings
# ingnorar mensajes de advertencias en el notebook
warnings.filterwarnings('ignore')
# graficos en el notebook
%matplotlib inline
def entropia(X):
"""Devuelve el valor de entropia de una muestra de datos"""
probs = [np.mean(X == valor) for valor in set(X)]
return round(np.sum(-p * np.log2(p) for p in probs), 3)
def entropia_prob_pq(x):
"""Devuelve la entropia de una probabilidad de dos posibilidades"""
return round((-x * np.log2(x)) + (-(1 - x ) * np.log2((1 - x))), 3)
def entropia_posibilidades(x):
"""Devuelve la entropía para la cantidad de posibilidades independientes x"""
return round(np.log2(x), 3)
In [2]:
# Graficando la información como sorpresa
# Mientras menos probable, más sorpresa y más información contiene.
vent = np.vectorize(entropia_posibilidades)
X = np.linspace(0, 1, 11)
plt.plot(X, vent(X)*-1)
plt.title("Información como sorpresa")
plt.grid(color='b', linestyle='-', linewidth=.3)
plt.xlabel(r'Probabilidades $p(x)$')
plt.ylabel(r'sorpresa $H(x) = log_2 1/p(x)$')
plt.show()
In [3]:
# Graficando la entropia en el caso de 2 posibilidades con
# probabilidad p y (1- p)
# vectorizar la función para poder pasarle un vector de parámetro
vent = np.vectorize(entropia_prob_pq)
X = np.linspace(0, 1, 11)
plt.plot(X, vent(X))
plt.title("Entropia para 2 posibilidades con probabilidad p")
plt.grid(color='b', linestyle='-', linewidth=.3)
plt.xlabel('Probabilidades p')
plt.ylabel('Bits')
plt.show()
In [4]:
# La entropia de una muestra de 2 posibilidades completamente
# aleatorias, en la que cualquiera de los 2 valores tiene la
# misma probabilidad (p=0.5) de ser seleccionada es de 1 bit
# Muestra de 10000 valores aleatorios entre 0 y 1
X = np.random.randint(0, 2, size=10000)
entropia(X), entropia_posibilidades(2)
Out[4]:
In [5]:
# La entropia de una muestra de 8 posibilidades completamente
# aleatorias es igual a 3 bits.
# Muestra de 10000 valores aleatorios entre 0 y 7
X = np.random.randint(0, 8, size=10000)
entropia(X), entropia_posibilidades(8)
Out[5]:
Otro de los conceptos fundamentales de la Teoría de la información es el de Redundancia. La Redundancia son esas pistas adicionales en una sentencia o mensaje que nos permiten entender su significado incluso si el mensaje esta incompleto o distorsionado; son esos caracteres extra en una cadena de símbolos, la parte predecible que nos permite completar la información faltante. Cualquier sentencia de cualquier lenguaje es altamente redundante. Todo sentencia nos proporciona información adicional para que podemos descifrarla. Esta Redundancia es fácil de ver, simplemente tr-t- d- l--r -st- m-ns-j-. A pesar de que quitemos todas la vocales, igualmente se podemos entender la sentencia.
Para nosotros, la redundancia del lenguaje es algo bueno, porque hace que un mensaje sea más fácil de comprender incluso cuando el mensaje está parcialmente modificado por el entorno. Podemos entender a un amigo hablando en un restaurante abarrotado de gente o hablando con un teléfono celular con mucha estática gracias a la Redundancia . La Redundancia es un mecanismo de seguridad; nos asegura que el mensaje se transmita incluso si se daña levemente en el camino. Todos los idiomas tienen estas redes de seguridad integradas compuestas de patrones, estructuras y un conjunto de reglas que los hacen redundantes. Usualmente no estamos al tanto de esas reglas, pero nuestro cerebro las usa inconscientemente mientras leemos, hablamos, escuchamos y escribimos.
Cuando eliminamos toda la redundancia en una cadena de símbolos, lo que queda es su núcleo concreto y cuantificable. Eso es la información, ese algo central e irreductible que se encuentra en la esencia de toda sentencia.
Para explorar en carne propia como la información es una medida de sorpresa y como la mayoría de los mensajes contienen bastantes Bits redundantes, les dejo otro juego; la idea es adivinar nombres que empiezan con "R" de Raúl a medida que se van descubriendo nuevas letras. Les garantizo que podrán descubrir los nombres sin tener que llegar que se descubra la última letra!
Nuestra experiencia del mundo nos lleva a concluir que muchos eventos son impredecibles y algunas veces bastante inesperados. Estos pueden variar desde el resultado de simples juegos de azar como arrojar una moneda e intentar adivinar si será cara o cruz, al colapso repentino de los gobiernos, o la caída dramática de los precios de las acciones en el mercado bursátil. Cuando tratamos de interpretar tales eventos, es probable que tomemos uno de dos enfoques: nos encogeremos de hombros y diremos que fue por casualidad o argumentaremos que podríamos haber sido más capaces de predecir, por ejemplo, el colapso del gobierno si hubiéramos tenido más información sobre las acciones de ciertos ministros. En cierto sentido, podemos decir que estos dos conceptos de información e incertidumbre están más estrechamente relacionados de lo que podríamos pensar. De hecho, cuando nos enfrentamos a la incertidumbre, nuestra tendencia natural es buscar información que nos ayude a reducir esa incertidumbre en nuestras mentes. Las herramientas que nos proporciona la Teoría de la información están en las bases de todos los modelos que desarrollamos para intentar predecir y lidiar con la incertidumbre del futuro.
Aquí concluye esta introducción, el trabajo de Shannon habrió un campo enorme del conocimiento científico. Por años, criptógrafos habían intentado esconder información y reducir la redundancia sin siquiera saber como medirlas; o los ingenieros trataron de diseñar maneras eficientes de transmitir mensajes sin conocer los límites que la Naturaleza ponía a su eficiencia. La Teoría de la información de Shannon revolucionó la criptografía, el procesamiento de señales, las ciencias de la computación, la física, y un gran número de otros campos.
Para cerrar, les dejo la implementación de los juegos utilizados en el artículo utilizando Python! :)
Saludos!
In [6]:
# <!-- collapse=True -->
import random
random.seed(1982)
def adivinar_numero():
mi_numero = random.randint(1, 1000)
bits = 1
tu_numero = int(input("Adivine un número entero entre 1 y 1000\nIngrese un número entre 1 y 1000: "))
while tu_numero != mi_numero:
if tu_numero < mi_numero:
tu_numero = int(input("Su número es muy bajo!\nIngrese otro número entre 1 y 1000:"))
else:
tu_numero = int(input("Su número es muy alto!\nIngrese otro número entre 1 y 1000:"))
bits += 1
print("Felicidades el número es {0} y ha utilizado {1} bits!".format(mi_numero, bits))
In [7]:
# <!-- collapse=True -->
def adivinar_nombre():
nombres = [
"ramses", "rodolfo", "regina", "ruth", "ramiro",
"ramon", "roxana", "rebeca", "raquel", "ruben",
"rosario", "renata", "raul", "romina", "roberto",
"ricardo", "rafael", "rosa", "rodrigo", "rocio"
]
index = random.randint(0, 19)
mi_nombre = nombres[index]
tu_nombre = input("Adivina el nombre! Empieza con R y tiene {} letras: ".format(len(mi_nombre)))
letras = 2
bits = 1
while tu_nombre.lower() != mi_nombre:
mi_nombre_parcial = mi_nombre[:letras]
if mi_nombre_parcial == mi_nombre:
break
tu_nombre = input("Inténtalo otra vez! Empieza con {0} y tiene {1} letras:".format(mi_nombre_parcial,
letras))
bits += 1
letras += 1
print("El nombre es {0} y has utilizado {1} bits! Los restantes {2} son redundantes!".format(mi_nombre.upper(),
bits,
len(mi_nombre) - bits))
In [ ]:
adivinar_numero()
In [ ]:
adivinar_nombre()
Este post fue escrito utilizando Jupyter notebook. Pueden descargar este notebook o ver su version estática en nbviewer.