Files
graphes-l3/Seance_2_Representations.ipynb
T

16 KiB

🧮 Séance 2 — Représenter un graphe : matrice, liste d'adjacence, incidence

Objectifs pédagogiques

À la fin de cette séance, vous serez capables de :

  • représenter un graphe à l'aide d'une matrice d'adjacence et d'une liste d'adjacence ;
  • représenter un graphe à l'aide d'une matrice/liste d'incidence (sommets × arêtes) ;
  • choisir la représentation la plus adaptée selon la taille et la densité d'un réseau ;
  • interpréter les liens sociaux à partir de ces représentations ;
  • comprendre la symétrie, le degré et les liens indirects dans un réseau ;
  • construire et explorer ces représentations avec Python.

Introduction

En sociologie, on cherche souvent à représenter les relations entre individus : qui connaît qui, qui travaille avec qui, qui échange le plus, etc.

Un graphe permet de modéliser ces interactions :

  • nœuds (ou sommets) → les individus
  • arêtes (ou liens) → les relations entre eux

Mais il existe plusieurs manières, plus mathématiques, de représenter ces relations : la matrice d'adjacence, la liste d'adjacence, et la matrice/liste d'incidence. Chacune a ses avantages selon la taille du réseau et ce qu'on veut en faire.

Définition

Pour un graphe G = (V, E) à n sommets, la matrice d'adjacence A est une matrice carrée n × n où :

A_{ij} = \begin{cases}1 & \text{si une arête relie le sommet } i \text{ au sommet } j \\0 & \text{sinon}\end{cases}
  • Dans un graphe non dirigé, A est symétrique : A_{ij} = A_{ji}
  • Dans un graphe dirigé, A peut être asymétrique : A_{ij} = 1 ne signifie pas forcément A_{ji} = 1

Partie 1 — Représentation papier

1. Graphe de départ

Voici un petit réseau d'amitié entre cinq personnes :

Alice — Bob — Claire
  │        │
 David     Emma

Consigne :

  1. Listez les sommets : Alice, Bob, Claire, David, Emma.
  2. Complétez la matrice d'adjacence correspondante :
Alice Bob Claire David Emma
Alice 0
Bob 0
Claire 0
David 0
Emma 0

(Remplissez avec des 1 là où il existe un lien.)

2. Questions d'analyse

  1. Quel est le degré de chaque individu (combien de liens possède-t-il) ?
  2. Quel est l'individu le plus central dans ce réseau ?
  3. Si on ajoute un lien entre David et Emma, comment la matrice change-t-elle ?
  4. Que signifie le fait que la matrice soit symétrique ?
  5. En sociologie, que représenterait une matrice non symétrique ? (donnez un exemple concret)

Explication :

  • Une matrice symétrique signifie que les relations sont réciproques : si Alice est amie avec Bob, Bob l'est aussi avec Alice. Cela correspond à des relations mutuelles (amitié, collaboration, parenté, etc.).
  • Une matrice non symétrique représente des relations non réciproques : par exemple, A suit B sur Twitter, A cite B dans un article scientifique, ou A supervise B dans une organisation.

Partie 2 — Exploration Python

In [ ]:
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt

1. Créer et afficher la matrice

In [ ]:
G = nx.Graph()
G.add_edges_from([
    ("Alice","Bob"),
    ("Bob","Claire"),
    ("Alice","David"),
    ("Bob","Emma")
])

# Obtenir la matrice d'adjacence
A = nx.to_numpy_array(G, nodelist=G.nodes())
print(list(G.nodes()))
print(A.astype(int))

2. Visualiser le graphe

In [ ]:
plt.figure()
nx.draw(G, with_labels=True, node_color="lightblue", node_size=1000)
plt.show()

3. Explorer la structure du réseau

In [ ]:
# Degré de chaque sommet
print("Degré de chaque individu :", dict(G.degree()))

# Densité du réseau (rapport entre liens existants et liens possibles)
print("Densité du réseau :", round(nx.density(G), 2))

