Compare commits
10 Commits
19f758f781
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 66376ea912 | |||
| d9f4818da3 | |||
| dbe5f21626 | |||
| b5601dcbf9 | |||
| 8282e70494 | |||
| d8705b3851 | |||
| 7db4900e6f | |||
| 5fa45aaf12 | |||
| 3adfad41f1 | |||
| 8a5376dc51 |
104
COURS.md
Normal file
104
COURS.md
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
# Algorithmes des graphes - Cours
|
||||||
|
|
||||||
|
## Introduction contextuelle
|
||||||
|
|
||||||
|
### 1.1 Les graphes : un outil essentiel en sciences sociales
|
||||||
|
|
||||||
|
Dans le cadre de la sociologie quantitative, les graphes sont des outils puissants pour modéliser et analyser les relations entre individus, groupes et institutions. En effet, une grande partie des études sociologiques se concentre sur les **interactions entre les individus** et sur la manière dont ces interactions influencent des phénomènes sociaux tels que la diffusion des idées, la formation de communautés, ou l'influence sociale.
|
||||||
|
|
||||||
|
Les graphes permettent de représenter ces relations de façon structurée et d'appliquer des méthodes d'analyse rigoureuses pour en extraire des informations pertinentes.
|
||||||
|
|
||||||
|
Un **graphe** est une structure composée de deux ensembles :
|
||||||
|
|
||||||
|
- Les **nœuds** (ou sommets) qui représentent les entités (par exemple, des individus dans une communauté).
|
||||||
|
- Les **arêtes** (ou liens) qui représentent les relations entre ces entités (par exemple, les relations d'amitié, de collaboration, ou d'interaction).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### Exemple : Réseaux sociaux
|
||||||
|
|
||||||
|
Prenons l'exemple d'un **réseau social** comme Facebook, LinkedIn ou Twitter. Dans ce contexte :
|
||||||
|
|
||||||
|
- Chaque **utilisateur** est un nœud du graphe.
|
||||||
|
- Une **arête** relie deux nœuds lorsqu'il existe une relation sociale entre ces utilisateurs (par exemple, ils sont amis, ils se suivent, ou ils interagissent).
|
||||||
|
|
||||||
|
<img src="assets/fb.png" alt="fb" />
|
||||||
|
|
||||||
|
*Exemple de graphe représentant des relations sur Facebook*
|
||||||
|
|
||||||
|
<img src="assets/x.png" alt="X" style="zoom: 50%;" />
|
||||||
|
|
||||||
|
*Exemple de graphe représentant des relations sur Twitter / X.*
|
||||||
|
|
||||||
|
Ce type de représentation permet de répondre à plusieurs questions pertinentes en sociologie :
|
||||||
|
|
||||||
|
- Quels individus jouent un rôle central dans un réseau social ?
|
||||||
|
- Comment l'information se diffuse-t-elle au sein d'un groupe ?
|
||||||
|
- Quelles sous-communautés ou groupes se forment dans une société donnée ?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1.2 Types de graphes couramment utilisés en sociologie
|
||||||
|
|
||||||
|
Il existe plusieurs types de graphes, chacun adapté à différents types de relations sociales et de données. Voici les plus courants :
|
||||||
|
|
||||||
|
- **Graphe non dirigé** : Un graphe où les relations entre les nœuds ne sont pas orientées. Cela signifie que si une relation existe entre A et B, elle est réciproque. Par exemple, dans un réseau d'amis, si A et B sont amis, cela est vrai dans les deux sens.
|
||||||
|
|
||||||
|
- **Graphe dirigé** : Un graphe où les relations ont une direction. Cela est utile pour représenter des relations non réciproques, comme les relations de suivi sur Twitter, où un utilisateur A peut suivre un utilisateur B, mais B ne suit pas nécessairement A.
|
||||||
|
|
||||||
|
- **Graphe pondéré** : Chaque arête d'un graphe est associée à un poids qui peut représenter la force d'une relation (par exemple, la fréquence des interactions entre deux individus). Cela permet de modéliser des relations plus fines et nuancées.
|
||||||
|
|
||||||
|
- **Graphe biparti** : Ce type de graphe est utile lorsqu'il s'agit de modéliser des relations entre deux types distincts d'entités. Par exemple, il peut être utilisé pour représenter les relations entre des individus et des événements (comme des personnes assistant à des conférences) ou des individus et des opinions (qui supporte telle ou telle idée politique).
|
||||||
|
|
||||||
|
### Exemple : Graphe biparti en sociologie
|
||||||
|
|
||||||
|
Dans une étude de sociologie politique, on pourrait modéliser un **graphe biparti** où :
|
||||||
|
|
||||||
|
- Les **nœuds de gauche** représentent des individus.
|
||||||
|
- Les **nœuds de droite** représentent des opinions ou partis politiques.
|
||||||
|
- Une **arête** existe entre un individu et une opinion s'il soutient cette idée.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Ce type de représentation permet d'analyser les relations complexes entre les individus et leurs idéologies ou appartenances politiques, et de voir comment ces relations évoluent dans le temps ou dans des contextes sociaux spécifiques.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1.3 Applications sociologiques des graphes
|
||||||
|
|
||||||
|
Les graphes offrent une **flexibilité exceptionnelle** pour modéliser et analyser une grande variété de phénomènes sociaux. Voici quelques exemples d'applications courantes en sociologie :
|
||||||
|
|
||||||
|
#### 1. Analyse des réseaux sociaux
|
||||||
|
|
||||||
|
L'analyse des réseaux sociaux permet d'identifier les individus les plus influents dans un groupe donné, de comprendre comment l'information ou les idées se diffusent, et de repérer des sous-groupes au sein de plus grandes communautés.
|
||||||
|
|
||||||
|
- **Centralité** : Un concept clé dans cette analyse est la notion de **centralité**. Un individu central dans un réseau est souvent celui qui a le plus d'interactions (mesuré par le nombre d'arêtes) ou celui qui est le mieux placé pour diffuser l'information dans le groupe.
|
||||||
|
|
||||||
|
- **Diffusion des idées** : Les graphes permettent aussi de modéliser la propagation des idées ou des innovations au sein d'une société, en identifiant les chemins les plus courts ou les relais clés dans la diffusion.
|
||||||
|
|
||||||
|
#### 2. Détection de communautés
|
||||||
|
|
||||||
|
Les graphes peuvent être utilisés pour détecter des **communautés** au sein d'un réseau, c'est-à-dire des groupes d'individus plus fortement connectés entre eux qu'au reste du réseau. Ces communautés peuvent représenter des groupes d'intérêts communs, des sous-cultures ou des classes sociales dans des contextes plus larges.
|
||||||
|
|
||||||
|
- **Exemple : Groupes d'amis dans un lycée** : On peut modéliser les interactions entre étudiants et utiliser des algorithmes pour identifier les groupes d'amis les plus cohésifs.
|
||||||
|
|
||||||
|
#### 3. Étude des inégalités sociales
|
||||||
|
|
||||||
|
Les graphes peuvent également servir à modéliser et analyser des phénomènes tels que les **inégalités sociales**. Par exemple, en étudiant les relations de collaboration ou de mentorat dans une entreprise, un graphe peut révéler des structures de pouvoir ou des barrières à la mobilité sociale.
|
||||||
|
|
||||||
|
- **Accès aux ressources** : En étudiant la distribution des liens dans un réseau, il est possible de comprendre qui a accès à des ressources critiques (telles que des informations ou des opportunités professionnelles) et qui est marginalisé.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Transition vers les concepts techniques :**
|
||||||
|
|
||||||
|
Dans le chapitre suivant, nous allons introduire les **concepts fondamentaux des graphes** en informatique et voir comment ils peuvent être formalisés et analysés à l'aide de différents algorithmes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Auteur : Florian Mathieu
|
||||||
|
|
||||||
|
Licence CC BY NC
|
||||||
|
|
||||||
|
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a>
|
||||||
|
Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||||
185
README.md
185
README.md
@@ -1,149 +1,88 @@
|
|||||||
## Algorithmes des graphes
|
# Algorithmes des Graphes - L3 Sociologie Quantitative
|
||||||
|
|
||||||
|
[](http://creativecommons.org/licenses/by-nc-sa/4.0/)
|
||||||
|
[](https://jupyter.org/)
|
||||||
|
|
||||||
|
Cours d'**algorithmes des graphes** pour les étudiants de L3 en sociologie quantitative.
|
||||||
|
|
||||||
### Introduction contextuelle
|
## Objectifs
|
||||||
|
|
||||||
|
Comprendre et utiliser les graphes pour analyser les **réseaux sociaux** et les **relations entre individus** :
|
||||||
|
- Modéliser des interactions sociales
|
||||||
|
- Identifier les individus influents
|
||||||
|
- Détecter des communautés
|
||||||
|
- Analyser la diffusion d'information
|
||||||
|
|
||||||
|
## Ouvrir les notebooks
|
||||||
|
|
||||||
**1.1 Les graphes : un outil essentiel en sciences sociales**
|
| Outil | Installation |
|
||||||
|
|-------|--------------|
|
||||||
|
| **[Basthon](https://basthon.fr)** | En ligne, sans installation |
|
||||||
|
| **Jupyter Notebook** | `pip install notebook` puis `jupyter notebook` |
|
||||||
|
| **Google Colab** | [colab.research.google.com](https://colab.research.google.com) |
|
||||||
|
|
||||||
|
## Programme
|
||||||
|
|
||||||
|
### 1. Introduction contextuelle
|
||||||
|
|
||||||
Dans le cadre de la sociologie quantitative, les graphes sont des outils puissants pour modéliser et analyser les relations entre individus, groupes et institutions. En effet, une grande partie des études sociologiques se concentre sur les **interactions entre les individus** et sur la manière dont ces interactions influencent des phénomènes sociaux tels que la diffusion des idées, la formation de communautés, ou l’influence sociale.
|
Les graphes en sciences sociales : modélisation des relations, réseaux sociaux, exemples Facebook/Twitter.
|
||||||
|
|
||||||
Les graphes permettent de représenter ces relations de façon structurée et d’appliquer des méthodes d’analyse rigoureuses pour en extraire des informations pertinentes.
|
### 2. Types de graphes
|
||||||
|
|
||||||
Un **graphe** est une structure composée de deux ensembles :
|
| Type | Description | Exemple |
|
||||||
|
|------|-------------|---------|
|
||||||
|
| **Non dirigé** | Relations réciproques | Amitié Facebook |
|
||||||
|
| **Dirigé** | Relations orientées | Followers Twitter |
|
||||||
|
| **Pondéré** | Force des relations | Fréquence d'interaction |
|
||||||
|
| **Biparti** | Deux types d'entités | Individus ↔ Opinions |
|
||||||
|
|
||||||
• Les **nœuds** (ou sommets) qui représentent les entités (par exemple, des individus dans une communauté).
|
### 3. Concepts fondamentaux
|
||||||
|
|
||||||
• Les **arêtes** (ou liens) qui représentent les relations entre ces entités (par exemple, les relations d’amitié, de collaboration, ou d’interaction).
|
- Sommets et arêtes
|
||||||
|
- Degré d'un sommet
|
||||||
|
- Chemins et cycles
|
||||||
|
- Connexité
|
||||||
|
|
||||||
|
### 4. Algorithmes
|
||||||
|
|
||||||
|
| Algorithme | Usage |
|
||||||
|
|------------|-------|
|
||||||
|
| **Parcours en largeur (BFS)** | Plus court chemin, exploration |
|
||||||
|
| **Parcours en profondeur (DFS)** | Détection de cycles, composantes |
|
||||||
|
| **Dijkstra** | Plus court chemin pondéré |
|
||||||
|
| **Centralité** | Identifier les nœuds influents |
|
||||||
|
|
||||||

|
### 5. Applications sociologiques
|
||||||
|
|
||||||
|
- Analyse des réseaux sociaux
|
||||||
|
- Détection de communautés
|
||||||
|
- Étude des inégalités d'accès aux ressources
|
||||||
|
- Diffusion des idées et innovations
|
||||||
|
|
||||||
|
## Structure du dépôt
|
||||||
|
|
||||||
|
```
|
||||||
|
├── FONDAMENTAUX.md # Concepts de base
|
||||||
|
├── Djikstra/ # Algorithme de Dijkstra
|
||||||
|
├── Exercices/ # Exercices pratiques
|
||||||
|
├── Corrige1/, 2/, 3/ # Corrigés
|
||||||
|
├── copies/ # Travaux étudiants
|
||||||
|
└── assets/ # Images et schémas
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ressources
|
||||||
|
|
||||||
**Exemple : Réseaux sociaux**
|
- 📖 [Introduction contextuelle (cours)](COURS.md)
|
||||||
|
- 📄 [Cours complet (PDF)](Cours.pdf)
|
||||||
|
- 📄 [Algorithmes des graphes (PDF)](coursAlgoGraphes.pdf)
|
||||||
|
- 📝 [Exercices](Exercices.md)
|
||||||
|
|
||||||
|
## Licence
|
||||||
|
|
||||||
|
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a>
|
||||||
|
|
||||||
Prenons l’exemple d’un **réseau social** comme Facebook, LinkedIn ou Twitter. Dans ce contexte :
|
Ce cours est sous licence [CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/).
|
||||||
|
|
||||||
• Chaque **utilisateur** est un nœud du graphe.
|
---
|
||||||
|
|
||||||
• Une **arête** relie deux nœuds lorsqu’il existe une relation sociale entre ces utilisateurs (par exemple, ils sont amis, ils se suivent, ou ils interagissent).
|
*Florian Mathieu*
|
||||||
|
|
||||||
<img src="assets/fb.png" alt="fb" />
|
|
||||||
|
|
||||||
*Exemple de graphe représentant des relations sur Facebook*
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<img src="assets/x.png" alt="X" style="zoom: 50%;" />
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*Exemple de graphe représentant des relations sur Twitter / X.*
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Ce type de représentation permet de répondre à plusieurs questions pertinentes en sociologie :
|
|
||||||
|
|
||||||
• Quels individus jouent un rôle central dans un réseau social ?
|
|
||||||
|
|
||||||
• Comment l’information se diffuse-t-elle au sein d’un groupe ?
|
|
||||||
|
|
||||||
• Quelles sous-communautés ou groupes se forment dans une société donnée ?
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
**1.2 Types de graphes couramment utilisés en sociologie**
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Il existe plusieurs types de graphes, chacun adapté à différents types de relations sociales et de données. Voici les plus courants :
|
|
||||||
|
|
||||||
• **Graphe non dirigé** : Un graphe où les relations entre les nœuds ne sont pas orientées. Cela signifie que si une relation existe entre A et B, elle est réciproque. Par exemple, dans un réseau d’amis, si A et B sont amis, cela est vrai dans les deux sens.
|
|
||||||
|
|
||||||
• **Graphe dirigé** : Un graphe où les relations ont une direction. Cela est utile pour représenter des relations non réciproques, comme les relations de suivi sur Twitter, où un utilisateur A peut suivre un utilisateur B, mais B ne suit pas nécessairement A.
|
|
||||||
|
|
||||||
• **Graphe pondéré** : Chaque arête d’un graphe est associée à un poids qui peut représenter la force d’une relation (par exemple, la fréquence des interactions entre deux individus). Cela permet de modéliser des relations plus fines et nuancées.
|
|
||||||
|
|
||||||
• **Graphe biparti** : Ce type de graphe est utile lorsqu’il s’agit de modéliser des relations entre deux types distincts d’entités. Par exemple, il peut être utilisé pour représenter les relations entre des individus et des événements (comme des personnes assistant à des conférences) ou des individus et des opinions (qui supporte telle ou telle idée politique).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Exemple : Graphe biparti en sociologie**
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Dans une étude de sociologie politique, on pourrait modéliser un **graphe biparti** où :
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
• Les **nœuds de gauche** représentent des individus.
|
|
||||||
|
|
||||||
• Les **nœuds de droite** représentent des opinions ou partis politiques.
|
|
||||||
|
|
||||||
• Une **arête** existe entre un individu et une opinion s’il soutient cette idée.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Ce type de représentation permet d’analyser les relations complexes entre les individus et leurs idéologies ou appartenances politiques, et de voir comment ces relations évoluent dans le temps ou dans des contextes sociaux spécifiques.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**1.3 Applications sociologiques des graphes**
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Les graphes offrent une **flexibilité exceptionnelle** pour modéliser et analyser une grande variété de phénomènes sociaux. Voici quelques exemples d’applications courantes en sociologie :
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1. **Analyse des réseaux sociaux** :
|
|
||||||
|
|
||||||
L’analyse des réseaux sociaux permet d’identifier les individus les plus influents dans un groupe donné, de comprendre comment l’information ou les idées se diffusent, et de repérer des sous-groupes au sein de plus grandes communautés.
|
|
||||||
|
|
||||||
• **Centralité** : Un concept clé dans cette analyse est la notion de **centralité**. Un individu central dans un réseau est souvent celui qui a le plus d’interactions (mesuré par le nombre d’arêtes) ou celui qui est le mieux placé pour diffuser l’information dans le groupe.
|
|
||||||
|
|
||||||
• **Diffusion des idées** : Les graphes permettent aussi de modéliser la propagation des idées ou des innovations au sein d’une société, en identifiant les chemins les plus courts ou les relais clés dans la diffusion.
|
|
||||||
|
|
||||||
2. **Détection de communautés** :
|
|
||||||
|
|
||||||
Les graphes peuvent être utilisés pour détecter des **communautés** au sein d’un réseau, c’est-à-dire des groupes d’individus plus fortement connectés entre eux qu’au reste du réseau. Ces communautés peuvent représenter des groupes d’intérêts communs, des sous-cultures ou des classes sociales dans des contextes plus larges.
|
|
||||||
|
|
||||||
• **Exemple : Groupes d’amis dans un lycée** : On peut modéliser les interactions entre étudiants et utiliser des algorithmes pour identifier les groupes d’amis les plus cohésifs.
|
|
||||||
|
|
||||||
3. **Étude des inégalités sociales** :
|
|
||||||
|
|
||||||
Les graphes peuvent également servir à modéliser et analyser des phénomènes tels que les **inégalités sociales**. Par exemple, en étudiant les relations de collaboration ou de mentorat dans une entreprise, un graphe peut révéler des structures de pouvoir ou des barrières à la mobilité sociale.
|
|
||||||
|
|
||||||
• **Accès aux ressources** : En étudiant la distribution des liens dans un réseau, il est possible de comprendre qui a accès à des ressources critiques (telles que des informations ou des opportunités professionnelles) et qui est marginalisé.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
**Transition vers les concepts techniques :**
|
|
||||||
|
|
||||||
Dans le chapitre suivant, nous allons introduire les **concepts fondamentaux des graphes** en informatique et voir comment ils peuvent être formalisés et analysés à l’aide de différents algorithmes.
|
|
||||||
|
|
||||||
-------
|
|
||||||
|
|
||||||
Auteur : Florian Mathieu
|
|
||||||
|
|
||||||
Licence CC BY NC
|
|
||||||
|
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
|
||||||
|
|||||||
191
TP_1.ipynb
Normal file
191
TP_1.ipynb
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Séance 1 TP — Rappels & prise en main de NetworkX\n",
|
||||||
|
"\n",
|
||||||
|
"## Objectifs pédagogiques\n",
|
||||||
|
"- Réviser les définitions : nœuds, arêtes, graphes dirigés / non-dirigés / pondérés.\n",
|
||||||
|
"- Prendre en main `networkx` pour créer un graphe et le visualiser.\n",
|
||||||
|
"- Explorer des propriétés simples (degré, nombre de sommets et d’arêtes).\n",
|
||||||
|
"- Introduire graphes dirigés et pondérés.\n",
|
||||||
|
"\n",
|
||||||
|
"## Contexte sociologique\n",
|
||||||
|
"Les graphes servent à modéliser les relations sociales :\n",
|
||||||
|
"- Graphe non dirigé : relations symétriques (amitié, collaboration).\n",
|
||||||
|
"- Graphe dirigé : relations asymétriques (qui suit qui sur Twitter).\n",
|
||||||
|
"- Graphe pondéré : intensité des relations (fréquence de contact).\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# %pip install networkx matplotlib\n",
|
||||||
|
"\n",
|
||||||
|
"import networkx as nx\n",
|
||||||
|
"import matplotlib.pyplot as plt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Exercice 1 : Créer un graphe non dirigé"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Construisons un mini-réseau social\n",
|
||||||
|
"G = nx.Graph()\n",
|
||||||
|
"G.add_edges_from([\n",
|
||||||
|
" (\"Alice\", \"Bob\"),\n",
|
||||||
|
" (\"Bob\", \"Claire\"),\n",
|
||||||
|
" (\"Alice\", \"David\"),\n",
|
||||||
|
" (\"Claire\", \"David\"),\n",
|
||||||
|
"])\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Nœuds :\", list(G.nodes()))\n",
|
||||||
|
"print(\"Arêtes:\", list(G.edges()))\n",
|
||||||
|
"\n",
|
||||||
|
"plt.figure()\n",
|
||||||
|
"nx.draw(G, with_labels=True, node_color=\"lightblue\", node_size=1000)\n",
|
||||||
|
"plt.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Questions :**\n",
|
||||||
|
"1. Qui a le plus de voisins / voisines (ami-e-s) ?\n",
|
||||||
|
"2. Quelles sont les relations réciproques ?\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Exercice 2 : Explorer les propriétés du graphe"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"print(\"Nombre de sommets :\", G.number_of_nodes())\n",
|
||||||
|
"print(\"Nombre d'arêtes :\", G.number_of_edges())\n",
|
||||||
|
"print(\"Degrés de chaque sommet :\", dict(G.degree()))\n",
|
||||||
|
"print(\"Degré moyen :\", sum(dict(G.degree()).values())/G.number_of_nodes())"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Question :** Quel est le degré moyen et comment l’interpréter sociologiquement ?"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Exercice 3 : Graphe dirigé"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"DG = nx.DiGraph()\n",
|
||||||
|
"DG.add_edges_from([\n",
|
||||||
|
" (\"Alice\", \"Bob\"),\n",
|
||||||
|
" (\"Bob\", \"Claire\"),\n",
|
||||||
|
" (\"Claire\", \"Alice\")\n",
|
||||||
|
"])\n",
|
||||||
|
"\n",
|
||||||
|
"plt.figure()\n",
|
||||||
|
"nx.draw(DG, with_labels=True, node_color=\"lightgreen\", node_size=1000, arrows=True)\n",
|
||||||
|
"plt.show()\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Degré sortant :\", dict(DG.out_degree()))\n",
|
||||||
|
"print(\"Degré entrant :\", dict(DG.in_degree()))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Questions :**\n",
|
||||||
|
"1. Quelle différence avec le graphe non dirigé ?\n",
|
||||||
|
"2. Que représentent les degrés entrants et sortants sociologiquement (ex : followers) ?"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Exercice 4 : Graphe pondéré"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"WG = nx.Graph()\n",
|
||||||
|
"WG.add_edge(\"Alice\", \"Bob\", weight=5) # forte relation\n",
|
||||||
|
"WG.add_edge(\"Alice\", \"Claire\", weight=1) # relation faible\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Arêtes avec poids :\", WG.edges(data=True))\n",
|
||||||
|
"\n",
|
||||||
|
"# Dessin avec poids visibles\n",
|
||||||
|
"pos = nx.spring_layout(WG)\n",
|
||||||
|
"nx.draw(WG, pos, with_labels=True, node_color=\"lightcoral\", node_size=1000)\n",
|
||||||
|
"labels = nx.get_edge_attributes(WG, \"weight\")\n",
|
||||||
|
"nx.draw_networkx_edge_labels(WG, pos, edge_labels=labels)\n",
|
||||||
|
"plt.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Questions :**\n",
|
||||||
|
"1. Comment interpréter le poids d’une relation en sociologie ?\n",
|
||||||
|
"2. Donnez un exemple concret (fréquence de discussions, intensité d’une amitié)."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"name": "python",
|
||||||
|
"version": "3.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
284
TP_2.ipynb
Normal file
284
TP_2.ipynb
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Séance 2 — Parcours & distances (BFS / DFS)\n",
|
||||||
|
"\n",
|
||||||
|
"## Objectifs pédagogiques\n",
|
||||||
|
"- Comprendre les notions de **chemin**, **distance** et ** composantes connexes**.\n",
|
||||||
|
"- Distinguer **BFS** (parcours en largeur) et **DFS** (parcours en profondeur).\n",
|
||||||
|
"- Utiliser `networkx` pour calculer des plus courts chemins dans un graphe **non pondéré**.\n",
|
||||||
|
"- Relier les distances à des interprétations sociologiques (proximité, relais, \"six degrés\").\n",
|
||||||
|
"\n",
|
||||||
|
"## Rappels\n",
|
||||||
|
"- Dans un **graphe non pondéré**, un **plus court chemin** est le chemin avec le **moins d'arêtes**.\n",
|
||||||
|
"- **BFS** explore par **couches** (distance croissante) et permet de trouver un plus court chemin.\n",
|
||||||
|
"- **DFS** explore en **profondeur** (par branches) ; utile pour détecter des cycles/composantes mais **ne garantit pas** un plus court chemin.\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# %pip install networkx matplotlib\n",
|
||||||
|
"\n",
|
||||||
|
"import networkx as nx\n",
|
||||||
|
"import matplotlib.pyplot as plt\n",
|
||||||
|
"from collections import deque"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## 1) Graphe de départ : petit réseau social"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Vous pouvez modifier/étendre ce graphe\n",
|
||||||
|
"G = nx.Graph()\n",
|
||||||
|
"G.add_edges_from([\n",
|
||||||
|
" (\"Alice\",\"Bob\"),\n",
|
||||||
|
" (\"Bob\",\"Claire\"),\n",
|
||||||
|
" (\"Claire\",\"Emma\"),\n",
|
||||||
|
" (\"Alice\",\"David\"),\n",
|
||||||
|
" (\"David\",\"Emma\"),\n",
|
||||||
|
" (\"Emma\",\"Fanny\"),\n",
|
||||||
|
" (\"Bob\",\"Gaston\"),\n",
|
||||||
|
"])\n",
|
||||||
|
"\n",
|
||||||
|
"# Visualisation simple\n",
|
||||||
|
"plt.figure()\n",
|
||||||
|
"nx.draw(G, with_labels=True)\n",
|
||||||
|
"plt.show()\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Nœuds :\", list(G.nodes()))\n",
|
||||||
|
"print(\"Arêtes:\", list(G.edges()))\n",
|
||||||
|
"print(\"Composantes connexes:\", nx.number_connected_components(G))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Question :** Y a-t-il un unique groupe connecté, ou plusieurs ? Impact sociologique : des individus isolés auront des distances infinies vers le reste."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## 2) Plus courts chemins et distances avec NetworkX"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"source, cible = \"Alice\", \"Fanny\"\n",
|
||||||
|
"chemin = nx.shortest_path(G, source=source, target=cible) # plus court chemin (non pondéré)\n",
|
||||||
|
"dist = nx.shortest_path_length(G, source=source, target=cible)\n",
|
||||||
|
"print(f\"Plus court chemin de {source} à {cible} :\", chemin)\n",
|
||||||
|
"print(f\"Distance (nombre d'arêtes) :\", dist)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Exercice 2.1** : testez 3 autres paires (par ex. `('Gaston','Fanny')`, `('Alice','Claire')`, `('David','Bob')`).\n",
|
||||||
|
"\n",
|
||||||
|
"**Exercice 2.2** : si vous supprimez l'arête `('David','Emma')`, que devient la distance `Alice→Fanny` ?"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## 3) Implémenter un BFS pédagogique (pour comprendre l'ordre d'exploration)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def bfs_layers(graph, start):\n",
|
||||||
|
" \"\"\"Retourne l'ordre de visite et les couches de distance (dict: noeud -> distance)\n",
|
||||||
|
" BFS avec file d'attente (deque).\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" visited = set([start])\n",
|
||||||
|
" dist = {start: 0}\n",
|
||||||
|
" order = []\n",
|
||||||
|
" q = deque([start])\n",
|
||||||
|
"\n",
|
||||||
|
" while q:\n",
|
||||||
|
" u = q.popleft()\n",
|
||||||
|
" order.append(u)\n",
|
||||||
|
" for v in graph.neighbors(u):\n",
|
||||||
|
" if v not in visited:\n",
|
||||||
|
" visited.add(v)\n",
|
||||||
|
" dist[v] = dist[u] + 1\n",
|
||||||
|
" q.append(v)\n",
|
||||||
|
" return order, dist\n",
|
||||||
|
"\n",
|
||||||
|
"order, dist = bfs_layers(G, \"Alice\")\n",
|
||||||
|
"print(\"Ordre BFS depuis Alice:\", order)\n",
|
||||||
|
"print(\"Distances depuis Alice:\", dist)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Exercice 3.1** : Comparez les **distances** renvoyées par `bfs_layers` et `nx.shortest_path_length` pour 3 nœuds.\n",
|
||||||
|
"\n",
|
||||||
|
"**Exercice 3.2** : Quel nœud est le plus proche (distance minimale) d'**Alice** ? Le plus lointain ?"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## 4) Implémenter un DFS (ordre d'exploration par branches)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def dfs_order(graph, start, visited=None, order=None):\n",
|
||||||
|
" if visited is None: visited = set()\n",
|
||||||
|
" if order is None: order = []\n",
|
||||||
|
" visited.add(start)\n",
|
||||||
|
" order.append(start)\n",
|
||||||
|
" for v in graph.neighbors(start):\n",
|
||||||
|
" if v not in visited:\n",
|
||||||
|
" dfs_order(graph, v, visited, order)\n",
|
||||||
|
" return order\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Ordre DFS depuis Alice:\", dfs_order(G, \"Alice\"))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Exercice 4.1** : Pourquoi **l'ordre DFS** diffère-t-il souvent de l'ordre BFS ?\n",
|
||||||
|
"\n",
|
||||||
|
"**Exercice 4.2** : DFS trouve-t-il un plus court chemin ? Expliquez avec un contre-exemple si possible."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## 5) Distances globales : diamètre & distance moyenne (si connexe)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"if nx.is_connected(G):\n",
|
||||||
|
" # Diamètre = plus longue distance entre deux nœuds\n",
|
||||||
|
" d = nx.diameter(G)\n",
|
||||||
|
" # Distance moyenne (longueur moyenne des plus courts chemins)\n",
|
||||||
|
" apl = nx.average_shortest_path_length(G)\n",
|
||||||
|
" print(\"Diamètre:\", d)\n",
|
||||||
|
" print(\"Distance moyenne:\", apl)\n",
|
||||||
|
"else:\n",
|
||||||
|
" print(\"Le graphe n'est pas connexe : diamètre et distance moyenne ne sont pas définis globalement.\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Exercice 5.1** : Ajoutez/supprimez une arête et observez l'effet sur la distance moyenne. Interprétez sociologiquement (ex. apparition d'un **pont** qui réduit les distances)."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## 6) Étude guidée : \"six degrés de séparation\" (mini-expérience)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Construisons un graphe en anneau + quelques liens longue portée pour réduire drastiquement les distances\n",
|
||||||
|
"H = nx.cycle_graph(12) # 12 individus en cercle (0..11)\n",
|
||||||
|
"H = nx.relabel_nodes(H, {i: f\"P{i}\" for i in range(12)})\n",
|
||||||
|
"H.add_edge(\"P0\",\"P6\") # raccourci longue portée\n",
|
||||||
|
"H.add_edge(\"P3\",\"P9\") # autre raccourci\n",
|
||||||
|
"\n",
|
||||||
|
"plt.figure()\n",
|
||||||
|
"nx.draw(H, with_labels=True)\n",
|
||||||
|
"plt.show()\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Connexe:\", nx.is_connected(H))\n",
|
||||||
|
"print(\"Distance moyenne:\", nx.average_shortest_path_length(H))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"**Questions**\n",
|
||||||
|
"1. Que se passe-t-il si on **retire** les liens longue portée ?\n",
|
||||||
|
"2. Pourquoi quelques liens inter-groupes peuvent-ils **réduire fortement** les distances ?\n",
|
||||||
|
"3. Donnez une interprétation en termes de diffusion d'une rumeur/idée."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## 7) Synthèse écrite\n",
|
||||||
|
"- Comparez BFS et DFS sur votre graphe.\n",
|
||||||
|
"- Donnez 2 exemples de distances pertinentes en sociologie (ex. accès à l'information, recrutement).\n",
|
||||||
|
"- Proposez une **hypothèse** : l'ajout d'un lien entre deux groupes réduira X ; comment le tester ?"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "75d566ac",
|
||||||
|
"metadata": {},
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"name": "python",
|
||||||
|
"version": "3.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
1
TP_3.ipynb
Normal file
1
TP_3.ipynb
Normal file
File diff suppressed because one or more lines are too long
88
TP_4.ipynb
Normal file
88
TP_4.ipynb
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "# Séance 6 — Parcours en largeur (BFS) : comment l’information se propage dans un réseau\n\n## Objectifs\n- Comprendre intuitivement ce qu’est un **parcours en largeur** (Breadth-First Search ou BFS).\n- Relier ce concept à la **diffusion d’une information, d’une rumeur ou d’une idée** dans un réseau social.\n- Explorer un réseau avec Python et `networkx` pour visualiser cette propagation.\n- Comparer avec une autre stratégie d’exploration : le **parcours en profondeur (DFS)**.\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 1. Introduction sociologique : une rumeur se propage\nImaginez qu’une personne — appelons-la **Alice** — partage une nouvelle dans son groupe d’amis.\nChacun la répète à ses proches, et ainsi de suite.\n\nL’information se diffuse **par cercles successifs** : d’abord les amis directs d’Alice, puis les amis des amis, etc.\n\nC’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\nConsidérons ce réseau :\n\n```\nAlice — Bob — Chloé — David\n │ │ │\n Emma Félix Gaël\n```\n\nSupposons qu’Alice commence à diffuser une nouvelle.\n\n**Étapes :**\n1. Niveau 0 : Alice\n2. Niveau 1 : les personnes directement connectées à Alice → {Bob, Emma}\n3. Niveau 2 : les amis de Bob (hors Alice) → {Chloé, Félix}\n4. Niveau 3 : les amis de Chloé → {David, Gaël}\n\nChaque *niveau* correspond à une **distance sociale** par rapport à la source."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 3. Visualisation avec Python\nCréons ce réseau et voyons comment le BFS le parcourt."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"metadata": {},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": [],
|
||||||
|
"source": "import networkx as nx\nimport matplotlib.pyplot as plt\n\n# Création du graphe\nG = nx.Graph()\nG.add_edges_from([\n ('Alice', 'Bob'), ('Alice', 'Emma'),\n ('Bob', 'Chloé'), ('Bob', 'Félix'),\n ('Chloé', 'David'), ('Chloé', 'Gaël')\n])\n\nplt.figure(figsize=(6,4))\npos = nx.spring_layout(G, seed=0)\nnx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=1000)\nplt.title('Réseau social — Diffusion de la nouvelle')\nplt.show()"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 4. Explorer le réseau en largeur\nOn peut utiliser la fonction `nx.bfs_tree()` pour construire un arbre de parcours à partir d’un point de départ (ici, Alice)."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"metadata": {},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": [],
|
||||||
|
"source": "source = 'Alice'\nT = nx.bfs_tree(G, source=source)\n\nplt.figure(figsize=(6,4))\nnx.draw(T, with_labels=True, node_color='lightgreen', node_size=1000)\nplt.title(f'Arbre BFS à partir de {source}')\nplt.show()\n\nprint('Ordre du parcours BFS :')\nprint(list(nx.bfs_edges(G, source)))"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 5. Distances sociales depuis Alice\nLe BFS permet aussi de mesurer la **distance minimale** entre Alice et chaque autre personne."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"metadata": {},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": [],
|
||||||
|
"source": "distances = nx.single_source_shortest_path_length(G, source)\nprint('Distances sociales depuis Alice :')\nfor 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."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 6. Comparaison intuitive : BFS vs DFS\nPour bien comprendre la logique du BFS, comparons-le brièvement à une 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, information publique |\n| DFS (profondeur) | exploration ciblée | suit un chemin jusqu’au bout avant de revenir | enquête individuelle, relation hiérarchique |\n\nLe BFS **propagera rapidement une information**, tandis que le DFS **creusera une piste en profondeur**."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 7. Pour aller plus loin\n- Comment interpréteriez-vous un individu qui n’est **atteint par personne** (non connexe) ?\n- Si plusieurs personnes diffusent simultanément une info, que se passe-t-il ?\n- Quels phénomènes réels le BFS peut-il modéliser ? (rumeur, contagion, propagation d’un hashtag, etc.)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 8. Synthèse\n- Le **BFS** explore un réseau **par cercles successifs** à partir d’une source.\n- Il permet de mesurer la **distance sociale** et d’identifier les **positions centrales**.\n- Dans un graphe non connexe, certaines personnes ne reçoivent jamais l’information.\n- Le **DFS**, lui, suit une logique d’exploration **en profondeur**, utile pour détecter des **sous-groupes**.\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"name": "python",
|
||||||
|
"version": "3.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
117
TP_4_bis.ipynb
Normal file
117
TP_4_bis.ipynb
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "# Séance 6 bis — TP dirigé : Diffusion d’une information dans un réseau (BFS)\n\n## Objectifs\n- Manipuler concrètement un **parcours en largeur (BFS)** avec Python.\n- Visualiser la **diffusion d’une information** dans un réseau social.\n- Interpréter sociologiquement la **distance**, la **proximité** et la **position** des individus.\n\nCe TP prolonge la séance précédente sur le parcours en largeur."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 1. Création du réseau\nCommençons par créer un petit réseau social entre 7 personnes. Nous utiliserons la bibliothèque `networkx` pour représenter et afficher le graphe."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"metadata": {},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": [],
|
||||||
|
"source": "import networkx as nx\nimport matplotlib.pyplot as plt\n\n# Création d'un graphe non orienté\nG = nx.Graph()\n\n# Sommets et arêtes du réseau\nrelations = [\n ('Alice', 'Bob'), ('Alice', 'Emma'),\n ('Bob', 'Chloé'), ('Bob', 'Félix'),\n ('Chloé', 'David'), ('Chloé', 'Gaël')\n]\n\nG.add_edges_from(relations)\n\n# Affichage du graphe\npos = nx.spring_layout(G, seed=0)\nplt.figure(figsize=(6,4))\nnx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=1000)\nplt.title('Réseau social : relations entre individus')\nplt.show()"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "**Questions :**\n1. Quelle personne semble la plus « centrale » dans le graphe ?\n2. Quelle personne paraît la plus isolée ?\n3. Ce graphe est-il connexe (toutes les personnes peuvent-elles être atteintes ?)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 2. Parcours en largeur (BFS)\nNous allons simuler la diffusion d’une information à partir d’un individu : **Alice**."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"metadata": {},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": [],
|
||||||
|
"source": "source = 'Alice'\n\n# Création de l'arbre de parcours BFS depuis Alice\nT = nx.bfs_tree(G, source=source)\n\nplt.figure(figsize=(6,4))\nnx.draw(T, with_labels=True, node_color='lightgreen', node_size=1000)\nplt.title(f'Arbre BFS à partir de {source}')\nplt.show()\n\n# Affichage de l'ordre du parcours\nprint('Ordre du parcours BFS :')\nprint(list(nx.bfs_edges(G, source)))"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "**Questions :**\n1. Dans quel ordre les personnes reçoivent-elles l'information ?\n2. Quel est le rôle d'Alice dans cette diffusion ?\n3. Que se passerait-il si l'information partait de Bob plutôt que d'Alice ?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 3. Distances sociales depuis la source\nLe BFS permet de mesurer la distance sociale entre la source et chaque personne du réseau."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"metadata": {},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": [],
|
||||||
|
"source": "distances = nx.single_source_shortest_path_length(G, source)\nprint('Distances sociales depuis Alice :')\nfor k, v in distances.items():\n print(f'{k} : {v}')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "**Interprétation :**\n- Distance = nombre d’étapes pour atteindre une personne depuis Alice.\n- Plus la distance est grande, plus la personne est éloignée socialement.\n\n**Questions :**\n1. Qui apprend la nouvelle en premier ? En dernier ?\n2. Quelle distance maximale observe-t-on dans ce réseau ?\n3. Quelle est la signification sociologique d'une distance de 3 ?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 4. Comparaison avec un autre point de départ\nRecommenç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é'\nT2 = nx.bfs_tree(G, source=source2)\n\nplt.figure(figsize=(6,4))\nnx.draw(T2, with_labels=True, node_color='lightcoral', node_size=1000)\nplt.title(f'Arbre BFS à partir de {source2}')\nplt.show()\n\nprint('Distances sociales depuis Chloé :')\nfor k, v in nx.single_source_shortest_path_length(G, source2).items():\n print(f'{k} : {v}')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "**Questions :**\n1. Quelles différences remarquez-vous par rapport au départ depuis Alice ?\n2. Quelle personne semble jouer un rôle « de pont » dans la diffusion ?\n3. Que peut-on dire de la position de Chloé dans le réseau ?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 5. Expérience sociologique : un acteur isolé\nAjoutons une nouvelle personne, **Hugo**, qui n’est reliée à personne. Que se passe-t-il lors du BFS ?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"metadata": {},
|
||||||
|
"execution_count": null,
|
||||||
|
"outputs": [],
|
||||||
|
"source": "# Ajout d'une personne isolée\nG.add_node('Hugo')\n\nplt.figure(figsize=(6,4))\npos = nx.spring_layout(G, seed=1)\nnx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=1000)\nplt.title('Réseau social avec une personne isolée (Hugo)')\nplt.show()\n\nprint('Composantes connexes du graphe :')\nfor i, comp in enumerate(nx.connected_components(G)):\n print(f'Composante {i+1} : {comp}')"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "**Questions :**\n1. Hugo peut-il recevoir l'information ? Pourquoi ?\n2. Que représente un acteur isolé dans un réseau social réel ?\n3. Comment cette notion d'isolement peut-elle s’interpréter en sociologie ?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 6. Pour aller plus loin (facultatif)\n1. Ajoutez de nouvelles relations pour rendre le graphe plus connecté.\n2. Essayez de trouver une configuration où tout le monde est relié en deux étapes maximum.\n3. Testez d'autres points de départ pour le BFS et comparez les distances obtenues."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": "## 7. Synthèse\n- Le **BFS** permet de simuler la **diffusion d’une information** dans un réseau.\n- Les **distances** indiquent le **niveau d’accès à l’information**.\n- Les **personnes centrales** propagent plus vite, les **isolées** restent à l’écart.\n- Ces observations permettent de **lier structure du réseau et dynamique sociale**."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"name": "python",
|
||||||
|
"version": "3.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user