Refonte du cours en 12 séances alignées sur le programme officiel
This commit is contained in:
263
Seance_5_Composantes_Diffusion.ipynb
Normal file
263
Seance_5_Composantes_Diffusion.ipynb
Normal file
@@ -0,0 +1,263 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Séance 5 — Diffusion d'une information (BFS) et composantes connexes\n",
|
||||
"\n",
|
||||
"## Objectifs\n",
|
||||
"- Comprendre intuitivement ce qu'est un **parcours en largeur** (BFS) et relier ce concept à la **diffusion d'une information, d'une rumeur ou d'une idée** dans un réseau social.\n",
|
||||
"- Mesurer des **distances sociales** et comparer l'effet du point de départ de la diffusion.\n",
|
||||
"- Comparer intuitivement le BFS au **parcours en profondeur (DFS)**.\n",
|
||||
"- Identifier les **composantes connexes** d'un réseau et interpréter la position d'un individu isolé."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 1. Introduction sociologique : une rumeur se propage\n",
|
||||
"Imaginez qu'une personne — appelons-la **Alice** — partage une nouvelle dans son groupe d'ami·es.\n",
|
||||
"Chacun·e la répète à ses proches, et ainsi de suite.\n",
|
||||
"\n",
|
||||
"L'information se diffuse **par cercles successifs** : d'abord les ami·es direct·es d'Alice, puis les ami·es des ami·es, etc.\n",
|
||||
"\n",
|
||||
"C'est exactement ce que fait un **parcours en largeur** : explorer un réseau *niveau par niveau*.\n",
|
||||
"\n",
|
||||
"→ En sociologie des réseaux, cela correspond à la **distance sociale** entre individus."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 2. Exemple manuel : propagation d'une information\n",
|
||||
"Considérons ce réseau à 7 personnes :\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"Alice — Bob — Chloé — David\n",
|
||||
" │ │ │\n",
|
||||
" Emma Félix Gaël\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Supposons qu'Alice commence à diffuser une nouvelle.\n",
|
||||
"\n",
|
||||
"**Étapes :**\n",
|
||||
"1. Niveau 0 : Alice\n",
|
||||
"2. Niveau 1 : les personnes directement connectées à Alice → {Bob, Emma}\n",
|
||||
"3. Niveau 2 : les ami·es de Bob (hors Alice) → {Chloé, Félix}\n",
|
||||
"4. Niveau 3 : les ami·es de Chloé → {David, Gaël}\n",
|
||||
"\n",
|
||||
"Chaque *niveau* correspond à une **distance sociale** par rapport à la source."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 3. Construire le réseau avec Python"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {},
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import networkx as nx\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"\n",
|
||||
"# Création du graphe\n",
|
||||
"G = nx.Graph()\n",
|
||||
"G.add_edges_from([\n",
|
||||
" ('Alice', 'Bob'), ('Alice', 'Emma'),\n",
|
||||
" ('Bob', 'Chloé'), ('Bob', 'Félix'),\n",
|
||||
" ('Chloé', 'David'), ('Chloé', 'Gaël')\n",
|
||||
"])\n",
|
||||
"\n",
|
||||
"pos = nx.spring_layout(G, seed=0)\n",
|
||||
"plt.figure(figsize=(6,4))\n",
|
||||
"nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=1000)\n",
|
||||
"plt.title('Réseau social — Diffusion de la nouvelle')\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 4. Explorer le réseau en largeur depuis Alice\n",
|
||||
"On peut utiliser la fonction `nx.bfs_tree()` pour construire un arbre de parcours à partir d'un point de départ."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {},
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"source = 'Alice'\n",
|
||||
"T = nx.bfs_tree(G, source=source)\n",
|
||||
"\n",
|
||||
"plt.figure(figsize=(6,4))\n",
|
||||
"nx.draw(T, with_labels=True, node_color='lightgreen', node_size=1000)\n",
|
||||
"plt.title(f'Arbre BFS à partir de {source}')\n",
|
||||
"plt.show()\n",
|
||||
"\n",
|
||||
"print('Ordre du parcours BFS :')\n",
|
||||
"print(list(nx.bfs_edges(G, source)))\n",
|
||||
"\n",
|
||||
"distances = nx.single_source_shortest_path_length(G, source)\n",
|
||||
"print('\\nDistances sociales depuis Alice :')\n",
|
||||
"for k, v in distances.items():\n",
|
||||
" print(f'{k} : {v}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Interprétation sociologique\n",
|
||||
"- Les **valeurs faibles** indiquent des individus **proches** d'Alice (accès direct à l'information).\n",
|
||||
"- Les **valeurs élevées** indiquent des individus **périphériques** : ils n'apprennent la nouvelle que tardivement.\n",
|
||||
"\n",
|
||||
"→ Cela permet d'analyser la **vitesse de diffusion** ou la **position sociale** dans le réseau.\n",
|
||||
"\n",
|
||||
"**Questions :**\n",
|
||||
"1. Dans quel ordre les personnes reçoivent-elles l'information ?\n",
|
||||
"2. Quel est le rôle d'Alice dans cette diffusion ?\n",
|
||||
"3. Quelle est la distance maximale observée ? Que signifie-t-elle socialement ?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 5. Comparaison intuitive : BFS vs DFS\n",
|
||||
"Pour bien comprendre la logique du BFS (revu en Séance 4), comparons-le brièvement à l'autre stratégie : le **DFS**.\n",
|
||||
"\n",
|
||||
"| Stratégie | Métaphore | Manière d'explorer | Exemple |\n",
|
||||
"|:-----------|:-----------|:------------------|:---------|\n",
|
||||
"| BFS (largeur) | diffusion sociale | explore les cercles autour de la source | bouche-à-oreille, message collectif |\n",
|
||||
"| DFS (profondeur) | exploration ciblée | suit un chemin jusqu'au bout avant de revenir | enquête, filiation, exploration hiérarchique |\n",
|
||||
"\n",
|
||||
"Le BFS **propagera rapidement une information**, tandis que le DFS **creusera une piste en profondeur**."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 6. Le point de départ change-t-il tout ? Recommençons depuis Chloé\n",
|
||||
"Recommençons la diffusion mais cette fois **à partir de Chloé**. Observez les différences de structure et de distances."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {},
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"source2 = 'Chloé'\n",
|
||||
"T2 = nx.bfs_tree(G, source=source2)\n",
|
||||
"\n",
|
||||
"plt.figure(figsize=(6,4))\n",
|
||||
"nx.draw(T2, with_labels=True, node_color='lightcoral', node_size=1000)\n",
|
||||
"plt.title(f'Arbre BFS à partir de {source2}')\n",
|
||||
"plt.show()\n",
|
||||
"\n",
|
||||
"print('Distances sociales depuis Chloé :')\n",
|
||||
"for k, v in nx.single_source_shortest_path_length(G, source2).items():\n",
|
||||
" print(f'{k} : {v}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Questions :**\n",
|
||||
"1. Quelles différences remarquez-vous par rapport au départ depuis Alice ?\n",
|
||||
"2. Quelle personne semble jouer un rôle « de pont » dans la diffusion (voir la notion de coefficient de clustering, Séance 3) ?\n",
|
||||
"3. Que peut-on dire de la position de Chloé dans le réseau ?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 7. Composantes connexes : un acteur isolé\n",
|
||||
"\n",
|
||||
"Jusqu'ici, tout le monde pouvait recevoir l'information de proche en proche. Mais que se passe-t-il si une personne n'est reliée à **personne** ?\n",
|
||||
"\n",
|
||||
"Ajoutons une nouvelle personne, **Hugo**, qui n'est reliée à personne dans le réseau."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {},
|
||||
"execution_count": null,
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Ajout d'une personne isolée\n",
|
||||
"G.add_node('Hugo')\n",
|
||||
"\n",
|
||||
"plt.figure(figsize=(6,4))\n",
|
||||
"pos = nx.spring_layout(G, seed=1)\n",
|
||||
"nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=1000)\n",
|
||||
"plt.title('Réseau social avec une personne isolée (Hugo)')\n",
|
||||
"plt.show()\n",
|
||||
"\n",
|
||||
"print('Composantes connexes du graphe :')\n",
|
||||
"for i, comp in enumerate(nx.connected_components(G)):\n",
|
||||
" print(f'Composante {i+1} : {comp}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Interprétation :** une **composante connexe** est un sous-ensemble du réseau où tout le monde peut s'atteindre par une suite de liens, mais qui n'a aucun lien vers le reste du réseau. Un individu isolé forme, à lui seul, sa propre composante.\n",
|
||||
"\n",
|
||||
"**Questions :**\n",
|
||||
"1. Hugo peut-il recevoir l'information ? Pourquoi ?\n",
|
||||
"2. Que représente un acteur isolé dans un réseau social réel ?\n",
|
||||
"3. Comment cette notion d'isolement peut-elle s'interpréter en sociologie (accès à l'information, exclusion sociale, marginalité) ?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 8. Pour aller plus loin (facultatif)\n",
|
||||
"1. Ajoutez de nouvelles relations pour rendre le graphe plus connecté.\n",
|
||||
"2. Essayez de trouver une configuration où tout le monde est relié en deux étapes maximum.\n",
|
||||
"3. Reliez Hugo au reste du réseau : combien de composantes reste-t-il ?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 9. Synthèse\n",
|
||||
"- Le **BFS** explore un réseau **par cercles successifs** à partir d'une source, et permet de mesurer la **distance sociale**.\n",
|
||||
"- Le point de départ de la diffusion **change radicalement** l'ordre et la vitesse à laquelle l'information circule.\n",
|
||||
"- Le **DFS** suit une logique d'exploration **en profondeur**, utile pour détecter des sous-groupes plutôt que pour simuler une diffusion rapide.\n",
|
||||
"- Une **composante connexe** est un sous-groupe où tout le monde est atteignable, mais coupé du reste. Un individu isolé ne reçoit jamais l'information : cela peut traduire une exclusion ou une marginalisation sociale."
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python",
|
||||
"pygments_lexer": "ipython3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
Reference in New Issue
Block a user