4. Liens indirects : le carré de la matrice

In [ ]:
A2 = np.linalg.matrix_power(A, 2)
print("A² =\n", A2.astype(int))

Interprétation :

  • Si A²[i][j] > 0, cela signifie qu'il existe un ami commun entre les nœuds i et j.
  • En sociologie : cela mesure les liens indirects, c'est-à-dire les "amis d'amis".

Pourquoi ne met-on pas les éléments eux-mêmes au carré ?

Quand on écrit , cela signifie A × A, c'est-à-dire qu'on multiplie la matrice par elle-même selon les règles de la multiplication matricielle.

On ne calcule pas (A_{ij})^2, car cela n'aurait aucun intérêt :

  • 0^2 = 0 et 1^2 = 1, donc la matrice ne changerait pas.
  • Le but du carré matriciel est de compter les chemins de longueur 2 entre les nœuds.

Formellement :

A^2_{ij} = \sum_k A_{ik} \times A_{kj}

Cela signifie que A^2_{ij} indique combien de façons il existe d'aller du nœud i au nœud j en passant par exactement un autre nœud.

Exemple : Si A =


\begin{bmatrix}
0 & 1 & 0 \\
1 & 0 & 1 \\
0 & 1 & 0
\end{bmatrix}

alors A^2 =


\begin{bmatrix}
1 & 0 & 1 \\
0 & 2 & 0 \\
1 & 0 & 1
\end{bmatrix}
  • A^2_{13} = 1 : il existe un chemin de longueur 2 entre 1 et 3 (en passant par 2).
  • A^2_{22} = 2 : le sommet 2 a deux chemins de longueur 2 qui reviennent à lui-même.

Résumé :

Calcul Signification Utilité
(A_{ij})^2 Élève chaque case au carré Inutile (0 et 1 inchangés)
A^2 = A × A Produit matriciel Donne les liens indirects (chemins de longueur 2)

Partie 3 — Liste d'adjacence

La matrice d'adjacence a un défaut : pour un réseau de 500 personnes, elle contient 500 × 500 = 250 000 cases, même si chacune n'a que 10 amis en moyenne (la plupart des cases valent alors 0). Or les réseaux sociaux réels sont presque toujours creux (sparse) : chaque individu ne connaît qu'une petite fraction du groupe.

La liste d'adjacence répond à ce problème : au lieu d'une grille, on associe à chaque sommet la liste de ses voisins. On ne stocke que les liens qui existent réellement.

\text{Alice} \rightarrow [\text{Bob}, \text{David}] \text{Bob} \rightarrow [\text{Alice}, \text{Claire}, \text{Emma}]

1. Construire la liste d'adjacence

In [ ]:
# NetworkX construit directement la liste d'adjacence à partir du graphe G
liste_adjacence = nx.to_dict_of_lists(G)

for personne, amis in liste_adjacence.items():
    print(f"{personne}{amis}")

2. Comparer matrice et liste d'adjacence

Questions :

  1. Combien de "cases" contient la matrice d'adjacence de ce petit réseau à 5 personnes ? Combien de liens contient la liste d'adjacence ?
  2. Pour un réseau de 10 000 personnes où chacune a en moyenne 50 ami·es, quelle représentation prendrait le moins de mémoire ?
  3. Pour répondre rapidement à la question "Alice et Emma sont-elles amies ?", quelle représentation est la plus directe ?
  4. Pour répondre à "quels sont les ami·es de Bob ?", quelle représentation est la plus directe ?

En résumé : la matrice d'adjacence est pratique pour les calculs matriciels (comme A^2) et les réseaux denses. La liste d'adjacence est plus économe en mémoire et plus rapide à parcourir pour les réseaux creux — c'est-à-dire la grande majorité des réseaux sociaux réels.

Partie 4 — Matrice et liste d'incidence

Les représentations précédentes croisent des sommets avec des sommets (qui est relié à qui). La matrice d'incidence change de point de vue : elle croise des sommets avec des arêtes (quel individu est concerné par quelle relation).

