La compresión dinámica de Markov ( DMC ) es un algoritmo de compresión de datos sin pérdidas desarrollado por Gordon Cormack y Nigel Horspool . [ 1 ] Utiliza codificación aritmética predictiva similar a la predicción por coincidencia parcial (PPM), excepto que la entrada se predice bit a bit (en lugar de byte a byte). DMC tiene una buena relación de compresión y una velocidad moderada, similar a PPM, pero requiere algo más de memoria y no está ampliamente implementada. Algunas implementaciones recientes incluyen los programas de compresión experimentales hook de Nania Francesco Antonio, ocamyd de Frank Schwellinger y como submodelo en paq8l de Matt Mahoney. Estos se basan en la implementación de 1993 en C de Gordon Cormack.
Algoritmo
DMC predice y codifica un bit a la vez. Se diferencia de PPM en que codifica bits en lugar de bytes, y de algoritmos de mezcla de contexto como PAQ en que solo hay un contexto por predicción. El bit predicho se codifica luego mediante codificación aritmética .
Codificación aritmética
Un codificador aritmético bit a bit como DMC tiene dos componentes: un predictor y un codificador aritmético. El predictor acepta una cadena de entrada de n bits x = x 1 x 2 ... x n y le asigna una probabilidad p ( x ), expresada como el producto de una serie de predicciones, p ( x 1 ) p ( x 2 | x 1 ) p ( x 3 | x 1 x 2 ) ... p ( x n | x 1 x 2 ... x n – 1 ). El codificador aritmético mantiene dos números binarios de alta precisión, p low y p high , que representan el rango posible para la probabilidad total que el modelo asignaría a todas las cadenas lexicográficamente menores que x , dados los bits de x vistos hasta el momento. El código comprimido para x es p x , la cadena de bits más corta que representa un número entre p low y p high . Siempre es posible encontrar un número en este rango que no sea más de un bit más largo que el límite de Shannon , log 2 1 / p ( x ). Uno de esos números se puede obtener a partir de p alto descartando todos los bits finales después del primer bit que difiere de p bajo .
La compresión procede de la siguiente manera. El rango inicial se establece en p bajo = 0, p alto = 1. Para cada bit, el predictor estima p 0 = p ( x i = 0 | x 1 x 2 ... x i – 1 ) y p 1 = 1 − p 0 , la probabilidad de un 0 o un 1, respectivamente. El codificador aritmético divide entonces el rango actual, ( p bajo , p alto ) en dos partes en proporción a p 0 y p 1 . Entonces el subrango correspondiente al siguiente bit x i se convierte en el nuevo rango.
Para la descompresión, el predictor realiza una serie idéntica de predicciones, dados los bits descomprimidos hasta el momento. El codificador aritmético realiza una serie idéntica de divisiones de rango, luego selecciona el rango que contiene p x y genera el bit x i correspondiente a ese subrango.
En la práctica, no es necesario mantener p bajo y p alto en memoria con alta precisión. A medida que el rango se reduce, los bits iniciales de ambos números serán iguales y podrán mostrarse inmediatamente.
Modelo DMC
El predictor DMC es una tabla que asigna contextos (a nivel de bits) a un par de recuentos, n₀ y n₁ , que representan la cantidad de ceros y unos observados previamente en ese contexto. Así , predice que el siguiente bit será un 0 con probabilidad p₀ = n₀ / n = n₀ / ( n₀ + n₁ ) y un 1 con probabilidad p₁ = 1 − p₀ = n₁ / n . Además, cada entrada de la tabla tiene un par de punteros a los contextos obtenidos al agregar un 0 o un 1 a la derecha del contexto actual (y posiblemente descartar bits a la izquierda). Por lo tanto, nunca es necesario consultar el contexto actual en la tabla; basta con mantener un puntero al contexto actual y seguir los enlaces.
En la implementación original de DMC, la tabla inicial es el conjunto de todos los contextos de longitud entre 8 y 15 bits que comienzan en un límite de byte. El estado inicial es cualquiera de los contextos de 8 bits. Los contadores son números de punto flotante inicializados con una pequeña constante distinta de cero, como 0,2. Los contadores no se inicializan a cero para permitir que se codifiquen valores incluso si no se han visto antes en el contexto actual.
El modelado es el mismo para la compresión y la descompresión. Para cada bit, se calculan p 0 y p 1 , el bit x i se codifica o decodifica, el modelo se actualiza sumando 1 al contador correspondiente a x i , y el siguiente contexto se encuentra recorriendo el enlace correspondiente a x i .
Agregar nuevos contextos
DMC, como se describió anteriormente, es equivalente a un modelo de contexto de orden 1. Sin embargo, es común agregar contextos más largos para mejorar la compresión. Si el contexto actual es A, y el siguiente contexto B descarta bits a la izquierda, entonces DMC puede agregar (clonar) un nuevo contexto C a partir de B. C representa el mismo contexto que A después de agregar un bit a la derecha como con B, pero sin descartar ningún bit a la izquierda. El enlace de A se moverá de B para apuntar a C. Tanto B como C harán la misma predicción, y ambos apuntarán al mismo par de estados siguientes. El recuento total, n = n 0 + n 1 para C será igual al recuento n x para A (para el bit de entrada x ), y ese recuento se restará de B.
Por ejemplo, supongamos que el estado A representa el contexto 11111. Al ingresar el bit 0, se produce una transición al estado B, que representa el contexto 110, obtenido al descartar 3 bits a la izquierda. En el contexto A, había 4 bits cero y algunos bits uno. En el contexto B, había 3 ceros y 7 unos ( n = 10), lo que predice p 1 = 0,7.
C se clona a partir de B. Representa el contexto 111110. Tanto B como C predicen p 1 = 0,7, y ambos van a los mismos estados siguientes, E y F. El recuento para C es n = 4, igual a n 0 para A. Esto deja n = 6 para B.
Los estados se clonan justo antes de la transición. En el DMC original, la condición para clonar un estado es que la transición de A a B sea al menos 2, y el conteo para B sea al menos 2 más que eso. (Cuando el segundo umbral es mayor que 0, garantiza que otros estados seguirán transicionando a B después de la clonación). Algunas implementaciones, como hook, permiten establecer estos umbrales como parámetros. En paq8l, estos umbrales aumentan a medida que se usa la memoria para ralentizar la tasa de crecimiento de nuevos estados. En la mayoría de las implementaciones, cuando se agota la memoria, el modelo se descarta y se reinicializa al modelo original de orden 1 bytewise.
Referencias
- ↑ Gordon Cormack y Nigel Horspool, "Compresión de datos mediante modelado dinámico de Markov", Computer Journal 30:6 (diciembre de 1987)
Enlaces externos
- Compresión de datos mediante modelado dinámico de Markov
- Canal de YouTube de Google Developers: Compressor Head, episodio 3 (Compresión de cadena de Markov) (
La página reproducirá el audio al cargarse).
- Algoritmos de compresión sin pérdidas
- modelos de Markov
- Compresión de datos