Chapitre 2
Chapitre 2
Chapitre 2
I.1. Introduction
Une source d’information est un dispositif qui délivre aléatoirement des symboles (ou lettres), à partir
d’un ensemble (alphabet). Les symboles sont choisis selon des probabilités qui sont parfois liées aux
symboles délivrés précédemment. Dans ce chapitre, nous nous intéressons au codage de la sortie d’une
source. Nous considérons les sources stationnaires, discrètes et sans mémoire. L’objectif du codage
source est de représenter la donnée originale par un nombre minimal de symboles ou lettres. C’est
donc : La compression de données.
Redondance :
Soit une source 𝑆 délivrant 𝑚 symboles selon des probabilités différentes. On définit la redondance
𝑟 de cette source par :
𝐻 (𝑆 )
𝑟 = 𝐻𝑚𝑎𝑥 − 𝐻(𝑆) , soit : 𝑟 = 1 − 𝐻
𝑚𝑎𝑥
Exemple 1:
On considère l’alphabet de la langue Anglaise (26 lettres + l’espace). Les fréquences de choix
exprimant les probabilités des lettres sont variées. L’entropie de cette source a été estimée en utilisant
un livre de Dumas Malone à 1.34 bits. Ainsi la redondance de cette langue est donnée par :
1.34
𝑟 =1− ≅ 0.72 ≅ 72%
𝑙𝑜𝑔2 (27)
Ce résultat veut dire que lorsqu’un texte est écrit en anglais, on a 28% des lettres qui sont librement
choisies, tandis que 72% des lettres sont choisies selon les règles et la structure de la langue.
Taux d’entropie :
La quantité d’information délivrée par une source en fonction du temps, dépend du taux de symboles
« Symbol rate ». Elle est exprimée par le taux d’entropie 𝐻 ′ (𝑆) donné par :
𝐻 ′ (𝑆) = 𝐻 (𝑆) × 𝐷𝑆
Le taux d’entropie est vu comme la quantité moyenne d’information émise par la source en une
seconde. Cette information est utile lors de la transmission des données dans un canal de
communication.
Un code est un ensemble de mots appelés « mots de code » ou « code words ». Ils correspondent à la
juxtaposition des symboles extraits de l’alphabet d’une source. Le nombre de symboles qui composent
un mot de code est appelé « longueur du mot ». Le code le plus utilisé en pratique est le codage
binaire.
Exemple 2 :
En technologie de communication ainsi qu’en analyse de données, on utilise souvent, le code ASCII
(American Standard Code for Information Interchange) développé en 1963. Ac tuellement, ce code
contient 28 =256 codes binaires avec une longueur fixée à 8 bits.
Exemple 3 :
Un autre code qu’on utilise est le « code Morse » qui permet de transmettre l’alphabet {𝑎, 𝑏, ⋯ , 𝑧, ⋯ }
par des signaux électriques :
Dans ce code, chaque lettre (ou symbole) est représentée par une séquence de points et de tirets :
Pour comprendre l’objectif et les problèmes liés au codage source, considérons l’exemple suivant :
Soit une source discrète sans mémoire délivrant des lettres dans :{𝐴, 𝐵, 𝐶, 𝐷} avec les probabilités
1 1 1 1
suivantes : , , , . On veut stocker 1000 symboles sous forme d’un fichier binaire. On doit donc
2 4 8 8
coder les symboles par des digits binaires. On veut optimiser la taille des codes pour réduire la taille
du fichier.
Première solution :
Puisque on doit coder 4 symboles, soit 2 2 symboles, on utilise 2 bits selon le principe de Shannon. On
considère le codage binaire suivant : A→00, B→01, C→10, D→11.
Tous les mots de code ont le même nombre de bits. Ce code est dit « Codage à longueur fixe » ou
« fixed length code ».
Deuxième solution :
Puisque les symboles n’ont pas les mêmes probabilités, on peut réfléchir à poser un code qui affecte
aux symboles les plus probables des mots de code de taille petite pour réduire encore la taille du
fichier. On peut utiliser par exemple, le codage suivant : A→1, B→01, C→000, D→001.
Ici, la longueur des mots de code est variable. On dit que le code est à « longueur variable ».
Pour calculer la taille du fichier, on utilise la fréquence d’apparition de chaque symbole dans les 1000
observations.
A : 1000×1/2=500 symboles
B : 1000×1/4=250 symboles
Remarques :
2000−1750
Comparativement au codage binaire, le taux de compression est : = 12.5%.
2000
1750
En moyenne, nous avons besoin de 1000 soit 1.75 bits pour coder un symbole.
Si le taux de symboles est de 1000 symboles par seconde, le bit rate est de 1750 bits par seconde.
Conclusion :
Pour répondre à toutes ces questions, le code qu’on va proposer doit respecter un certain nombre de
propriétés. Avant d’aborder les algorithmes de codage, nous allons établir les propriétés d’un code
efficace.
Pour établir un codage source efficace, le code doit vérifier plusieurs propriétés pour être : non-
ambigu, à déchiffrage (ou déchiffrement) unique, et sans préfixe. Pour comprendre ces propriétés,
nous allons les exposer à travers des exemples.
Code ambigu :
Pour une source ayant un alphabet {𝐴, 𝐵, 𝐶, 𝐷}, on se propose le code suivant : A→1, B→10, C→00,
D→01. Supposons la séquence 10001 qu’on souhaite décoder. Dans ce cas, il y a deux interprétations
possibles : 10001→ACD ou 10001→BCA. Ce code est dit « ambigu ».
Définition :
On dit qu’un code est « non-ambigu » si et seulement si chaque séquence du code ne correspond qu’à
un seul message de la source. On dit qu’un code est à déchiffrement unique « non ambigu » si et
seulement si chaque séquence de mots de code possède un décodage unique.
Code instantané :
On considère une source à deux symboles A et B. On propose les deux codes suivants :
Lors d’une transmission, le récepteur peut décoder d’une façon instantanée, les mots reçus si on utilise
le premier code. En effet, si on reçoit 0 on sait que c’est un A et nous n’avons pas besoin d’attendre le
deuxième bit. En revanche, si on utilise le deuxième code, et on reçoit un 1, on doit attendre le bit
suivant pour décider s’il s’agit d’un A ou d’un B. On dit que le premier code est instantané.
Définition :
Un code instantané est un code dans lequel chaque mot de code peut être interprété (décodé) mot par
mot sans attendre les mots suivants.
On considère une source définie sur l’alphabet: {𝐴, 𝐵, 𝐶, 𝐷, 𝐸, 𝐹, 𝐺 }. On propose le code suivant :
{𝐴 → 01, 𝐵 → 11, 𝐶 → 000, 𝐷 → 101,𝐸 → 111,𝐹 → 1100,𝐺 → 1101}.
Si on reçoit le mot de code 1101, le décodage peut donner deux solutions : G ou BA. Le code est
ambigu car le mot de code du symbole B (11) est le préfixe du mot de code du symbole G (1101).
Pour éviter cette confusion, chaque mot de code ne doit pas être le préfixe d’un autre mot de code.
Définition :
On dit qu’un code est un code « sans préfixe » si et seulement si aucun mot de code n’est le préfixe
d’un autre mot de code.
Remarques :
Il existe un code n’aire sans préfixe de 𝑚 mots de code {𝐶1,𝐶2 ,⋯ , 𝐶𝑚 } avec des longueurs
{𝑙 1 ,𝑙 1,⋯ , 𝑙 𝑚 } pour coder un alphabet, si et seulement si l’inégalité de Kraft est vérifiée :
∑ 𝑛 −𝑙 𝑘 ≤ 1
𝑘=1
Exemple 4:
Ce code n’est pas un code préfixe car le 11 est le préfixe des mots 111, 1100, et 1101.
Néanmoins, l’inégalité de Kraft est vérifiée car : 2−2 + 2−2 + 2−3 + 2−3 + 2−3 + 2−4 + 2−4 = 1.
Nous concluons que parmi les codes qui vérifient l’inégalité de Kraft on peut trouver un code préfixe
(sans préfixe), mais ce n’est pas le code proposé par notre exemple. Ainsi, il exis te un code préfixe
ayant deux mots de code de longueur 2, trois mots de code de longueur 3 et deux mots de code de
longueur 4. Pour trouver un tel code, on doit passer par la représentation graphique utilisant les arbres
de codage.
Pour construire un code sans préfixe n’aire, le moyen le plus efficace est la représentation graphique
par un arbre n’aire. Rappelons que 𝑛 est le nombre de bits (ou digits) qui constituent l’alphabet du
code. Pour un code binaire composé de 0 et 1, 𝑛 = 2. Aussi, un codage ternaire (𝑛 = 3) correspond
par exemple à un alphabet de 0, 1 et -1.
Un arbre est un graphe qui possède des nœuds et des arcs. Il commence par un nœud de racine.
Chaque nœud est soit une feuille (point de terminaison), soit un nœud intérieur à partir duquel d’autres
nœuds fils peuvent dériver.
La profondeur d’un nœud correspond au nombre d’arcs à parcourir pour aller de la racine à ce
nœud.
Un arbre n’aire est un arbre dans lequel chaque nœud à une arité (nombre de nœuds fils) égale à
n.
Un arbre n’aire complet est un arbre dans lequel toutes les feuilles ont la même profondeur.
Un mot de code est représenté par une séquence de branches (arcs) allant de la racine. Sa
longueur est égale à la profondeur de sa feuille.
Le codage de Shannon définit la longueur du mot de code d’un symbole par : 𝑙 𝑖 = ⌈−𝑙𝑜𝑔𝑛 (𝑝𝑖 )⌉
Exemple 5:
On veut construire un arbre de codage pour trouver un code préfixe pour la source utilisée dans
l’exemple 4. L’alphabet est {𝐴, 𝐵, 𝐶, 𝐷, 𝐸, 𝐹, 𝐺 } . Selon l’inégalité de Kraft, il existe un code préfixe
ayant deux mots de codes de longueur 2, deux autres de longueur 4 et 3 mots de code de longueur 3.
On peut trouver ce code à l’aide de l’arbre de codage.
Racine
Code :
0 1
A : 01
B: 10
C: 000
D: 001
0 1 0 1
E:110
F:1110
A B G: 1111
0 1 0 1
C D E
0 1
F G
Le théorème du codage source établit les limites et les conditions qui permettent de développer un
code sans préfixe et à déchiffrement unique. Soit S une source débitant des symboles pris d’un
alphabet de taille 𝑚 et soit 𝑛 la taille de l’alphabet du code. Le théorème du codage source est tel que :
a) Chaque code à déchiffrement unique utilisé pour coder des séquences d’une source discrète,
𝐻 (𝑆 )
stationnaire et sans mémoire, satisfait : 𝐸[𝑙] = 𝐿̅ ≥
𝑙𝑜𝑔 (𝑛 )
b) On peut coder une source discrète, stationnaire et sans mémoire par un code instantané n’aire
𝐻 (𝑆 )
dont la longueur moyenne du code vérifie : 𝐸[𝑙] = 𝐿̅ < +1
𝑙𝑜𝑔 (𝑛 )
Remarques :
L’entropie est la borne inférieure pour les longueurs moyennes de tous les codes instantanés que
l’on peut proposer.
Un code efficace ou optimal doit avoir une longueur moyenne telle que : 𝐿̅ = 𝐻 (𝑆)
𝐻 (𝑆 )
Lorsque 𝐿̅ = , soit 𝐿̅ = 𝐻(𝑆), on dit que le code est optimal ou efficace.
𝑙𝑜𝑔 (𝑛 )
Exemple 6 :
Soit une source S définie par l’alphabet {𝐴, 𝐵, 𝐶, 𝐷, 𝐸, 𝐹, 𝐺 } avec les probabilités : 1/3 pour A et 1/9
pour les autres symboles. On veut coder la sortie de S par un code ternaire ayant l’alphabet suivant :
{0, 1,2}. Le codage de Shannon estime la longueur du mot de code par : 𝑙 𝑖 = ⌈−𝑙𝑜𝑔3 (𝑝𝑖 )⌉ (⌈ ⌉
correspond à l’entier supérieur ou égal à la valeur). Ainsi, pour le symbole A, nous avons : 𝑙𝐴 =
1 1
−𝑙𝑜𝑔3 (3) = 𝑙𝑜𝑔3 (3) = 1𝑏𝑖𝑡. Pour les autres symboles, nous avons : 𝑙 𝑖 = −𝑙𝑜𝑔3 (9 ) = 𝑙𝑜𝑔3 (9) =
2 𝑏𝑖𝑡𝑠.
Avant de poser l’arbre de codage, on doit vérifier si un tel code respecte l’inégalité de Kraft.
Nous avons :(3−1 ) + (6 × 3−2 ) = 1. Alors, on peut trouver un code préfixe à déchiffrement unique
utilisant les longueurs calculées selon le principe de Shannon. La longueur moyenne de ce code est
5 1 1
telle que : 𝐿̅ = 𝑡𝑟𝑖𝑡𝑠/𝑠𝑦𝑚𝑏𝑜𝑙𝑒. L’entropie de la source est : 𝐻(𝑆) = − 𝑙𝑜𝑔3 ( ) − 6 ×
3 3 3
1 1 5
𝑙𝑜𝑔3 ( ) = 𝑡𝑟𝑖𝑡𝑠 .
9 9 3
Code :
0 1 2
A:1
B: 00
C: 01
A D: 02
0 1 2 0 1 2
E: 20
F : 21
G: 22
B C D E F G
Prof. Y. Chibani et Prof. H. Nemmour Page 22
USTHB/FEI/ Licence Télécommunications/ Codage et Théorie de l’information / 2019-2020
En résumé :
Pour une source d’information S, la compression de données est possible si : 𝐻(𝑆) < 𝑙𝑜𝑔𝑛 (𝐿̅ ). Le
nombre moyen minimal des symboles codes requis pour représenter un symbole est égal à l’entropie
𝐻(𝑆).
Dans cette section, nous présentons les algorithmes de codage binaire permettant la compression de
données.
Ce code constitue la méthode basique du codage binaire. Il est basé sur l’utilisation de l’information
propre pour définir la taille du mot de code de chaque symbole de l’alphabet. Pour une source S
définie sur un alphabet {𝑎1 ,𝑎2 ,⋯ } , choisi selon les probabilités { 𝑝𝑎1 , 𝑝𝑎2 ,⋯ }, la taille des mots de
code est définie par : ⌈−𝑙𝑜𝑔 ( 𝑝𝑎𝑖 )⌉ (l’entier supérieur ou égal à l’information propre). Ainsi, les codes
sont obtenus à l’aide d’un arbre de codage.
Le codage binaire de Shannon est optimal si l’entropie de la source H(S) est égale à Hmax
(Symboles équiprobables)
Cet algorithme est basé sur le principe que chaque bit de code décrit par une variable aléatoire doit
avoir une entropie maximale.il est composé des étapes suivantes :
2. Diviser l’ensemble des symboles en deux sous-ensembles contenant chacun des symboles
consécutifs de façon que les probabilités totales (somme des probabilités) des deux sous -ensembles
soientt les plus proches possible. On affecte 1 pour un sous-ensemble et 0 pour l’autre.
3. Répéter l’étape 2 pour chaque sous-ensemble contenant au moins deux symboles. L’algorithme se
termine lorsque tous les sous-ensembles contiennent un seul symbole.
4. Les digits binaires successifs affectés aux sous-ensembles sont groupés pour former les mots de
codes.
Exemple 7:
Considérons une source S discrète, stationnaire et sans mémoire, prenant des valeurs dans
{𝐴, 𝐵, 𝐶, 𝐷, 𝐸, 𝐹, 𝐺 }, avec les probabilités {0.4, 0.15,0.15,0.1,0.1, 0.05,0.05}
Pour vérifier la faisabilité d’une compression, on doit comparer l’entropie de la source à Hmax.
Puisque H(S) est inférieure à Hmax, la source contient une redondance et peut être compressée. Nous
allons appliquer l’algorithme de Shannon-Fano comme décrit dans le tableau suivant :
Pour évaluer l’efficacité de l’algorithme de codage, on doit calculer la longueur moyenne du code.
Comparativement à un codage binaire classique qui utilise 3 bits pour coder 7 symboles, la réduction
3−2.55
du taux de symboles offerte par la méthode de Shannon-Fano est de 15%, soit : ≅ 0.15
3
Cet algorithme a été proposé par Huffman en 1952. Il permet de développer des codes préfixes (sans
préfixes) en utilisant les arbres de codage. En pratique, l’algorithme de Huffman est utilisé dans les
applications de compression sans perte telles que le format JPEG pour les images, MPEG pour les
vidéos et MP3 pour l’audio. Il se compose des étapes suivantes :
1. Classer les symboles de la source en bas et de gauche à droite selon l’ordre croissant des
probabilités.
2. On combine les deux symboles ayant les deux plus faibles probabilités dans un nœud obtenu en
utilisant des arcs sortants des deux symboles. Un arc sera affecté d’une valeur égale à 1 et l’autre
prend 0. Le nœud obtenu est considéré comme un nouveau symbole dont la probabilité est la
somme des deux probabilités. Supprimer ainsi les deux symboles utilisés et rajouter le nouveau
symbole à la liste des symboles.
3. Reprendre l’étape 2 jusqu’à l’obtention d’un nœud ayant une probabilité égale à 1 (Racine de
l’arbre de codage).
4. Les codes des chemins qui mènent aux différents symboles depuis la racine constituent les mots de
code respectifs.
Exemple 8: On reprend la source utilisée dans l’exemple 7. Le codage de Huffman est tel que :
1
0 1
Niveau 4 : 0.60
0 1
Niveau 3 : 0.35
0 1
Niveau 2 : 0.20
0 1
G F E C D B A
Evaluation :
𝐻( 𝑆)
Efficacité : 𝐸𝐹 =
𝐿̅
𝐿̅−𝐻( 𝑠) 𝐻( 𝑆)
Taux de redondance de la source codée (après codage) noté rc: 𝑟𝑐 = =1− = 1 − 𝐸𝐹
𝐿̅ 𝐿̅
Conclusions :
a) Lorsque les mots de source (un mot est une suite de symboles source) ont la même longueur, le
codage de Huffman est le plus efficace parmi les codes à déchiffrement unique.
Le code Lempel-Ziv connu sous le nom LZ-78 est un codage basé sur l’utilisation d’un dictionnaire. Il
a été inventé en 1978 (Première version en 1977) pour permettre la compression d’une source avec les
avantages suivants :
La compression est universelle, donc les probabilités de distribution des symboles sources, ne
doivent pas être connues.
C’est un code optimal (ou efficace), car le nombre de bits par symbole tend vers l’entropie.
La séquence source est découpée en plusieurs séquences (ou chaines) de symboles qui ne sont pas
apparues précédemment. Par exemple, la séquence : 1011010100010 est découpée en 1, 0, 11,
01,010,00,10. Dans ce cas, le dictionnaire initial contient deux caractères 0 et 1. A chaque fois que
l’on veut extraire une sous-chaine il faut tenir compte des sous-chaines précédentes, pour ne pas créer
une sous-chaine existante. Pour cette raison, la cinquième sous-chaine prend 010 et non pas 01 qui
existe déjà dans le dictionnaire. Une fois le découpage terminé, le codage LZ transforme chaque sous -
chaine en un couple contenant :
Pour notre exemple nous obtenons le codage décrit par le tableau suivant :
Dans le cas où le message contient des caractères, on utilise le code ASCII comme dictionnaire de
codage.
Algorithme LZW :
En 1984, Terry Welch a proposé une amélioration de l’algorithme LZ appelée LZW. Il consiste à
utiliser une table de codage appelée Dictionnaire contenant des chaînes de caractères avec leurs
positions (appelées Index) pour compresser un message. Il est composé des étapes suivantes :
1. Au départ, le dictionnaire est initialisé avec des chaînes composées d’un seul caractère (Exemple
code ASCII sur 8 bits) en affectant un numéro d’index pour chaque chaîne en commençant par 0.
2. Puis, le dictionnaire est mis à jour progressivement au fur et à mesure de l’apparition d’une
nouvelle chaîne. Pour cela, l’algorithme utilise un pointeur pour balayer le message à compresser
de la gauche vers la droite. Ce pointeur permet d’identifier le code de la chaîne se trouvant dans le
dictionnaire pour coder le message. Le premier caractère correspond à la première chaine
d’initialisation « P ». On lit le caractère suivant dans le message « c ». Si la juxtaposition P⊕c
n’est pas dans le dictionnaire, on l’ajoute comme nouvelle chaine, on envoie la position de P et on
utilise c pour initialiser la chaine suivante.
Exemple 9:
Lire le premier caractère et l’envoyer en sortie. Ce caractère est utilisé comme chaine
d’initialisation « P » pour l’étape suivante.
Remarques :
Pour terminer le codage avec LZW, on envoie toujours la position du dernier caractère.
Les positions peuvent être codées sur un nombre fixe de bits, mais l’algorithme est plus
efficace avec un nombre variable. On commence toujours par 9 bits, car 8 bits sont réservés
pour le code ASCII qui est très souvent utilisé comme dictionnaire initial du codage.
Le taux de compression évalué sur des fichiers de 6MB de type texte, binaire et graphique a donné les
résultats ci-dessous:
Conclusion :
Dans ce chapitre, nous avons appris les notions fondamentales du codage source, notamment, les
propriétés d’un codage efficace et à déchiffrement unique. Nous avons étudié quelques algorithmes de
compression. Parmi ces algorithmes, le codage entropique par l’algorithme de Huffman permet une
compression sans perte avec des codes binaires.