Pour un graphe à n sommets et m arêtes, la matrice d'incidence B est une matrice n × m où :

B_{ie} = \begin{cases}1 & \text{si le sommet } i \text{ est une extrémité de l'arête } e \\0 & \text{sinon}\end{cases}

Chaque colonne représente donc une relation (une arête), avec exactement deux 1 : ses deux extrémités.

Cette idée rejoint celle du graphe biparti vue en Introduction (COURS.md — individus ↔ opinions, individus ↔ événements) : on peut voir la matrice d'incidence comme "qui participe à quelle relation", exactement comme on notait "qui participe à quel événement".

1. Construire la matrice d'incidence

In [ ]:
# Construction manuelle de la matrice d'incidence avec numpy
# (une colonne par arête, deux 1 par colonne : les deux extrémités)
liste_aretes = list(G.edges())
sommets = list(G.nodes())

B = np.zeros((len(sommets), len(liste_aretes)), dtype=int)
for colonne, (u, v) in enumerate(liste_aretes):
    B[sommets.index(u), colonne] = 1
    B[sommets.index(v), colonne] = 1

print("Arêtes (colonnes) :", liste_aretes)
print(sommets)
print(B)

Interprétation : chaque colonne de B contient exactement deux 1, ceux des deux personnes impliquées dans cette relation. Une ligne "pleine de 0" signifierait un individu isolé, qui n'apparaît dans aucune relation.

2. Liste d'incidence

De la même façon qu'on a allégé la matrice d'adjacence en liste d'adjacence, on peut alléger la matrice d'incidence : au lieu d'une grille sommets × arêtes, on liste simplement, pour chaque arête, ses deux extrémités. C'est en fait exactement ce que renvoie G.edges() :

In [ ]:
# La liste d'incidence : pour chaque arête, ses deux extrémités
for i, (u, v) in enumerate(G.edges()):
    print(f"Arête {i} : {u}{v}")

Application sociologique : l'incidence est surtout utile quand la relation elle-même porte de l'information (sa date, son contexte, son type), plutôt que le simple fait qu'elle existe. Par exemple, une matrice d'incidence "individus × réunions" (chaque colonne = une réunion, chaque 1 = une personne présente) permet de repérer qui participe aux mêmes réunions que qui — c'est d'ailleurs la logique du graphe biparti vu en introduction, ramenée à une structure sommets × arêtes plutôt que sommets × sommets.

Synthèse

Concept mathématique Interprétation sociologique
1 dans la matrice d'adjacence lien direct entre deux individus
0 dans la matrice d'adjacence absence de lien
somme d'une ligne (matrice) / longueur d'une liste (liste d'adjacence) degré (popularité / nombre de connexions)
symétrie réciprocité des relations
A^2 existence de relations indirectes
densité cohésion du groupe
liste d'adjacence représentation compacte, adaptée aux réseaux creux (la plupart des réseaux sociaux réels)
matrice/liste d'incidence met en avant les relations elles-mêmes (utile si elles portent de l'information : date, contexte, type)
Représentation Taille Adaptée à
Matrice d'adjacence n × n petits réseaux, réseaux denses, calculs matriciels
Liste d'adjacence proportionnelle au nombre de liens grands réseaux creux (cas le plus fréquent)
Matrice/liste d'incidence n × m (sommets × arêtes) quand la relation elle-même porte de l'information

Questions de réflexion

  1. En quoi la matrice d'adjacence permet-elle de quantifier un réseau social ?
  2. Si une matrice est très dense, que peut-on en conclure sur le type de groupe étudié ?
  3. Comment pourriez-vous pondérer les liens dans cette matrice pour représenter l'intensité des relations ?
  4. Vous devez analyser le réseau de tou·tes les utilisateur·rices d'un réseau social (des millions de personnes, chacune avec quelques centaines d'ami·es en moyenne). Justifiez votre choix entre matrice et liste d'adjacence.
  5. Donnez un exemple de situation sociologique où la matrice d'incidence serait plus informative que la matrice d'adjacence.