Appearance
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, moderateWith 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 libraryReport 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 signs | Balanced? | Reading |
|---|---|---|
| +,+,+ | yes | mutual allies |
| +,-,- | yes | common enemy unites two |
| +,+,- | no | unstable; friend of friend is enemy |
| -,-,- | no | all-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?
| Tool | Signed support |
|---|---|
R signnet | balance, signed centrality, blockmodels |
Python networkx | manual sign attribute + custom code |
igraph | signed community detection |
| Gephi | colour 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/igraphwith 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.