

A team of researchers from Bocconi University in Milan Italy successfully predicted that Robert Prevost might be elected as pope before his election was announced. In this article, we’ll discuss how they did it.
Who is this useful for? Anyone interested in understanding how AI can be used to make compelling predictions about complex topics.
How advanced is this post? This article is designed to be accessible to beginners, but contains compelling tricks that even senior data scientists might learn from. Later sections contain an implementation that may be compelling to more experienced data scientists.
Prerequisites: None, though supporting material will be provided throughout the article.
How A Pope is Elected
Before we get into the meat of it, I think it might be useful to explore why it’s challenging to predict who will be the pope in the first place.
The pope, considered by Catholics to be the successor to Saint Peter and the earthly head of the Roman Catholic Church, is an incredibly powerful figure today, and was an even more powerful figure in the 13th century. At the time, the church’s influence was vast and significant. Popes commanded armies, controlled territories, intervened in political affairs, and even excommunicated and disposed of kings. Cardinal-elects agreeing on which among them should rise to be the pope was a monumentally important decision, not just for catholicism, but for the entire world.
As a result, the election of the pope was prone to significant political influence. The interregnum of 1268–1271, at the height of Papal power, was the longest papal election in history, largely due to political infighting between cardinals which resulted from the tremendously potent relationship between the pope and the greater secular world.
The election took over two years, and was finally pushed passed gridlock after the electing cardinals were locked in a room, their rations were reduced to bread and water, and the roof in the room they occupied was removed. As a result of the length of the election, three of the twenty cardinal-electors died and one resigned.
Prompted by the untenability of this event, the “papal conclave” was formed; The word “conclave” came from the Latin phrase “cum clave” meaning “with a key”. During the papal conclave, cardinal-elects are locked in seclusion and are not allowed to leave until a pope is elected. The white smoke is used to communicate that the papal conclave has come to a conclusion. The Papal conclave, as per rules stipulated by the Roman Catholic Church, must begin 15 to 20 days after the pope’s death. Modern conclaves typically take around one to two days, though they can take longer.
As data scientists, this emerges as a compelling challenge. Presumably, much discussion and deliberation take place over that one to two-day stretch, and no one outside of the conclave has any knowledge of what is happening. How can we predict who the conclave might elect without hearing anything they’re saying, or what they’re talking about?
The Conclave as a Graph
While we don’t know exactly what the cardinal-elects may discuss within the conclave, we do know who they are, and can analyze documents about their relationships and interactions before the conclave commences. A team of researchers from Bocconi University, based on their article which details their analysis from a high level, chose to analyze key documents to build a “graph” of how cardinal elects within the conclave relate with one another.
A “graph”, in data science, is a key data structure often used to represent complex networks of social relationships. This is accomplished by representing each entity (each cardinal-elect) as a “node”, and the relationship between entities (if they worked together, if one ordained another, etc.) as an “edge”. By representing each cardinal as a “node”, and each relationship as an “edge”, we can construct a “graph” of relationships
Graphs have some attributes which make them compelling for this type of analysis. Chief among them is the concept of “centrality”.
Centrality
I have an article on Graphs where I discuss centrality in a graph context.
At its most basic, “Centrality” is simply a calculation of how “central” a node is. Depending on what you care about, “central” can be defined in many ways:
-
Degree Centrality is judging centrality by how many connections a node has. A node with more connections is more central.
-
Betweenness Centrality is judging centrality by how many shortest paths go through a node. If you need to pass through a node to traverse between nodes, then that node is more central.
-
Closeness Centrality is judged based on the average distance to all other nodes. If a node can be quickly navigated to by all other nodes, then that node is more central.
-
Eigenvector Centrality is a bit complex mathematically, but the essential idea is that it accounts for how impactful the neighbors of a particular node are. So, a node may be deemed “central” based on how important neighboring nodes are, even if it would rank low on all other metrics of centrality.
The core idea from our Milan research team was, once you construct a graph based on the relation of cardinal members with one another, the elected pope will likely be the most “central”.
Because there are several ways to define “centrality” in a graph context, the researchers conceptualized these different centrality metrics as a different form of social influence:
Status, measured by ‘eigenvector centrality’, rewards cardinals who are connected not only to many, but to the most influential ones.
Information control, estimated using ‘betweenness centrality’, identifies those who act as hubs between different groups: bridges, rather than pillars.
The ability to build coalitions, calculated using a composite index that combines clustering (which reflects how much a cardinal is part of a cohesive group based on trust and able to provide strong support) and direct influence (through the cardinal’s centrality, which measures how many direct connections they have — the higher the degree, the greater the influence and popularity) and strategic role (i.e., the extent to which a cardinal can act as a social bridge thanks to their position at the center of conversations or connections between other members of the network, improving their ability to build alliances between groups). — Source
They also adjusted these metrics based on the age of the cardinal elects, as it’s known that the conclave prefers to elect a cardinal who is neither too young, nor too old.
The “coalition building capacity” they define is a bit complex, but the other two are simply bog-standard centrality metrics used in many graph applications. Funnily enough, these simple metrics were sufficient.
The Results

