---
title: "Day 10: Latent Geometry and AME"
subtitle: "From Distance Maps to Changing Relationship Profiles"
author: "Shahryar Minhas"
engine: knitr
editor: source
format:
  revealjs:
    theme: [simple, day10_teaching_shell.scss]
    slide-number: c/t
    transition: fade
    controls: true
    progress: true
    hash: true
    center: false
    width: 1600
    height: 900
    margin: 0.055
    embed-resources: true
---

```{r}
#| label: deck-setup
#| include: false
#| warning: false
#| message: false
library(ggplot2)
library(ggrepel)
library(lame)
stopifnot(packageVersion("lame") >= "1.3.4")
library(netify)
library(sna)
source("basicHelpers.R")
theme_set(
  theme_minimal(base_size = 17) +
    theme(
      plot.title = element_text(color = "#18453B", face = "bold"),
      axis.title = element_text(color = "#18453B"),
      panel.grid.minor = element_blank()
    )
)
```

## Where Today Starts {#where-today-starts}

Day 9 represented unobserved relationship patterns in two ways:

:::: {.comparison-row}
::: {.comparison-card}
[Additive Effects]{.card-title}

The SRM asked whether some actors repeatedly appear across many relationships and whether the two directions of a pair remain connected.
:::
::: {.comparison-card .accent-card}
[Discrete Roles]{.card-title}

Blockmodels asked whether partner lists can be summarized by a few recurring patterns.
:::
::::

::: {.bottom-line}
Today asks whether one particular pairing can have its own history after accounting for actors that appear across many relationships.
:::

