Skip to content
Network Analysis of Sources

When modelling signed and hostile ties — alliances versus enmities — the errors almost always come from collapsing sign into strength and then running tools that silently assume every edge is positive. The fix is to store the sign (+1 ally, -1 enemy) as its own attribute and use signed-aware methods or split the graph into positive and negative subgraphs. Here is how to diagnose the common failures and repair them so the analysis holds.

How do I represent a hostile tie in the first place? ​

The root mistake is encoding hostility as a small or zero weight, which conflates "weak alliance" with "strong enmity". Keep sign and strength separate:

python
import networkx as nx
G = nx.Graph()
G.add_edge("Florence", "Milan", sign=-1, strength=3)   # hostile, intense
G.add_edge("Florence", "Venice", sign=+1, strength=2)  # allied, moderate

With sign as its own attribute you can filter, weight, and measure positive and negative ties independently — which every downstream fix depends on.

Why does standard centrality give nonsense here? ​

Classic centrality (degree, betweenness, eigenvector) assumes edges are positive ties. Feed it a signed graph and an enemy connection counts the same as an ally, so a state surrounded by hostility looks "well-connected" and important. Symptom: your most embattled actor tops the centrality table.

Two reliable fixes:

python
# 1. analyse the positive and negative subgraphs separately
pos = G.edge_subgraph([(u, v) for u, v, s in G.edges(data="sign") if s > 0])
neg = G.edge_subgraph([(u, v) for u, v, s in G.edges(data="sign") if s < 0])
# 2. or use a signed-aware measure (e.g. PN centrality) from a signed library

Report alliance centrality and hostility centrality as distinct quantities; never blend them.

What is structural balance and why measure it? ​

Structural balance theory formalises "the enemy of my enemy is my friend." A triangle is balanced if it has an even number of negative edges (0 or 2). A signed system full of balanced triangles is stable; one full of imbalanced triangles is under tension and likely to realign — historically, a powerful predictor of shifting alliances.

Triangle signsBalanced?Reading
+,+,+yesmutual allies
+,-,-yescommon enemy unites two
+,+,-nounstable; friend of friend is enemy
-,-,-noall-hostile; tension

Compute the fraction of balanced triangles to summarise systemic stability over time.

How do I handle a tie that is both ally and rival? ​

Ambivalent relationships — allies who also compete — break a single-sign model. Do not force them to one sign. Either store two parallel edges (one +1, one -1) in a MultiGraph, or use a continuous sign in [-1, +1] and document the coding rule. Whatever you choose, write the rule down and ideally have a second coder apply it; ambivalence handled by gut feeling is not reproducible.

Which tools actually support signed networks? ​

ToolSigned support
R signnetbalance, signed centrality, blockmodels
Python networkxmanual sign attribute + custom code
igraphsigned community detection
Gephicolour edges by sign (no balance)

For balance and signed clustering, signnet in R is the most complete; for pipeline integration, custom sign handling on top of networkx is common.

How do I detect communities when ties are signed? ​

Ordinary modularity ignores sign, so it happily places sworn enemies in one "community" because they interact a lot. Use signed modularity or correlation clustering, which rewards positive ties within a group and negative ties between groups. The result aligns with how historians actually think about blocs and coalitions.

Key Takeaways ​

  • Store sign as its own attribute (+1/-1), separate from tie strength.
  • Standard centrality assumes positive edges — split into positive/negative subgraphs or use signed-aware measures.
  • Measure structural balance (even number of negatives per triangle) to gauge systemic stability.
  • Model ambivalent ties with parallel edges or a continuous sign plus a documented coding rule.
  • Use signnet (R) for balance and signed clustering; networkx/igraph with custom handling otherwise.
  • Detect blocs with signed modularity, not ordinary modularity, which ignores hostility.

Frequently Asked Questions ​

How do I represent a hostile tie in a network? ​

Store the sign as a separate edge attribute, conventionally weight = +1 for alliance and -1 for hostility, rather than mixing strength and sign into one number. This keeps positive and negative ties analysable independently.

Why does standard centrality give odd results on signed networks? ​

Most centrality measures assume all edges are positive, so they treat an enemy tie as just another connection and inflate the importance of conflict-ridden nodes. Use signed-aware measures or analyse the positive and negative subgraphs separately.

What is structural balance and why does it matter? ​

Structural balance theory predicts that 'the enemy of my enemy is my friend': triangles with an even number of negative ties are balanced. Measuring balance tells you whether your alliance system is stable or under tension.

How do I handle a tie that is both ally and rival? ​

Ambivalent relationships need either two parallel edges (one positive, one negative) or a continuous sign scale, plus a documented coding rule, because forcing them to a single sign erases real historical complexity.

Which tools support signed networks? ​

The signnet R package and Python's networkx with custom sign handling both work; igraph supports signed community detection. Gephi can colour edges by sign for visualisation but does not compute balance natively.

How do I detect communities in a signed network? ​

Use signed modularity or correlation-based clustering that rewards positive ties inside groups and negative ties between them, rather than ordinary modularity, which ignores sign entirely.