Based on the three metrics posed by the researchers which might be indicative of who the pope might be, these were the results:
Top 5 by Status 1. Robert Prevost (moderate, US) 2. Lazzaro You Heung-sik (soft liberal, South Korea) 3. Arthur Roche (liberal, UK) 4. Jean-Marc Aveline (soft liberal, France) 5. Claudio Gugerotti (soft liberal, Italy) Top 5 for Information Control 1. Anders Arborelius (soft conservative, Sweden) 2. Pietro Parolin (liberal, Italy) 3. Víctor Fernández (liberal, Argentina) 4. Gérald Lacroix (moderate, Canada) 5. Joseph Tobin (liberal, USA) Top 5 for Coalition Building Capacity 1. Luis Antonio Tagle (soft liberal, Philippines) 2. Ángel Fernández Artime (soft liberal, Spain) 3. Gérald Lacroix (moderate, Canada) 4. Fridolin Besungu (soft conservative, Congo) 5. Sérgio da Rocha (soft liberal, Brazil)
As you can see, our baseball watching, deep dish eating Chicagoan is right there at the top of the list for status, which is derived by calculating the nodes which have the highest eigenvector centrality among all nodes in the graph.
Pretty cool, but unfortunately I couldn’t find any of the code they used to produce these findings. Let’s try to do something similar ourselves.
Giving it a Shot
The main task of this problem isn’t analyzing the graph, it’s constructing it in the first place. We need to get data off of websites and news reels and somehow turn that into a graph of cardinals and their relationships.
This is a pretty big task within itself. The Bocconi researchers specify a variety of sources they used, but in the interest of time I chiefly used catholic-hierarchy.org. This is an excellent website which automatically catalogues key information from a variety of trusted sources. This website contains a ton of information on the various cardinals who participated in the conclave and their relationships. It may not contain all of what the research team included in their graph, but we can play around and see if we get the same thing.
I opted to use OpenAI Deep Research to do my web scraping, which scrubbed through catholic-hierarchy as well as some Wikipedia articles and defined all the cardinals:
{ "nodes": [ { "name": "Pietro Parolin", "country": "Italy", "appointing_pope": "Francis", "religious_order": null, "roles": ["Secretary of State of His Holiness", "Cardinal-Bishop of Santi Simone e Giuda Taddeo"], "past_dioceses": ["Nuncio (Venezuela)"], "episcopal_consecrator": "Pope Benedict XVI" }, { "name": "Fernando Filoni", "country": "Italy", "appointing_pope": "Benedict XVI", "religious_order": null, "roles": ["Grand Master, Equestrian Order of the Holy Sepulchre", "Prefect Emeritus, Congregation for Evangelization"], "past_dioceses": ["Nuncio (Iraq)"], "episcopal_consecrator": "Pope John Paul II" }, { "name": "Luis Antonio Tagle", "country": "Philippines", "appointing_pope": "Benedict XVI", "religious_order": null, "roles": ["Pro-Prefect, Dicastery for Evangelization", "Archbishop Emeritus of Manila"], "past_dioceses": ["Diocese of Imus", "Archdiocese of Manila"], "episcopal_consecrator": "Jaime Cardinal Sin" }, { "name": "Robert Francis Prevost", "country": "United States", "appointing_pope": "Francis", "religious_order": "O.S.A.", "roles": ["Prefect, Dicastery for Bishops"], "past_dioceses": ["Bishop of Chiclayo (Peru)"], "episcopal_consecrator": "Seán Patrick Cardinal O’Malley" }, ...
I also asked Deep Research to drum up some of the connections between cardinals. GPT did that fun LLM thing where it leaves key information as an exercise for the reader, then failed to flesh out any more details upon further prompting. This very minimal set of connections I got wouldn’t cut it for the type of analysis we’re doing because it results in a lot of islands where certain cardinals are not connected in any way to some other cardinals within the graph. This simply isn’t how this particular social network works, all cardinals are connected if not directly than by a small number of indirect connections.
{ "edges": [ // Shared appointing Pope (weight 1) – connecting cardinals created by the same Pope { "source": "Vinko Puljić", "target": "Peter Turkson", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Vinko Puljić", "target": "Josip Bozanić", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Vinko Puljić", "target": "Philippe Barbarin", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Vinko Puljić", "target": "Péter Erdő", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Peter Turkson", "target": "Josip Bozanić", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Peter Turkson", "target": "Philippe Barbarin", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Peter Turkson", "target": "Péter Erdő", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Josip Bozanić", "target": "Philippe Barbarin", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Josip Bozanić", "target": "Péter Erdő", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Philippe Barbarin", "target": "Péter Erdő", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Stanisław Ryłko", "target": "Francisco Robles Ortega", "type": "same_appointing_pope", "pope": "Benedict XVI", "weight": 1 }, { "source": "Stanisław Ryłko", "target": "Daniel DiNardo", "type": "same_appointing_pope", "pope": "Benedict XVI", "weight": 1 }, // ... (all 20 Benedict XVI appointees similarly interconnected with weight 1) ... // (Francis created 108 cardinals – all are mutually connected with weight 1; omitted here due to volume) // Shared country or region (weight 1) – cardinals from the same national episcopal conference { "source": "Juan José Omella", "target": "Carlos Osoro Sierra", "type": "same_country", "country": "Spain", "weight": 1 }, { "source": "Antonio Cañizares Llovera", "target": "Juan José Omella", "type": "same_country", "country": "Spain", "weight": 1 }, // ... (e.g. all 17 Italian cardinals linked with each other; all 10 US cardinals linked; etc.) ... // Shared religious order (weight 2) – connecting cardinals belonging to the same religious institute { "source": "Ángel Fernández Artime", "target": "Charles Maung Bo", "type": "same_religious_order", "order": "Salesians (S.D.B.)", "weight": 2 }, { "source": "Jean-Claude Hollerich", "target": "Michael Czerny", "type": "same_religious_order", "order": "Jesuits (S.J.)", "weight": 2 }, { "source": "Mauro Gambetti", "target": "François-Xavier Bustillo", "type": "same_religious_order", "order": "Franciscans (O.F.M. Conv.)", "weight": 2 }, // ... (others, e.g. Arborelius–Cleemis (O.C.D.), Prevost–Ribat (Augustinians vs MSC), etc.) ... // Same or overlapping diocesan posting (weight 2) – cardinals who served in the same diocese (successively or together) { "source": "Luis Antonio Tagle", "target": "Jose Advincula", "type": "same_diocese", "diocese": "Manila", "weight": 2 }, { "source": "Wilton Daniel Gregory", "target": "Robert McElroy", "type": "same_diocese", "diocese": "Washington, D.C.", "weight": 2 }, { "source": "Jean-Pierre Kutwa", "target": "Ignace Bessi Dogbo", "type": "same_diocese", "diocese": "Abidjan", "weight": 2 }, { "source": "Carlos Osoro Sierra", "target": "José Cobo Cano", "type": "same_diocese", "diocese": "Madrid", "weight": 2 }, { "source": "João Braz de Aviz", "target": "Paulo Cezar Costa", "type": "same_diocese", "diocese": "Brasília", "weight": 2 }, { "source": "Fridolin Ambongo Besungu", "target": "Laurent Monsengwo Pasinya", "type": "same_diocese", "diocese": "Kinshasa", "weight": 2 }, // ... (additional overlaps like: Tempesta–Sérgio da Rocha (Rio/São Paulo), etc.) ... // Consecrator relationship (weight 3) – one cardinal was principal consecrator for the other's episcopal ordination { "source": "Carlos Osoro Sierra", "target": "José Cobo Cano", "type": "consecrator", "weight": 3 }, { "source": "Manuel Clemente", "target": "José Tolentino de Mendonça", "type": "consecrator", "weight": 3 }, { "source": "Orani João Tempesta", "target": "Paulo Cezar Costa", "type": "consecrator", "weight": 3 }, { "source": "João Braz de Aviz", "target": "Leonardo Ulrich Steiner", "type": "consecrator", "weight": 3 }, { "source": "Fernando Filoni", "target": "Giorgio Marengo", "type": "consecrator", "weight": 3 }, { "source": "Leonardo Sandri", "target": "Pierbattista Pizzaballa", "type": "consecrator", "weight": 3 }, { "source": "Thomas Collins", "target": "Frank Leo", "type": "consecrator", "weight": 3 }, { "source": "Jean-Pierre Kutwa", "target": "Ignace Bessi Dogbo", "type": "consecrator", "weight": 3 }, { "source": "Mario Aurelio Poli", "target": "Víctor Manuel Fernández", "type": "consecrator", "weight": 3 }, { "source": "Crescenzio Sepe", "target": "Domenico Battaglia", "type": "consecrator", "weight": 3 }, { "source": "Agostino Vallini", "target": "Matteo Zuppi", "type": "consecrator", "weight": 3 }, { "source": "Angelo Sodano", "target": "Dominique Mamberti", "type": "consecrator", "weight": 3 }, { "source": "Jaime Cardinal Sin", "target": "Luis Antonio Tagle", "type": "consecrator", "weight": 3 }, { "source": "Justin Francis Rigali", "target": "Raymond Leo Burke", "type": "consecrator", "weight": 3 }, { "source": "Godfried Danneels", "target": "Jozef De Kesel", "type": "consecrator", "weight": 3 }, { "source": "Stanisław Dziwisz", "target": "Grzegorz Ryś", "type": "consecrator", "weight": 3 }, // ... (additional consecrator edges connecting cardinals who ordained each other) ... ] }

Because we’re just playing around, I generated some fake plausible data based on a subset of these connections which is fully connected. We’ll use that as our data to play around with the approach.
edges = [ { "source": "Vinko Puljić", "target": "Peter Turkson", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Vinko Puljić", "target": "Josip Bozanić", "type": "same_country", "country": "Croatia", "weight": 1 }, { "source": "Peter Turkson", "target": "Philippe Barbarin", "type": "same_religious_order", "order": "Jesuits", "weight": 2 }, { "source": "Philippe Barbarin", "target": "Péter Erdő", "type": "same_appointing_pope", "pope": "John Paul II", "weight": 1 }, { "source": "Josip Bozanić", "target": "Péter Erdő", "type": "same_country", "country": "Central Europe", "weight": 1 }, { "source": "Wilton Daniel Gregory", "target": "Robert McElroy", "type": "same_diocese", "diocese": "Washington", "weight": 2 }, { "source": "Wilton Daniel Gregory", "target": "Michael Czerny", "type": "same_appointing_pope", "pope": "Francis", "weight": 1 }, { "source": "Robert McElroy", "target": "Frank Leo", "type": "same_country", "country": "USA", "weight": 1 }, { "source": "Frank Leo", "target": "Víctor Manuel Fernández", "type": "consecrator", "weight": 3 }, { "source": "Víctor Manuel Fernández", "target": "Leonardo Ulrich Steiner", "type": "same_country", "country": "Latin America", "weight": 1 }, { "source": "Leonardo Ulrich Steiner", "target": "Paulo Cezar Costa", "type": "same_diocese", "diocese": "Brasília", "weight": 2 }, { "source": "Paulo Cezar Costa", "target": "João Braz de Aviz", "type": "consecrator", "weight": 3 }, { "source": "Matteo Zuppi", "target": "Domenico Battaglia", "type": "same_diocese", "diocese": "Rome", "weight": 2 }, { "source": "Matteo Zuppi", "target": "Stanisław Ryłko", "type": "same_country", "country": "Europe", "weight": 1 }, { "source": "Stanisław Ryłko", "target": "Jean-Claude Hollerich", "type": "same_country", "country": "Europe", "weight": 1 }, { "source": "Jean-Claude Hollerich", "target": "Michael Czerny", "type": "same_religious_order", "order": "Jesuits", "weight": 2 }, { "source": "Fridolin Ambongo Besungu", "target": "Peter Turkson", "type": "same_country", "country": "Africa", "weight": 1 }, { "source": "Fridolin Ambongo Besungu", "target": "Jean-Pierre Kutwa", "type": "same_diocese", "diocese": "Kinshasa–Abidjan", "weight": 2 }, { "source": "Jean-Pierre Kutwa", "target": "Ignace Bessi Dogbo", "type": "consecrator", "weight": 3 }, { "source": "Ignace Bessi Dogbo", "target": "Jose Advincula", "type": "same_country", "country": "South Global Conference", "weight": 1 }, { "source": "Jose Advincula", "target": "Luis Antonio Tagle", "type": "same_diocese", "diocese": "Manila", "weight": 2 }, { "source": "Ángel Fernández Artime", "target": "Charles Maung Bo", "type": "same_religious_order", "order": "Salesians", "weight": 2 }, { "source": "Ángel Fernández Artime", "target": "Grzegorz Ryś", "type": "same_country", "country": "Europe", "weight": 1 }, { "source": "Grzegorz Ryś", "target": "Stanisław Dziwisz", "type": "consecrator", "weight": 3 }, { "source": "Stanisław Dziwisz", "target": "Godfried Danneels", "type": "same_country", "country": "Western Europe", "weight": 1 }, { "source": "Godfried Danneels", "target": "Jozef De Kesel", "type": "same_appointing_pope", "pope": "Benedict XVI", "weight": 1 }, { "source": "Carlos Osoro Sierra", "target": "José Cobo Cano", "type": "same_diocese", "diocese": "Madrid", "weight": 2 }, { "source": "Carlos Osoro Sierra", "target": "Antonio Cañizares Llovera", "type": "same_country", "country": "Spain", "weight": 1 }, { "source": "Antonio Cañizares Llovera", "target": "Domenico Battaglia", "type": "same_religious_order", "order": "Franciscans", "weight": 2 }, { "source": "Jean-Claude Hollerich", "target": "Luis Antonio Tagle", "type": "same_country", "country": "Asia-Europe Synod", "weight": 1 }, { "source": "João Braz de Aviz", "target": "Fridolin Ambongo Besungu", "type": "consecrator", "weight": 3 }, { "source": "Frank Leo", "target": "Stanisław Dziwisz", "type": "same_appointing_pope", "pope": "Francis", "weight": 1 }, { "source": "Peter Turkson", "target": "João Braz de Aviz", "type": "same_country", "country": "Global South", "weight": 1 } ]
I did a bit of prompting to encourage the model to search for connections between cardinals that are useful for the application. I think GPT 4o did a decent job defining a few key types of relationships to leverage.
- same_appointing_pope Weight: 1 Description: Cardinals created by the same pope (e.g., Francis, Benedict XVI). Relevance: Indicates shared ideological or theological alignment, papal favor, and potential voting bloc behavior. - same_country Weight: 1 Description: Cardinals from the same country or part of the same national episcopal conference. Relevance: Shared national identity, policy priorities, or episcopal collaboration; often vote similarly or coordinate. - same_continent Weight: 0.5 Description: Cardinals from the same continent (e.g., Asia, Africa, Europe). Relevance: Weaker regional commonalities, can reflect geographic affinity or geopolitical considerations. - same_religious_order Weight: 2 Description: Cardinals who are members of the same religious order (e.g., Jesuits, Franciscans, Salesians). Relevance: Very strong internal loyalty and ideological cohesion; orders often function like networks within the hierarchy. - same_diocese Weight: 2 Description: Cardinals who served in the same diocese, even at different times. Relevance: Shared pastoral context, institutional history, and possibly direct collaboration or succession planning. - shared_curial_body Weight: 2 Description: Cardinals who served together in a Roman Curia congregation, dicastery, or council. Relevance: Indicates direct collaboration on Church governance, reform agendas, or doctrinal oversight. - episcopal_lineage Weight: 3 Description: One cardinal consecrated the other as a bishop. Relevance: Denotes spiritual mentorship, hierarchical influence, and often a lasting personal relationship. - direct_successor Weight: 2.5 Description: One cardinal directly succeeded the other in a diocesan post. Relevance: Implies a close institutional link and often a continuation or shift in leadership style or priorities. - nuncio_overlap Weight: 1 Description: Cardinals who served in the Vatican diplomatic corps in the same or overlapping regions. Relevance: Exposure to common geopolitical and pastoral issues; may imply diplomatic collaboration or alignment. - co-consistory Weight: 0.5 Description: Cardinals created in the same consistory (i.e., elevated at the same ceremony). Relevance: Shared formative moment; cohort camaraderie. Useful for community/cohort modeling. - academic_alma_mater Weight: 1 Description: Cardinals who studied at the same seminary or Catholic university (e.g., Gregorian, Angelicum). Relevance: Intellectual and theological alignment; shared mentors or networks; formative ideological influence. - ideological_affinity Weight: variable / N/A Description: Cardinals aligned in public theology, liturgical orientation (e.g., progressive vs traditionalist), or Vatican politics. Relevance: Reflects real-world alliances in papal elections or policy debates, but harder to quantify objectively.
If I were doing this study in-depth myself, I would consider this to be phase one. I think GPT 4o in deep research mode did a great job blocking out a structure for us to build off of, but it’s not good at these super-verbose tasks that require a ton of repetitive work. Phase two would probably be to build custom parsing tools based on this outline, explore building separate parsers and LLM summarization techniques for different websites, and potentially massage some of the weights based on human intuition. We won’t do that in this article, but it is in line with a very common theme I see in industry: much of the power of LLMs isn’t in making decisions, it’s in cleaning up a lot of unstructured data so that developers can make decisions with more classical methods.
Prevost (The elected pope) isn’t even in the connections I got from GPT 4o, so we definitely won’t get the right answer, but we can explore what a graph looks like based on the data we have. The LLM chose to represent each connection as a dictionary with the following fields:
-
source
the node (cardinal) the connection is coming from -
target
the node (cardinal) the connection is going to -
type
a textual description of the nature of the connection -
weight
a number expressing the importance of the connection.
The LLM chose to define the weighting system accordingly:
Weighting System: 3 = strong link - episcopal_lineage (one cardinal consecrated the other) 2.5 = very strong link - direct_successor (one succeeded the other in a diocese) 2 = strong link - same_religious_order - shared_curial_body - same_diocese 1 = moderate link - same_appointing_pope - same_country - nuncio_overlap - academic_alma_mater 0.5 = weak link - same_continent - co-consistory variable / N/A = inferred or subjective strength - ideological_affinity
I’m not particularly religious, and know little about the social dynamics of the upper echelon of Catholicism, so I say good enough for government work. We can construct a graph based on the connections the LLM did provide to us, just to see what we might get.
As I covered in my article on graphs, we’ll be using networkx
as our library to construct a graph based on these edges. networkx
has a few types of graphs that can be used, I chose to use an undirected weighted graph (meaning each connection goes both ways, not just one way, the connections are weighted, and each pair of nodes has a single connection). In reality, two nodes can have multiple types of connections, which might be a good application for a multigraph (which allows multiple connections between two nodes). In networkx
, centrality calculations aren’t supported with multigraphs, so instead, I elected to aggregate all of the weights of all of the connections between two nodes, and used those to construct the graph.
import networkx as nx from collections import defaultdict # Step 1: Accumulate weights per (u, v) pair edge_weight_map = defaultdict(int) for edge in edges: u, v = edge["source"], edge["target"] weight = edge["weight"] # Ensure undirected consistency if u > v: u, v = v, u edge_weight_map[(u, v)] += weight # Step 2: Create a simple weighted graph G = nx.Graph() for (u, v), total_weight in edge_weight_map.items(): G.add_edge(u, v, weight=total_weight) # Draw with labels and edge weights (if graph is small) nx.draw(G, with_labels=True)

Now that we’ve constructed our graph, we can use networkx
to calculate eigenvector and betweenness centrality.
import matplotlib.pyplot as plt # Compute centrality metrics eigen_centrality = nx.eigenvector_centrality(G, weight='weight') betweenness_centrality = nx.betweenness_centrality(G, weight='weight') # Normalize centralities max_eigen = max(eigen_centrality.values()) max_betw = max(betweenness_centrality.values()) # Shared layout for consistency pos = nx.spring_layout(G, seed=42) # Start figure with two subplots fig, axes = plt.subplots(1, 2, figsize=(9, 4)) ### Left: Eigenvector Centrality (size) node_sizes_eigen = [10 + 1000 * (eigen_centrality[n] / max_eigen) for n in G.nodes] nx.draw_networkx_nodes(G, pos, ax=axes[0], node_size=node_sizes_eigen, node_color='skyblue') nx.draw_networkx_edges(G, pos, ax=axes[0], alpha=0.5) nx.draw_networkx_labels(G, pos, ax=axes[0], font_size=8) axes[0].set_title("Eigenvector Centrality (Node Size)") axes[0].axis('off') ### Right: Betweenness Centrality (size) node_sizes_betw = [10 + 1000 * (betweenness_centrality[n] / max_betw if max_betw != 0 else 0) for n in G.nodes] nx.draw_networkx_nodes(G, pos, ax=axes[1], node_size=node_sizes_betw, node_color='salmon') nx.draw_networkx_edges(G, pos, ax=axes[1], alpha=0.5) nx.draw_networkx_labels(G, pos, ax=axes[1], font_size=8) axes[1].set_title("Betweenness Centrality (Node Size)") axes[1].axis('off') plt.tight_layout() plt.show()
It’s a little hard to see exactly what’s going on here. Instead, we can go ahead and list out the top 5 cardinals for each metric.
# Sort and display top 5 by eigenvector centrality top_eigen = sorted(eigen_centrality.items(), key=lambda x: x[1], reverse=True)[:5] print("Top 5 by Eigenvector Centrality:") for name, score in top_eigen: print(f"{name}: {score:.4f}") print("nTop 5 by Betweenness Centrality:") top_betw = sorted(betweenness_centrality.items(), key=lambda x: x[1], reverse=True)[:5] for name, score in top_betw: print(f"{name}: {score:.4f}")
Naturally these results are dead wrong because the data we’re using is bogus, but I imagine if you put in the effort to curate sufficient data you would get a list that is more inline with what the researchers from Bocconi university got.
Conclusion
I’ve been using Graphs like crazy lately; from fraud detection to delivery route planning, they are an incredibly useful core data structure capable of efficiently modeling very complex systems.
I think a lot of people think “predicting who the pope will be” would be something for some fancy, deep-learning AI system, but simpler approaches remain incredibly powerful when the application is right. If anything, in my experience, the main job of LLMs is often to clean unstructured data so that it can be used to populate explicit data structures like graphs.
The researchers that inspired this article are quick to point out the limitations of their approach:
The Bocconi team is the first to point out the limitations of the model. “We do not claim to predict the outcome of the Conclave,” Soda points out. “As the great statistician George Box said: ‘All models are wrong, but some are useful.’ Ours is intended to be a tool for reading the context, not an oracle.”
On the other hand, history confirms how important relational dynamics are. Benedict XVI was at the center of the theological Curia. Francis, on the other hand, arrived as an outsider: “from the end of the world,” and also on the margins of the ecclesiastical network, as the model would have shown at the time. — Source
It’s worth noting that many other researchers used many different approaches to come up with many different predictions (example). One of them had to be right, and just because this approach was right this time doesn’t mean it will be in the future.
Regardless, the fact that the true pope was placed at the top of the list was pretty interesting, and highlights the power of graphs in analyzing social networks.