::: {.slide-link}
[Open Today’s Starting Point](day10_latent.html#sec-where){.walkthrough-link target="_blank"}
:::

## Two Questions Organize the Day {#two-questions}

:::: {.comparison-row}
::: {.comparison-card}
[Syrian Armed Organizations]{.card-title}

Was tactical cooperation scattered across unrelated pairs, or concentrated among organizations with overlapping sets of partners?
:::
::: {.comparison-card .accent-card}
[Changing State-Pair Relationships]{.card-title}

When high-volume conflictual relationships change, does a state become more involved across many relationships, or do particular directed relationships change in their own ways?
:::
::::

::: {.say-it}
The model comes after the relationship and the question are clear.
:::

::: {.slide-link}
[Connect the Questions to the Models](day10_latent.html#sec-political-question){.walkthrough-link target="_blank"}
:::

## What Might the Missing Pattern Represent? {#missing-pattern}

The same latent term can do very different jobs:

- Summarize unmeasured proximity between actors
- Represent complementary source and target roles
- Help the model handle connected observations
- Measure a relationship pattern we want to study

::: {.bottom-line}
A useful map does not automatically reveal ideology, rivalry, or another named trait. The model finds a pattern; we still have to justify its meaning.
:::

::: {.slide-link}
[Separate the Possible Meanings](day10_latent.html#sec-political-question){.walkthrough-link target="_blank"}
:::

## The Models Answer Different Questions {#model-compass}

| Model | Question | What It Lets Us Say |
|---|---|---|
| SRM | Are some actors involved across many relationships, regardless of partner? | Broad involvement can change even when we do not know which bilateral relationship changed |
| Distance | Is cooperation concentrated among organizations with overlapping partner lists? | Organizations with similar overall cooperation patterns are placed near one another |
| Factor | Can actors play similar or complementary parts without belonging to one group? | Actors can engage the same kinds of partners without engaging one another |
| AME | Is change spread across all of a state's relationships or concentrated in particular directed pairs? | Broad state involvement and the history of a particular ordered pair are separated |

::: {.slide-link}
[Use the Applied Model Compass](day10_latent.html#sec-model-compass){.walkthrough-link target="_blank"}
:::

## A Distance Model Starts With One Claim {#distance-claim}

::: {.big-claim}
Pairs placed closer together in the fitted latent space have a higher probability of a tie.
:::

$$
\operatorname{logit}\Pr(Y_{ij}=1)
=\alpha+x_{ij}^{\mathsf T}\beta-\lVert z_i-z_j\rVert
$$

The model runs a familiar idea backward: ties go in, and positions that make those ties plausible come out.

::: {.slide-link}
[Build the Distance Intuition](day10_latent.html#sec-idea){.walkthrough-link target="_blank"}
:::

## Read the Distance Equation in Pieces {#distance-equation}

:::: {.metric-row}
::: {.metric-card}
[Baseline]{.metric-label}

**$\alpha$**

Overall tendency for pairs to connect
:::
::: {.metric-card}
[Measured Features]{.metric-label}

**$x_{ij}^{\mathsf T}\beta$**

Observed pair or actor information
:::
::: {.metric-card}
[Hidden Distance]{.metric-label}

**$\lVert z_i-z_j\rVert$**

How far apart the fitted positions are
:::
::: {.metric-card}
[Tie Probability]{.metric-label}

**$\operatorname{logit}^{-1}(\eta_{ij})$**

The result on a zero-to-one scale
:::
::::

::: {.slide-link}
[Read the Model Carefully](day10_latent.html#sec-idea){.walkthrough-link target="_blank"}
:::

## What Makes One Fitted Map Better Than Another? {#distance-likelihood}

$$
p(Y\mid Z,\alpha,\beta)
=\prod_{i<j}p_{ij}^{y_{ij}}(1-p_{ij})^{1-y_{ij}}
$$

- An observed tie rewards a map that gives the pair a high $p_{ij}$.
- An observed non-tie rewards a map that gives the pair a low $p_{ij}$.
- Moving one actor changes its distance from everyone else, so the model must compromise across the whole partner list.
- The posterior combines this likelihood with priors on the coefficients, positions, and their spread.

::: {.say-it}
One tie does not place two actors. Their complete patterns of ties and non-ties determine where the model can put them.
:::

::: {.slide-link}
[See What the Distance Likelihood Rewards](day10_latent.html#what-the-distance-likelihood-rewards){.walkthrough-link target="_blank"}
:::

## Estimation Runs the Distance Story Backward {#estimation-story}

We observe who relates to whom. The estimator searches for coefficients and actor positions that make the complete pattern plausible.

1. Define the outcome, risk set, predictors, and map dimension.
2. Start with provisional coefficients and positions.
3. Compare their fitted probabilities with every tie and non-tie.
4. Update the coefficients and positions in turn.
5. Retain many plausible states rather than only one map.

::: {.say-it}
The posterior says what is being learned. MCMC says how the computer explores it.
:::

::: {.slide-link}
[Walk Through Distance-Model Estimation](day10_latent.html#sec-estimation-roadmap){.walkthrough-link target="_blank"}
:::

## What the Distance Posterior Represents {#distance-posterior}

$$
p(\alpha,\beta,Z,\Sigma\mid Y,X)
\propto
\underbrace{p(Y\mid X,\alpha,\beta,Z)}_{\text{network fit}}
\times
\underbrace{p(\alpha,\beta,Z,\Sigma)}_{\text{prior structure}}
$$

- $\alpha$ and $\beta$ describe the baseline and measured associations.
- $Z$ contains the actor positions.
- $\Sigma$ describes how dispersed those positions can be.
- The likelihood rewards ties with high probabilities and non-ties with low probabilities.

::: {.bottom-line}
The posterior contains many plausible maps and coefficient values, weighted by how well they explain the network and how plausible they are under the prior.
:::

## How MCMC Explores the Posterior {#latent-mcmc}

Imagine reconstructing a seating chart from observed relationships:

1. Begin with provisional positions, coefficients, and variance quantities.
2. Hold the positions fixed and update the other model pieces.
3. Hold those pieces fixed and move actors using their complete partner lists.
4. Record the complete current explanation and repeat.

::: {.bottom-line}
A posterior draw is one plausible explanation of the same observed network. It is not a new network or a new set of actors.
:::

::: {.slide-link}
[Work Through the MCMC Updates](day10_latent.html#sec-latent-mcmc){.walkthrough-link target="_blank"}
:::

## Diagnostics Answer a Narrow Question {#diagnostics}

:::: {.comparison-row}
::: {.comparison-card}
[What They Can Tell Us]{.card-title}

- Whether retained draws stay in a stable region
- Whether independent chains agree
- How much independent Monte Carlo information we have
- Whether fitted distances and probabilities agree across chains
:::
::: {.comparison-card .accent-card}
[What They Cannot Tell Us]{.card-title}

- Whether the distance model is a good account of the process
- Whether an omitted process is independent of a predictor
- Whether a displayed axis has a substantive meaning
- Whether an association is causal
:::
::::

::: {.slide-link}
[Read the MCMC Diagnostic Guide](day10_latent.html#sec-latent-mcmc){.walkthrough-link target="_blank"}
:::

## Distance Buys Clustering and Imposes a Restriction {#distance-tradeoff}

:::: {.comparison-row}
::: {.comparison-card}
[What It Buys]{.card-title}

If actor $i$ is near both $j$ and $k$, then $j$ and $k$ cannot be arbitrarily far apart. Clustered ties and triangles become more likely.
:::
::: {.comparison-card .accent-card}
[What It Imposes]{.card-title}

One map ties similar relationship profiles to direct proximity. That can be awkward when actors play the same role but do not connect to one another.
:::
::::

::: {.bottom-line}
The geometry raises the probability of clustered ties. It does not make closure deterministic.
:::

::: {.slide-link}
[See What Distance Assumes](day10_latent.html#sec-idea){.walkthrough-link target="_blank"}
:::

## The Gade Application Uses Recorded Joint Operations {#gade-data}

:::: {.metric-row}
::: {.metric-card}
[Organizations]{.metric-label}

**31**

Syrian armed organizations
:::
::: {.metric-card}
[Period]{.metric-label}

**2012 to 2015**

July through June
:::
::: {.metric-card}
[Cooperative Pairs]{.metric-label}

**86**

Pairs with at least one joint operation
:::
::: {.metric-card}
[Density]{.metric-label}

**18.5%**

Share of possible undirected pairs
:::
::::

Gade et al. (2019) provide the cooperation data.

::: {.slide-link}
[Meet the Gade Cooperation Network](day10_latent.html#sec-cameo){.walkthrough-link target="_blank"}
:::

## This Is a Focused Reanalysis, Not a Replication {#gade-boundary}

- An undirected tie means at least one recorded joint operation during the full period.
- An operation involving several organizations creates several pair ties.
- The original article models a square-root count outcome; today uses a binary whole-period projection.
- A tie means recorded tactical cooperation, not ideological agreement or a stable coalition.

::: {.bottom-line}
The fitted map summarizes this coded network. It does not recover every changing relationship during the Syrian conflict.
:::

::: {.slide-link}
[Read the Gade Data Boundary](day10_latent.html#sec-cameo){.walkthrough-link target="_blank"}
:::

## Fitting the Gade Map Is a Repeated Conditional Update {#gade-fit}

1. Choose a two-dimensional Euclidean space.
2. Start with provisional organization positions and an intercept.
3. Update the intercept given the current positions.
4. Update positions given the current intercept and observed ties.
5. Repeat, discard burn-in, and retain 4,000 draws.
6. Align equivalent maps before summarizing positions.

::: {.say-it}
Two dimensions make the result readable. They are a modeling choice, not a fact the data discovered for us.
:::

::: {.slide-link}
[Fit the Gade Distance Model](day10_latent.html#sec-cameo){.walkthrough-link target="_blank"}
:::

## Check the Chain Before Reading the Map {#gade-diagnostics}

The focused check follows two quantities that do not change when the map rotates:

- The intercept, which controls the baseline tie tendency at zero distance
- The latent-position variance, which describes how spread out the map is

In the matching seeded run, both effective sample sizes exceed 1,500.

::: {.mini-caution}
Use coefficient traces together with fitted distances and probabilities. Those are the quantities we eventually interpret.
:::

::: {.slide-link}
[Inspect the Gade MCMC Output](day10_latent.html#sec-cameo){.walkthrough-link target="_blank"}
:::

## Read the Gade Map as a Probability Surface {#gade-map}

:::: {.comparison-row}
::: {.comparison-card}
[A Defensible Reading]{.card-title}

Organizations placed near one another recorded joint operations with many of the same partners, so the model gives pairs in that part of the map a higher chance of a tie.
:::
::: {.comparison-card .accent-card}
[An Overreach]{.card-title}

The first axis is ideology, the second is power, or a nearby pair necessarily formed a stable coalition.
:::
::::

::: {.bottom-line}
One joint operation does not determine two positions. Every organization’s full pattern of ties contributes to the map.
:::

::: {.slide-link}
[Open the Fitted Gade Map](day10_latent.html#sec-cameo){.walkthrough-link target="_blank"}
:::

## Does the Geometry Reproduce the Observed Clustering? {#gade-fit-check}

:::: {.metric-row}
::: {.metric-card}
[Independent Baseline]{.metric-label}

**18.5%**

Expected weak transitivity near network density
:::
::: {.metric-card}
[Distance Simulations]{.metric-label}

**28.7%**

Average across replicated networks
:::
::: {.metric-card}
[Observed Network]{.metric-label}

**35.7%**

Weak transitivity in the Gade projection
:::
::: {.metric-card}
[Predictive Interval]{.metric-label}

**17.4% to 39.0%**

Variation across replications
:::
::::

::: {.bottom-line}
The fitted geometry reproduces much of the clustering. It does not show that one joint operation caused another tie to close.
:::

::: {.slide-link}
[Run the Gade Fit Check](day10_latent.html#sec-cameo){.walkthrough-link target="_blank"}
:::

## What the Gade Map Adds {#gade-tldr}

::: {.final-claim}
Al-Nusrah Front and Ahrar al-Sham Islamic Movement sit in the same tightly connected part of the map. They recorded an operation with one another, and each also recorded operations with 18 of the same other organizations. The map reproduces much of the observed clustering, but it mainly reinforces Day 9's tactical-core finding rather than supplying a new explanation. We use it to understand the distance model and then move on.
:::

What we would report:

- The relationship and period
- The two-dimensional distance assumption
- Sampling diagnostics
- Invariant distances or fitted probabilities
- Posterior predictive performance and remaining uncertainty

::: {.slide-link}
[Review the Complete Gade Interpretation](day10_latent.html#sec-cameo){.walkthrough-link target="_blank"}
:::

## Distance Becomes Awkward for Complementary Roles {#distance-foil}

Suppose two groups mostly connect across groups:

:::: {.comparison-row}
::: {.comparison-card}
[The Relationship Pattern]{.card-title}

Members of the same group have similar partner profiles because they connect to the other group.
:::
::: {.comparison-card .accent-card}
[The Distance Tension]{.card-title}

Similar profiles encourage similar positions, but similar positions also raise their direct tie probability.
:::
::::

::: {.say-it}
The problem is not that distance can never approximate the pattern. The problem is that a small Euclidean map represents it inefficiently.
:::

::: {.slide-link}
[See Where the Distance Map Struggles](day10_latent.html#sec-foil){.walkthrough-link target="_blank"}
:::

## A Longer Run Cannot Repair the Wrong Representation {#computation-or-model}

Ask two questions in order:

1. **Did the sampler explore the fitted model?** Check the trace, effective sample size, and stability across starts.
2. **Can the fitted model represent the pattern economically?** Compare observed and fitted features after the computational check passes.

::: {.bottom-line}
When a longer, well-mixed run reproduces the same miss, the limitation belongs to the model’s geometry rather than the chain length.
:::

::: {.slide-link}
[Separate Computation From Representation](day10_latent.html#sec-foil){.walkthrough-link target="_blank"}
:::

## The Geometry Itself Was Chosen {#geometry-choice}

Before seeing the network, we chose:

- Two dimensions
- A flat Euclidean space
- No curvature
- Distance as the relationship rule

::: {.say-it}
The plot is the fitted geometry conditional on those choices, not the one true map hidden inside the network.
:::

Dimension, geometry, and curvature require an argument and sensitivity checks (Lubold, Chandrasekhar, and McCormick 2023).

::: {.slide-link}
[Read the Deeper Geometry Caution](day10_latent.html#sec-geometry-choice){.walkthrough-link target="_blank"}
:::

## Similarity Can Mean Two Different Things {#two-similarities}

:::: {.comparison-row}
::: {.comparison-card}
[Direct Proximity]{.card-title}

Two actors are similar because they are likely to connect to one another.

This is the natural distance-model story.
:::
::: {.comparison-card .accent-card}
[Similar Relationship Profiles]{.card-title}

Two actors are similar because they connect to the same kinds of partners, even if they do not connect to each other.

This is stochastic equivalence.
:::
::::

::: {.slide-link}
[Separate the Two Meanings of Similarity](day10_latent.html#sec-factor){.walkthrough-link target="_blank"}
:::

## Start With the Regression We Already Know {#regression-start}

For an ordered relationship from $i$ to $j$:

$$
g\!\left(E[Y_{ij}\mid\cdot]\right)
=\eta_{ij}
=\beta_0+\mathbf{x}_{ij}^{\mathsf T}\boldsymbol{\beta}.
$$

:::: {.comparison-row}
::: {.comparison-card}
[What Is Observed]{.card-title}

$Y_{ij}$ and the measured pair characteristics $\mathbf{x}_{ij}$
:::
::: {.comparison-card .accent-card}
[What Regression Estimates]{.card-title}

The baseline and coefficients that move the relationship score up or down
:::
::::

::: {.bottom-line}
The factor model keeps this outcome, link function, and linear predictor. It adds structure to the part ordinary regression leaves unexplained.
:::

::: {.slide-link}
[Build the Model From a Regression](day10_latent.html#sec-regression-bridge){.walkthrough-link target="_blank"}
:::

## The SRM Adds Broad Source and Target Differences {#regression-srm}

$$
\eta_{ij}
=\beta_0+\mathbf{x}_{ij}^{\mathsf T}\boldsymbol{\beta}
+a_i+b_j
$$

:::: {.comparison-row}
::: {.comparison-card}
[Source Effect $a_i$]{.card-title}

Moves every relationship beginning with actor $i$
:::
::: {.comparison-card .accent-card}
[Target Effect $b_j$]{.card-title}

Moves every relationship aimed at actor $j$
:::
::::

::: {.say-it}
These terms explain why a row or column is broadly high. They cannot explain why one particular source-target combination is high and another involving the same source is low.
:::

::: {.slide-link}
[See What the Additive Terms Cannot Do](day10_latent.html#sec-regression-bridge){.walkthrough-link target="_blank"}
:::

## A Factor Is an Interaction With Unknown Inputs {#regression-interaction}

If source capability $c_i$ and target vulnerability $r_j$ are measured, and their main effects are already in $\mathbf{x}_{ij}$, an ordinary regression can include

$$
\delta\,c_i r_j.
$$

The rank-one factor model uses the same multiplication:

$$
\delta\,u_i v_j,
$$

but $u_i$ and $v_j$ are not measured variables. The model learns them from repeated source-target patterns in the relationship matrix.

::: {.bottom-line}
Observed interaction: multiply two known characteristics. Latent interaction: estimate the two characteristics and their product together with the rest of the model.
:::

::: {.slide-link}
[Move From a Measured to a Latent Interaction](day10_latent.html#sec-regression-bridge){.walkthrough-link target="_blank"}
:::

## One Source Can Fit Two Targets Differently {#regression-numeric}

With one latent dimension and $\delta=1$:

|  | Target C: $v_C=1.5$ | Target D: $v_D=-2$ |
|---|---:|---:|
| Source A: $u_A=2$ | $2(1.5)=3$ | $2(-2)=-4$ |
| Source B: $u_B=-1$ | $-1(1.5)=-1.5$ | $-1(-2)=2$ |

::: {.say-it}
Actor A does not have one universally positive factor effect. Its contribution is positive with C and negative with D. This is pair-specific fit, not broad source activity.
:::

::: {.slide-link}
[Work Through the Rank-One Example](day10_latent.html#sec-regression-bridge){.walkthrough-link target="_blank"}
:::

## Rank Is the Number of Latent Interactions {#regression-rank}

$$
\eta_{ij}
=\beta_0+\mathbf{x}_{ij}^{\mathsf T}\boldsymbol{\beta}+a_i+b_j
+\underbrace{\sum_{r=1}^{R}\delta_r u_{ir}v_{jr}}_{\text{\(R\) latent interactions}}
$$

Equivalently,

$$
\eta_{ij}
=\beta_0+\mathbf{x}_{ij}^{\mathsf T}\boldsymbol{\beta}+a_i+b_j
+\mathbf{u}_i^{\mathsf T}D\mathbf{v}_j.
$$

::: {.bottom-line}
If $U$ and $V$ were known, their products could enter a regression like ordinary interaction predictors. The hard part is estimating those unknown profiles jointly with everything else.
:::

::: {.slide-link}
[See the Full Regression Derivation](day10_latent.html#sec-regression-bridge){.walkthrough-link target="_blank"}
:::

## A Movie Matrix Makes the Factor Idea Visible {#movie-matrix}

| Viewer | Star Wars | Alien | Blade Runner | Casablanca | Pretty Woman |
|---|---:|---:|---:|---:|---:|
| Mike | 1 | 1 | 1 | 0 | 0 |
| Cindy | 3 | 3 | 3 | 0 | 0 |
| Hyerin | 4 | 4 | 4 | 0 | 0 |
| Emily | 5 | 5 | 5 | 0 | 0 |
| Cassy | 0 | 2 | 0 | 4 | 4 |
| Juan | 0 | 0 | 0 | 5 | 5 |
| Max | 0 | 1 | 0 | 2 | 2 |

::: {.bottom-line}
Instead of explaining 35 scores separately, can a few repeated viewer and movie profiles reconstruct almost all of the matrix?
:::

Zero is a recorded score in this toy example. It is not a missing value.

::: {.slide-link}
[Work Through the Movie Matrix](day10_latent.html#sec-svd-movies){.walkthrough-link target="_blank"}
:::

## SVD Separates Rows, Columns, and Pattern Strength {#svd-pieces}

$$
M=UDV^{\mathsf T}
$$

:::: {.metric-row}
::: {.metric-card}
[Viewer Profiles]{.metric-label}

**Rows of $U$**

How each viewer loads on the shared directions
:::
::: {.metric-card}
[Movie Profiles]{.metric-label}

**Rows of $V$**

How each movie loads on the same directions
:::
::: {.metric-card}
[Pattern Strength]{.metric-label}

**Diagonal of $D$**

How much squared matrix magnitude each direction reconstructs
:::
::::

::: {.slide-link}
[See What the SVD Separates](day10_latent.html#sec-svd-movies){.walkthrough-link target="_blank"}
:::

## Rank Two Nearly Reconstructs the Movie Matrix {#svd-reconstruction}

:::: {.comparison-row}
::: {.comparison-card}
[What We Keep]{.card-title}

Two repeated row-column directions rather than 35 unrelated cell explanations
:::
::: {.comparison-card .accent-card}
[What We Recover]{.card-title}

**99.3%** of the squared magnitude of the uncentered matrix, with an RMSE of **0.227**
:::
::::

::: {.mini-caution}
This is squared matrix magnitude, not automatically “variance explained,” because the matrix was not centered. It also does not prove that two psychological traits generated the ratings.
:::

::: {.slide-link}
[Compare the Matrix and Its Reconstruction](day10_latent.html#sec-svd-movies){.walkthrough-link target="_blank"}
:::

## Every Fitted Cell Is a Compatibility Score {#svd-cell}

Split each singular value across the two sides:

$$
P=U_RD_R^{1/2},\qquad Q=V_RD_R^{1/2},\qquad \widehat m_{ij}=\mathbf p_i^{\mathsf T}\mathbf q_j.
$$

For Emily and Star Wars:

$$
\widehat m_{\text{Emily, Star Wars}}
=p_{\text{Emily},1}q_{\text{Star Wars},1}
+p_{\text{Emily},2}q_{\text{Star Wars},2}.
$$

::: {.bottom-line}
The same viewer coordinate can raise one fitted score and do little for another because it is always multiplied by the movie’s coordinate. That pair-specific product is what separate viewer and movie intercepts cannot supply.
:::

::: {.slide-link}
[Read the Cell Products](day10_latent.html#sec-svd-movies){.walkthrough-link target="_blank"}
:::

## Carry the Same Product Into a Directed Network {#svd-network}

In a directed network, the same actors appear on both sides of the matrix, but the jobs differ:

$$
z_{ij}\approx u_i^{\mathsf T}v_j.
$$

:::: {.comparison-row}
::: {.comparison-card}
[Source Profile $u_i$]{.card-title}

Which targets repeatedly appear in actor $i$’s outgoing relationship pattern
:::
::: {.comparison-card .accent-card}
[Target Profile $v_j$]{.card-title}

Which sources repeatedly appear in actor $j$’s incoming relationship pattern
:::
::::

The product says whether this particular source profile fits this particular target profile. Additive effects still handle broad source activity and target exposure.

::: {.slide-link}
[Move From Movies to Networks](day10_latent.html#sec-svd-network){.walkthrough-link target="_blank"}
:::

## SVD Gives the Scaffold, Not the Network Fit {#svd-scaffold}

| Truncated SVD | Latent Factor or AME Model |
|---|---|
| Minimizes squared reconstruction error | Fits a likelihood or posterior for the outcome |
| Treats every supplied cell as observed | Defines missing dyads, structural zeros, and the risk set |
| Has no predictors or actor effects | Can include predictors, additive actor effects, and reciprocity |
| Produces a point decomposition | Can quantify uncertainty |

::: {.say-it}
We do not run `svd()` on an adjacency matrix and call it AME. SVD shows why low-rank products compress repeated row-column patterns. The probability model estimates that surface together with everything else.
:::

::: {.slide-link}
[Separate the Scaffold From the Estimator](day10_latent.html#sec-svd-network){.walkthrough-link target="_blank"}
:::

## The Factor Term Adds Compatibility {#factor-term}

For a directed relationship:

$$
\gamma(u_i,v_j)=u_i^{\mathsf T}v_j
$$

Multiply matching coordinates and add them:

- A large positive result raises the fitted relationship score.
- A value near zero adds little.
- A negative result lowers the score.

::: {.bottom-line}
Distance says “near or far.” A factor surface can also represent compatible opposites and recurring source-target roles.
:::

::: {.slide-link}
[Build the Multiplicative Term](day10_latent.html#sec-factor){.walkthrough-link target="_blank"}
:::

## What Factor-Model Estimation Learns {#factor-estimation}

The model learns these pieces together:

- $\beta$: associations with measured predictors
- $a_i$ and $b_j$: actors that are broadly high as sources or targets
- $U$ and $V$: recurring source-target compatibility patterns
- Variance and reciprocity parameters: remaining dependence and uncertainty

$$
p(\beta,a,b,U,V,\Sigma\mid Y,X)
\propto
p(Y\mid X,\beta,a,b,U,V,\Sigma)\,p(\beta,a,b,U,V,\Sigma)
$$

For a probit AME model, the sampler first represents each zero or one with a latent continuous relationship score. Given those scores, it cycles through regression, actor-effect, factor, and variance updates.

::: {.bottom-line}
The target is a joint posterior for all model pieces. SVD explains the low-rank scaffold, but one SVD of the adjacency matrix is not an AME estimate.
:::

::: {.slide-link}
[Follow the Factor-Model Updates](day10_latent.html#sec-factor-estimation){.walkthrough-link target="_blank"}
:::

## Eigenvalue Signs Describe the Symmetric Surface {#eigenvalue-signs}

For a symmetric eigenmodel:

$$
\gamma(u_i,u_j)=u_i^{\mathsf T}\Lambda u_j
$$

| Sign of $\lambda_r$ | What That Component Represents |
|---|---|
| Positive | Similar scores receive a positive contribution, an assortative pattern |
| Negative | Opposite scores receive a positive contribution, a disassortative pattern |
| Mixed signs | Both relationship patterns are present in the fitted surface |

::: {.mini-caution}
The sign describes a fitted component. It does not identify the social mechanism that generated the network.
:::

::: {.slide-link}
[Read the Eigenmodel Carefully](day10_latent.html#sec-factor){.walkthrough-link target="_blank"}
:::

## The Planted Simulations Show Why the Sign Matters {#eigen-demo}

:::: {.comparison-row}
::: {.comparison-card}
[Distance-Generated Network]{.card-title}

Both fitted weights are positive. The factor model sees the assortative pattern planted by proximity.
:::
::: {.comparison-card .accent-card}
[Across-Group Network]{.card-title}

The dominant fitted weight is large and negative. The factor model captures the complementary role pattern that the two-dimensional distance map missed.
:::
::::

::: {.bottom-line}
This is an illustration of representational flexibility, not proof that one model wins on every dataset.
:::

::: {.slide-link}
[Run the Eigenvalue-Sign Demonstration](day10_latent.html#sec-eigen){.walkthrough-link target="_blank"}
:::

## Choose the Representation That Matches the Question {#model-choice}

| Use This | When This Is the Defensible Starting Point |
|---|---|
| Distance model | Proximity is meaningful, a parsimonious map matters, and role mixing is not central |
| Factor or eigenmodel | Similar and complementary roles may both shape ties |
| Full AME | Measured predictors, broad actor tendencies, reciprocity, and pair profiles all matter |

Check prediction, posterior reproduction, stability, and interpretability. A more flexible model has to earn the extra complexity.

::: {.slide-link}
[Compare Distance and Factor Representations](day10_latent.html#sec-eigen){.walkthrough-link target="_blank"}
:::

## Same Data, A More Specific Question {#icews-question}

Day 9 used the ICEWS panel to ask which states appeared in many above-threshold relationships as the coded source or target.

Day 10 asks what the additive scores could not:

::: {.final-claim}
When a high-volume conflictual relationship changes, is the change spread across many partners or concentrated in a particular directed state pair?
:::

The outcome equals one when an ordered state pair has more than 20 coded material-conflict events in a year. It measures high coded event volume, not conflict initiation or severity.

::: {.slide-link}
[Return to the ICEWS Question](day10_latent.html#sec-icews-data){.walkthrough-link target="_blank"}
:::

## There Is Enough Movement to Ask {#icews-movement}

:::: {.metric-row}
::: {.metric-card}
[Panel]{.metric-label}

**18 states**

13 annual directed networks
:::
::: {.metric-card}
[Ordered Pair-Years]{.metric-label}

**3,978**

No self-pairs
:::
::: {.metric-card}
[Threshold Crossings]{.metric-label}

**244**

Move from zero to one
:::
::: {.metric-card}
[Threshold Exits]{.metric-label}

**218**

Move from one to zero
:::
::::

::: {.bottom-line}
A dynamic model needs observed change, not merely time-varying parameters. The 462 status changes give it something to learn.
:::

::: {.slide-link}
[Inspect the Data and Changes](day10_latent.html#sec-icews-data){.walkthrough-link target="_blank"}
:::

## The Dynamic AME Keeps Five Jobs Separate {#dynamic-equation}

$$
Y^*_{ijt}
=\alpha_t+\mathbf{x}_{ijt}^{\mathsf T}\boldsymbol\beta
+a_{it}+b_{jt}
+\mathbf{u}_{it}^{\mathsf T}\mathbf{v}_{jt}
+e_{ijt}.
$$

| Piece | Job |
|---|---|
| $\alpha_t$ | Let the whole network become busier or quieter |
| $\mathbf{x}_{ijt}^{\mathsf T}\boldsymbol\beta$ | Account for Polity gap and same region |
| $a_{it}$ | Track whether events are coded from state $i$ across many partners |
| $b_{jt}$ | Track whether events are coded toward state $j$ across many partners |
| $\mathbf{u}_{it}^{\mathsf T}\mathbf{v}_{jt}$ | Track whether this exact directed pair is unusually likely after those broad patterns |

::: {.slide-link}
[Walk Through Every Model Piece](day10_latent.html#sec-fits){.walkthrough-link target="_blank"}
:::

## Broad Involvement Is Not a Bilateral Relationship {#dynamic-distinction}

:::: {.comparison-row}
::: {.comparison-card}
[Additive Paths]{.card-title}

$a_{it}$ and $b_{jt}$ answer whether ICEWS records events from or toward a state across many different partners in a year.
:::
::: {.comparison-card .accent-card}
[Multiplicative Paths]{.card-title}

$\mathbf{u}_{it}^{\mathsf T}\mathbf{v}_{jt}$ asks whether one exact directed state pair is more or less likely to cross the threshold than those broad patterns imply.
:::
::::

::: {.say-it}
A state can appear with many partners without every particular relationship being equally likely. The two directions of one pair can also follow different paths.
:::

::: {.slide-link}
[Keep the Three Dynamic Pieces Separate](day10_latent.html#sec-dynamic-pieces){.walkthrough-link target="_blank"}
:::

## `netify` Keeps the Panel Aligned {#dynamic-netify}

`netify()` receives the ordered state-pair-year table and keeps the design choices visible:

1. `source` and `target` preserve direction.
2. `year` defines the 13 network slices.
3. `symmetric = FALSE` keeps Iran-Syria separate from Syria-Iran.
4. `missing_to_zero = FALSE` prevents an unobserved dyad from becoming a recorded zero.

`to_lame()` returns 13 aligned outcome matrices and 13 aligned predictor arrays.

::: {.slide-link}
[Build and Validate the Matrices](day10_latent.html#sec-icews-netify){.walkthrough-link target="_blank"}
:::

## What Dynamic ALS Is Trying to Do {#dynamic-als}

The estimator has two connected jobs:

1. Reconstruct which ordered state pairs cross the event threshold in each year.
2. Keep neighboring years connected unless the data support a sustained change.

The baseline, measured predictors, broad actor paths, and pair-specific factor surface divide the first job. Smoothing penalties handle the second.

::: {.bottom-line}
The model can let a state become active across many partners without treating every particular relationship as equally unusual.
:::

::: {.slide-link}
[See How the Estimator Works](day10_latent.html#sec-dynamic-als){.walkthrough-link target="_blank"}
:::

## What Dynamic ALS Minimizes {#dynamic-als-objective}

At each binary-response update, the estimator approximately minimizes

$$
\sum_{t,i\ne j}w_{ijt}(z_{ijt}-\widehat\eta_{ijt})^2
+\lambda_{ab}\,\text{actor jumps}
+\lambda_{uv}\,\text{factor jumps}
+\lambda_\alpha\,\text{intercept jumps}.
$$

1. Build a working response $z_{ijt}$ and weight $w_{ijt}$ from current probabilities.
2. Update coefficients, actor paths, and factor paths in turn.
3. Recalculate probabilities and repeat until the objective barely changes.

::: {.mini-caution}
This is a penalized point estimate, not an MCMC sample or a direct one-step maximization of the exact binary likelihood. The smoothing settings are fixed tuning values, and rank greater than zero creates possible local solutions.
:::

## The Actual `lame()` Call {#dynamic-call}

```r
fit_r2 <- lame(
  Y = Y_icews,
  Xdyad = X_icews,
  family = "binary",
  symmetric = FALSE,
  R = 2,
  dynamic_ab = TRUE,
  dynamic_uv = TRUE,
  dynamic_beta = "intercept",
  dynamic_beta_kind = "rw1",
  method = "als",
  als_stability = "validation",
  bootstrap = 100,
  seed = 6886
)
```

All four validation starts converged to essentially the same fitted probability surface. The 100 bootstrap refits also completed successfully.

::: {.slide-link}
[Open the Fit and Full Call](day10_latent.html#sec-dynamic-fit){.walkthrough-link target="_blank"}
:::

## Broad State Paths Come First {#dynamic-ab .dense-plot-slide}

```{r}
#| label: deck-dynamic-ab
#| echo: false
#| warning: false
#| message: false
#| fig-height: 6.3
#| fig-width: 10.5
#| out-width: "88%"
#| fig-alt: "Two stacked line charts show broad source-side and target-side adjustments for Iran, Russia, Syria, and the United States from 2002 to 2014. Color, line type, and point shape distinguish states."
load("cache/icews_dynamic_ame_r2_boot100_v1.rda")
years <- as.integer(fit_r2$time_names)
fit_r2_display <- fit_r2
display_names <- fit_r2$row_names
display_names[display_names == "Iran, Islamic Republic Of"] <- "Iran"
display_names[display_names == "Syrian Arab Republic"] <- "Syria"
display_names[display_names == "Korea, Republic Of"] <- "South Korea"
rownames(fit_r2_display$a_dynamic) <- display_names
rownames(fit_r2_display$b_dynamic) <- display_names
dimnames(fit_r2_display$U)[[1]] <- display_names
dimnames(fit_r2_display$V)[[1]] <- display_names
fit_r2_display$row_names <- display_names
fit_r2_display$col_names <- display_names
focus_states <- c(
  "United States", "Syria",
  "Iran", "Russian Federation"
)
state_colors <- c(
  "Syria" = "#18453B",
  "Russian Federation" = "#008208",
  "Iran" = "#7BBD00",
  "United States" = "#535054"
)
p_source <- lame::ab_plot(
  fit_r2_display,
  effect = "sender",
  plot_type = "trajectory",
  show_actors = focus_states,
  title = "Broad Source-Side Activity"
) +
  aes(linetype = actor, shape = actor) +
  scale_color_manual(values = state_colors, name = NULL) +
  scale_linetype_discrete(name = NULL) +
  scale_shape_discrete(name = NULL) +
  labs(x = "Year", y = "Source-side adjustment")
p_target <- lame::ab_plot(
  fit_r2_display,
  effect = "receiver",
  plot_type = "trajectory",
  show_actors = focus_states,
  title = "Broad Target-Side Exposure"
) +
  aes(linetype = actor, shape = actor) +
  scale_color_manual(values = state_colors, name = NULL) +
  scale_linetype_discrete(name = NULL) +
  scale_shape_discrete(name = NULL) +
  labs(x = "Year", y = "Target-side adjustment")
p_source / p_target
```

::: {.mini-caution}
Each line pools across all partners. It does not identify which relationship changed or why it changed.
:::

::: {.slide-link}
[Read the Additive Paths](day10_latent.html#sec-dynamic-ab){.walkthrough-link target="_blank"}
:::

## Then Ask Which Directed Relationships Changed {#dynamic-uv .dense-plot-slide}

```{r}
#| label: deck-dynamic-uv
#| echo: false
#| warning: false
#| message: false
#| fig-height: 6.2
#| fig-width: 11
#| out-width: "92%"
#| fig-alt: "Two biplots compare source and target relationship profiles in 2002 and 2014. Circles and colors distinguish source from target profiles, and labels identify Iran and Syria."
fit_r2_aligned <- align_directed_uv(fit_r2_display)
uv_snapshot <- function(tt) {
  p <- lame::uv_plot(
    fit_r2_aligned,
    plot_type = "snapshot",
    time_point = tt,
    label.nodes = FALSE,
    show_arrows = FALSE,
    title = years[tt]
  )
  focus_data <- p$data[p$data$name %in% c("Iran", "Syria"), ]
  focus_data$label <- paste0(
    focus_data$name,
    ifelse(focus_data$type == "Sender", " (source)", " (target)")
  )
  p +
    ggrepel::geom_text_repel(
      data = focus_data,
      aes(label = label),
      size = 3.2,
      max.overlaps = Inf,
      show.legend = FALSE
    ) +
    scale_color_manual(
      values = c(Sender = "#18453B", Receiver = "#7BBD00"),
      labels = c(
        Sender = "Source profile",
        Receiver = "Target profile"
      ),
      name = NULL
    ) +
    scale_shape_manual(
      values = c(Sender = 16, Receiver = 1),
      labels = c(
        Sender = "Source profile",
        Receiver = "Target profile"
      ),
      name = NULL
    )
}
patchwork::wrap_plots(
  lapply(c(1, 13), uv_snapshot),
  ncol = 2,
  guides = "collect"
) & theme(legend.position = "bottom")
```

::: {.mini-caution}
The axes can rotate and reflect. Use this as an overview, then interpret a named pair's inner product and fitted probability.
:::

::: {.slide-link}
[Read the Aligned Partner Profiles](day10_latent.html#sec-dynamic-uv){.walkthrough-link target="_blank"}
:::

## Rank Two Is a Practical Choice {#dynamic-rank}

| Rank | ROC AUC | Precision-Recall AUC | Brier |
|---:|---:|---:|---:|
| 0 | 0.825 | 0.676 | 0.118 |
| 1 | 0.837 | 0.694 | **0.113** |
| 2 | 0.837 | **0.695** | **0.113** |
| 3 | 0.833 | 0.686 | 0.116 |
| 4 | **0.839** | 0.687 | 0.115 |

The test hides both directions and all 13 years for each unordered pair.

::: {.bottom-line}
Ranks one and two are tied in held-pair prediction. We keep rank two because it improves temporal reproduction and gives a readable two-dimensional profile display. Higher rank does not earn a consistent gain.
:::

::: {.slide-link}
[Inspect the Complete-Pair Validation](day10_latent.html#sec-dynamic-rank){.walkthrough-link target="_blank"}
:::

## Direction and Timing Matter {#dynamic-pairs .dense-plot-slide}

```{r}
#| label: deck-dynamic-pairs
#| echo: false
#| warning: false
#| message: false
#| fig-height: 5.8
#| fig-width: 10.5
#| out-width: "88%"
#| fig-alt: "Four line charts show fitted probabilities for Iran toward Syria, Syria toward Iran, the United States toward Syria, and Syria toward the United States from 2002 to 2014. Iran-Syria probabilities rise sharply around 2011, while United States-Syria probabilities remain high. Ribbons show bootstrap intervals and point shape shows the observed outcome."
load("cache/icews_dynamic_data_v1.rda")
Y_icews <- summary_out$Y
years <- summary_out$years
p_r2 <- fit_r2$fitted
pair_path <- function(source, target, source_label, target_label) {
  ii <- match(source, rownames(Y_icews[[1]]))
  jj <- match(target, colnames(Y_icews[[1]]))
  data.frame(
    pair = paste(source_label, "toward", target_label),
    year = years,
    observed = vapply(Y_icews, function(M) M[ii, jj], numeric(1)),
    probability = vapply(p_r2, function(M) M[ii, jj], numeric(1)),
    lower = vapply(
      seq_along(years),
      function(tt) {
        quantile(
          vapply(
            fit_r2$bootstrap_dynamic$refits,
            function(refit) refit$fitted[[tt]][ii, jj],
            numeric(1)
          ),
          .025
        )
      },
      numeric(1)
    ),
    upper = vapply(
      seq_along(years),
      function(tt) {
        quantile(
          vapply(
            fit_r2$bootstrap_dynamic$refits,
            function(refit) refit$fitted[[tt]][ii, jj],
            numeric(1)
          ),
          .975
        )
      },
      numeric(1)
    )
  )
}
deck_pair_paths <- rbind(
  pair_path(
    "Iran, Islamic Republic Of", "Syrian Arab Republic",
    "Iran", "Syria"
  ),
  pair_path(
    "Syrian Arab Republic", "Iran, Islamic Republic Of",
    "Syria", "Iran"
  ),
  pair_path(
    "United States", "Syrian Arab Republic",
    "United States", "Syria"
  ),
  pair_path(
    "Syrian Arab Republic", "United States",
    "Syria", "United States"
  )
)
ggplot(deck_pair_paths, aes(year, probability)) +
  geom_ribbon(
    aes(ymin = lower, ymax = upper),
    fill = "#7BBD00",
    alpha = .18
  ) +
  geom_line(color = "#18453B", linewidth = 1.15) +
  geom_point(aes(shape = factor(observed)), size = 2.4) +
  facet_wrap(~ pair, ncol = 2) +
  scale_shape_manual(values = c("0" = 1, "1" = 19)) +
  scale_y_continuous(
    labels = scales::label_percent(),
    limits = c(0, 1)
  ) +
  labs(
    x = NULL,
    y = "Estimated chance of crossing the threshold",
    shape = "Observed"
  ) +
  theme(legend.position = "bottom")
```

Iran toward Syria rises from about 2% in 2002 to 92% in 2012. Syria toward Iran rises earlier, reaching about 69% in 2011. The model preserves that difference in timing.

::: {.slide-link}
[Follow the Ordered Pair Paths](day10_latent.html#sec-dynamic-pairs){.walkthrough-link target="_blank"}
:::

## The Annual Shape Is Mostly Right {#dynamic-annual-gof}

| Check | Rank 0 | Rank 2 | Years |
|---|---:|---:|---:|
| Density | 13 | 13 | 13 |
| Source-rate variation | 13 | 13 | 13 |
| Target-rate variation | 13 | 13 | 13 |
| Reciprocity | 5 | 6 | 13 |
| Cyclic triadic dependence | 11 | 12 | 13 |
| Transitive triadic dependence | 10 | 12 | 13 |

::: {.bottom-line}
Rank two captures annual volume, uneven state involvement, and most triadic structure. Reciprocity remains the main annual miss.
:::

::: {.slide-link}
[Inspect the Annual GOF Checks](day10_latent.html#sec-dynamic-gof){.walkthrough-link target="_blank"}
:::

## Rank Two Gets Much Closer Over Time {#dynamic-transition .dense-plot-slide}

```{r}
#| label: deck-dynamic-transition
#| echo: false
#| warning: false
#| message: false
#| fig-height: 5.8
#| fig-width: 10.5
#| out-width: "88%"
#| fig-alt: "Two stacked panels compare observed annual tie changes with simulation intervals from the dynamic SRM and rank-two AME. The rank-two model contains eight of twelve observed transition counts, compared with two of twelve for the SRM."
load("cache/icews_dynamic_gof_v1.rda")
observed_changes <- summary_out$change_stats$changes
transition_deck <- do.call(
  rbind,
  lapply(c("r0", "r2"), function(model_name) {
    M <- gof[[model_name]]$changes
    data.frame(
      year = years[-1],
      model = ifelse(
        model_name == "r0",
        "Dynamic SRM, rank 0",
        "Dynamic AME, rank 2"
      ),
      observed = observed_changes,
      median = apply(M, 1, median),
      lower = apply(M, 1, quantile, 0.025),
      upper = apply(M, 1, quantile, 0.975)
    )
  })
)
transition_deck$model <- factor(
  transition_deck$model,
  levels = c("Dynamic SRM, rank 0", "Dynamic AME, rank 2")
)
ggplot(
  transition_deck,
  aes(year, median, color = model, fill = model)
) +
  geom_ribbon(
    aes(ymin = lower, ymax = upper),
    alpha = 0.14,
    color = NA
  ) +
  geom_line(linewidth = 1) +
  geom_point(aes(y = observed), color = "#111111", size = 2) +
  facet_wrap(~ model, ncol = 1) +
  scale_color_manual(values = c(
    "Dynamic SRM, rank 0" = "#535054",
    "Dynamic AME, rank 2" = "#18453B"
  )) +
  scale_fill_manual(values = c(
    "Dynamic SRM, rank 0" = "#535054",
    "Dynamic AME, rank 2" = "#18453B"
  )) +
  labs(
    x = NULL,
    y = "Ordered pairs that changed status"
  ) +
  guides(color = "none", fill = "none")
```

Rank zero covers 2 of 12 observed transitions. Rank two covers 8 of 12. The improvement is large, but four transitions still miss.

::: {.slide-link}
[Read the Transition Check](day10_latent.html#sec-dynamic-gof){.walkthrough-link target="_blank"}
:::

## What the Iran-Syria Paths Show {#dynamic-result}

1. Some states appear in above-threshold relationships with many partners, but the Iran-Syria directions still follow their own distinct paths after accounting for that broad involvement.
2. Rank two improves held-pair prediction and makes simulated movement much more realistic than additive effects alone.
3. Iran toward Syria and Syria toward Iran both rise sharply, but not at exactly the same time.
4. The remaining reciprocity and transition misses limit the claim.

::: {.final-claim}
The estimated chance for Iran toward Syria rises from about 2% in 2002 to 92% in 2012. Syria toward Iran rises on a different timetable, reaching about 69% in 2011. These are changes in coded event volume, not a causal account of the Syrian conflict or a measure of battlefield severity.
:::

::: {.slide-link}
[Read the Complete Interpretation](day10_latent.html#sec-dynamic-after){.walkthrough-link target="_blank"}
:::

## A Published Directed Application: Conflict in Nigeria {#nigeria-illustration}

Dorff, Gallop, and Minhas (2020) study directed ACLED battle ties among 37 Nigerian armed organizations from 2000 through 2016.

| Model | ROC AUC | Precision-Recall AUC |
|---|---:|---:|
| AME | **0.92** | **0.33** |
| Measured predictors plus a lagged tie | 0.82 | 0.26 |
| Measured predictors only | 0.79 | 0.15 |

The factors place organizations in similar roles when they repeatedly fight the same kinds of opponents, even when they operate in different places and pursue different projects. The wider post-2009 increase in fitted battle risk is a system-level descriptive result, not a randomized effect of Boko Haram’s uprising.

::: {.slide-link}
[Read the Published Nigeria Illustration](day10_latent.html#sec-after-fit){.walkthrough-link target="_blank"}
:::

## Latent Adjustment Does Not Settle Omitted-Variable Bias {#exogeneity}

Suppose the latent outcome contains an omitted relational pattern $W$:

$$
Y^*=\beta X+\gamma W+e,
\qquad
W=\alpha X+z.
$$

Substitution gives

$$
Y^*=(\beta+\gamma\alpha)X+\gamma z+e.
$$

::: {.bottom-line}
If the omitted pattern is related to the measured predictor, the network alone cannot tell us how much of their shared pattern belongs to $X$ and how much belongs to $W$.
:::

AME can represent patterned dependence. It cannot turn that dependence adjustment into automatic confounding control (Minhas et al. 2022).

::: {.slide-link}
[Read the Exogeneity Boundary](day10_latent.html#sec-notbuy){.walkthrough-link target="_blank"}
:::

## What We Learned About Iran and Syria {#after-fit}

1. **Question:** When high-volume conflictual relationships change, is the change broad across a state's partners or concentrated in particular directed pairs?
2. **Validation:** Rank two improves complete-pair prediction and reproduces much more observed movement than the dynamic SRM.
3. **Relationship pattern:** Iran toward Syria and Syria toward Iran rise at different times, and the fitted probabilities preserve that difference.
4. **Boundary:** Reciprocity remains weak in several years, and four transition intervals still miss.

::: {.final-claim}
The result is not “two factors.” Iran toward Syria and Syria toward Iran follow different paths even after accounting for how often each state appears across all of its partners. That is a description of coded event volume, not an explanation of why the conflict changed.
:::

::: {.slide-link}
[Read the Complete After-Fit Interpretation](day10_latent.html#sec-after-fit){.walkthrough-link target="_blank"} [Continue to the Exercises](day10_latent.html#sec-exercises){.walkthrough-link target="_blank"}
:::
