# How Synthome uses network science

The explorer uses measured network structure to position and color the graph. Its factual arcs remain the submitted, typed relationships. Clustering does not add facts.

The downloadable [analysis JSON](/network-analysis.json) drives the explorer. The [Gephi GEXF](/synthome.gexf) contains every public node and original directed arc. Both derive from the public projection, excluding private course fields.

## What the visual encodings mean

| Encoding | Network measure | Interpretation |
| --- | --- | --- |
| Neighborhood color | Weighted Louvain community | A computed group of densely connected nodes, labeled by its leading topic titles. |
| Position | Three-dimensional NetworkX ForceAtlas2 | Connected nodes attract; nodes repel. The layout reveals structure without asserting geographic or semantic distance. |
| Node size options | Degree, weighted PageRank, or betweenness | Connectivity, structural influence, or bridging between shortest paths. These do not measure teaching quality or truth. |
| Node shape | Resource, topic, publisher, or week | The entity class is distinct from the computed community. |
| Layer view | Entity-type planes | Publisher, resource, topic, and week occupy explicit z planes. ForceAtlas2 supplies their x/y coordinates. |
| Arc label and direction | Original ontology predicate | Each arc keeps its source, target, relationship, label, review status, and provenance. |

This is a heterogeneous graph with an optional layered view. It is not a multiplex model with replicated entities across independent network layers. Week planes are proposed placement, not a causal or temporal sequence.

One/two-hop inspection paginates the actual neighborhood into at most twelve displayed arcs. Those focus pages use a radial arrangement for readable labels, rather than ForceAtlas2 coordinates. The complete source relationships remain available in the selected-node list. Filters and focus do not recalculate full-graph metrics or communities.

## Analytical projection and weights

The source graph is directed. Network analysis uses an undirected, simple projection because its current arcs all point from resources toward classifiers. Directional prestige would otherwise concentrate on classifier sinks. No undirected connection is written back as an ontology assertion.

Parallel source arcs, if present, contribute summed strength in the analytical projection. The directed GEXF retains every source arc separately.

| Relation | Attraction weight | Reason |
| --- | ---: | --- |
| `CLASSIFIED_AS` | 1.00 | Topic classifications chiefly define learning neighborhoods. |
| `PUBLISHED_BY` | 0.35 | Publisher identity provides context while avoiding dominance by prolific publishers. |
| `PROPOSED_FOR` | 0.20 | Large week hubs provide course context without controlling the entire layout. |

These are analyst choices, not learned parameters, calibrated probabilities, evidence confidence, or causal strength. Changing them can change neighborhoods and positions.

## Metrics and reproducibility

- **Degree:** number of distinct adjacent nodes in the undirected projection.
- **Weighted degree:** sum of adjacent attraction weights.
- **PageRank:** weighted undirected structural influence, damping `0.85`, tolerance `1e-12`, at most `1000` iterations. The resulting scores sum to one.
- **Betweenness:** exact, normalized Brandes shortest-hop betweenness, excluding endpoints. It is unweighted because attraction strength is not path distance.
- **Core number:** largest unweighted k-core containing the node.
- **Component:** connected component of the undirected projection.
- **Community:** weighted Louvain modularity optimization, resolution `1`, random seed `42`. Community IDs are stable for an unchanged snapshot and environment, but may change after updates.
- **ForceAtlas2:** NetworkX implementation, `dim=3`, `max_iter=300`, `scaling_ratio=2`, `gravity=1`, `jitter_tolerance=1`, seed `42`; strong gravity, distributed action, and LinLog are off. Coordinates are centered and uniformly scaled to a maximum absolute coordinate of `220`.

All source nodes and arcs are sorted before insertion. NetworkX `3.7`, NumPy `2.2.6`, and SciPy `1.15.3` are pinned. Generated files omit wall-clock timestamps. Floating-point behavior can differ across platforms; reproducibility is verified within the pinned execution environment.

`sourceRevision` is SHA-256 of the exact UTF-8 bytes from `JSON.stringify(projectPublicGraph(source))`. Python receives those bytes from `scripts/export-public.mjs`; it does not reserialize the source before hashing. The web build must reject an analysis revision that differs from the current public projection.

## Current snapshot and sensitivity

The current projection has **1,188 nodes**, **3,475 arcs**, **one connected component**, and **10 communities**. Weighted modularity is **0.62206312**; undirected density is **0.0049285327**. It is bipartite: resources connect to classifiers, not directly to other resources. Ordinary triangle clustering would therefore be zero by construction, not evidence that learning topics lack cohesion.

The report recomputes Louvain communities under two alternative weight profiles. Adjusted Rand agreement compares partitions independently of community labels; `1` means identical membership, `0` is chance-adjusted agreement, and negative values are possible.

| Profile | Topic / publisher / week weights | Communities | Modularity | Agreement with baseline |
| --- | --- | ---: | ---: | ---: |
| Baseline | 1 / 0.35 / 0.20 | 10 | 0.62206312 | 1.00000000 |
| Equal relationships | 1 / 1 / 1 | 10 | 0.55306765 | 0.57195129 |
| Half context weights | 1 / 0.175 / 0.10 | 13 | 0.64099292 | 0.62287717 |

These changes are material. Colors represent one useful exploratory view, not a definitive taxonomy. Modularity values across differently weighted graphs do not establish that one profile is objectively better. The JSON includes the profiles and results for inspection.

## Regenerate locally

From `integrations/synthome-library`, using Python 3.12 and Node:

```sh
python -m venv test-output/networkx-venv
# Windows PowerShell:
test-output/networkx-venv/Scripts/python.exe -m pip install -r analysis/requirements.txt
test-output/networkx-venv/Scripts/python.exe scripts/analyze_network.py
test-output/networkx-venv/Scripts/python.exe -m unittest discover -s test -p test_network_analysis.py -v
```

On macOS/Linux, substitute `test-output/networkx-venv/bin/python`. Python runs during editorial regeneration, not inside Vercel requests. Commit both regenerated artifacts with the source update, then run the JavaScript tests and build.

## Explore in Gephi

1. Download `synthome.gexf` and open it in Gephi as a directed graph.
2. Check the import report for the expected node and arc counts.
3. Inspect `entityType`, `community`, `degree`, `weightedDegree`, `pagerank`, `betweenness`, `core`, and `component` in Data Laboratory.
4. Use Appearance to partition colors by `community` and rank size by a metric. The supplied visualization attributes already include colors, positions, and degree-based sizes.
5. Enable edge labels to see the ontology predicates. Filter an ego neighborhood when labels overlap.
6. Optionally run Gephi ForceAtlas2 to explore another layout. Gephi's interactive layout and NetworkX's 3D implementation need not produce identical coordinates.

The GEXF remains directed. Running Gephi statistics with directed settings can produce different values from Synthome's documented undirected analytical projection. Select equivalent settings when comparing.

## Sources

- [NetworkX ForceAtlas2 API](https://networkx.org/documentation/stable/reference/generated/networkx.drawing.layout.forceatlas2_layout.html)
- [NetworkX Louvain communities](https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.community.louvain.louvain_communities.html)
- [NetworkX PageRank](https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.link_analysis.pagerank_alg.pagerank.html)
- [NetworkX betweenness centrality](https://networkx.org/documentation/stable/reference/algorithms/generated/networkx.algorithms.centrality.betweenness_centrality.html)
- [Gephi's official quickstart](https://gephi.org/quickstart/)

Primary documentation checked September 29, 2026. The data provenance and review status of individual resources remain separate from the correctness of these computations.
