Skip to content

Commit 2b5da49

Browse files
fix(p1b-oom): fold Sol OOM docs + release-hygiene findings
P1b-OOM disposition (Sol/ultra out-of-model review). Gate targets B1/B2/eval confirmed clean; folding the doc/config/metadata findings only. - README: clustered heatmap is unconditional (clustered= flag is not gated); TF-IDF experimental variant requires distance_metric="raw_weighted" (F10, F11) - notebook: align method labels to README — method 2 "Jaccard" -> "Co-occurrence"; PMI described as PPMI, cosine-only; core comment typo co-occurrnece->co-occurrence - notebook kernelspec cmap_vis_replication -> python3 (portable; was local env) (F4) - .gitignore: re-exclude function/__pycache__/ and the foreign CDPH org_cooccurrence_network.py so neither can reach the public repo (F8, F9) Deferred (tracked follow-up): F2 empty-seed None-guard, F3 singleton memory, F5 pytest dep, F6 parser char-bound, F1 chunking (pre-existing), F7 nltk-at-collection.
1 parent 429c3d8 commit 2b5da49

4 files changed

Lines changed: 28 additions & 24 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,7 @@ __marimo__/
165165
!/tests/**
166166
!pytest.ini
167167
tests/__pycache__/
168+
# Re-exclude bytecode under the un-ignored source dirs
169+
function/__pycache__/
170+
# Foreign module from another lane (CDPH org-cooccurrence network) — keep it out of this public repo
171+
function/org_cooccurrence_network.py

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,13 +341,13 @@ Word-to-word similarity can be computed with one of four methods, chosen with `c
341341
- **1 — RoBERTa embeddings:** contextual embeddings compared with cosine similarity.
342342
- **2 — Co-occurrence:** `cosine` uses frequency-sensitive context vectors; the default uses the Jaccard index (set-based, binary overlap).
343343
- **3 — PMI (Positive Pointwise Mutual Information):** supported with `distance_metric = "cosine"` **only**. PMI builds context vectors whose similarity is meaningful under cosine; other metrics are not defined for this method, so pairing PMI with a non-cosine metric is an unsupported configuration rather than a defect. Use `"cosine"` with method 3.
344-
- **4 — TF-IDF weighted co-occurrence:** `cosine` (or `default`) uses cosine similarity; other values select an experimental unnormalized-sum variant.
344+
- **4 — TF-IDF weighted co-occurrence:** `cosine` (or `default`) uses cosine similarity; `distance_metric = "raw_weighted"` selects an experimental unnormalized-sum variant. No other `distance_metric` value is supported for this method.
345345

346346
Combining a method and metric outside these supported pairings — most notably PMI with a non-cosine metric — will not produce a usable similarity matrix. This is expected behavior: select a supported method/metric pair.
347347

348348
### Hierarchical Clustering (Ward Linkage) in the Clustered Heatmap
349349

350-
When `clustered = True`, the heatmap also shows a dendrogram-ordered version that groups words using hierarchical clustering (Ward linkage) applied to the rows and columns of the word-by-word similarity matrix. This places similar words next to one another and reveals nested groupings.
350+
The heatmap output always includes a dendrogram-ordered version, shown side by side with the standard (unclustered) heatmap, that groups words using hierarchical clustering (Ward linkage) applied to the rows and columns of the word-by-word similarity matrix. This places similar words next to one another and reveals nested groupings.
351351

352352
Ward linkage here operates on each word's full similarity *profile* (its row/column in the matrix). It is a deliberate choice for producing interpretable dendrograms and word groupings, not a transformation of the individual similarity values. The values shown in the standard (unclustered) heatmap are unchanged; the clustered view only reorders and annotates them.
353353

function/vis_tool_core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ def run_pmi(sentences, selected_words, context_window, cache_file, epsilon=1e-9)
379379

380380
return filtered_embeddings, None, pmi_matrix
381381

382-
def run_tfidf_overlap(sentences, selected_words, context_window, all_candidates, cache_file): # Get TF-IDF co-occurrnece matrix
382+
def run_tfidf_overlap(sentences, selected_words, context_window, all_candidates, cache_file): # Get TF-IDF co-occurrence matrix
383383
"""
384384
Calculates similarity based on TF-IDF vectors of context windows.
385385
The primary and recommended method is 'cosine' similarity.

visualization_toolkit_final.ipynb

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"2. **Run Setup + Helper Functions top-to-bottom** — these load packages, define directories, stopwords / word-families, validators, and the plotting functions.\n",
1717
"3. **Run a tool section** — Basic (word cloud), Intermediate (heatmaps, t-SNE, networks), or Advanced (full / interactive). Edit the user-configuration block at the top of each section.\n",
1818
"\n",
19-
"**Key parameters (set per tool):** `clustering_method` 1 = RoBERTa, 2 = Jaccard, 3 = PMI, 4 = TF-IDF; `distance_metric` `\"cosine\"` or `\"default\"`. Design rationale for the environment-configuration and word-family setup steps is in [README → Design Notes](https://github.com/Computational-Ethnography-Lab/cmap_visualization_toolkit#design-notes).\n",
19+
"**Key parameters (set per tool):** `clustering_method` 1 = RoBERTa, 2 = Co-occurrence, 3 = PMI, 4 = TF-IDF; `distance_metric` `\"cosine\"` or `\"default\"`. Design rationale for the environment-configuration and word-family setup steps is in [README → Design Notes](https://github.com/Computational-Ethnography-Lab/cmap_visualization_toolkit#design-notes).\n",
2020
"\n",
2121
"## Core principles \n",
2222
"- Abramson, C. M., Prendergast, T., Li, Z., & Dohan, D. (2026). \"Qualitative Research in an Era of Artificial Intelligence: A Pragmatic Approach to Data Analysis, Workflow, and Computation.\" *Annual Review of Sociology, 52* (in press). https://doi.org/10.1146/annurev-soc-011824-104836\n",
@@ -899,14 +899,14 @@
899899
" print(\"Method: RoBERTa – Shows semantic relationships based on contextual embeddings\")\n",
900900
" elif input_data.clustering_method == 2:\n",
901901
" if input_data.distance_metric == \"cosine\":\n",
902-
" print(\"Method: Jaccard (cosine) – Uses context window vectors to compute cosine-based similarity between word usage patterns\")\n",
902+
" print(\"Method: Co-occurrence (cosine) – Uses context window vectors to compute cosine-based similarity between word usage patterns\")\n",
903903
" elif input_data.distance_metric == \"default\":\n",
904-
" print(\"Method: Jaccard (default) – Uses binary co-occurrence counts within a context window to capture word overlap\")\n",
904+
" print(\"Method: Co-occurrence (Jaccard index, default) – Uses binary co-occurrence counts within a context window to capture word overlap\")\n",
905905
" elif input_data.clustering_method == 3:\n",
906906
" if input_data.distance_metric == \"cosine\":\n",
907907
" print(\"Method: PMI (cosine) – Highlights statistically significant word associations using cosine similarity of PMI-weighted context vectors\")\n",
908908
" elif input_data.distance_metric == \"default\":\n",
909-
" print(\"Method: PMI (default) – Highlights statistically significant word associations using raw PMI scores\")\n",
909+
" print(\"Method: PMI (default) – Highlights statistically significant word associations using positive PMI (PPMI) scores\")\n",
910910
" elif input_data.clustering_method == 4:\n",
911911
" if input_data.distance_metric == \"raw_weighted\":\n",
912912
" print(\"Method: TF-IDF (raw weighted) – Uses raw TF-IDF-weighted co-occurrence scores for word associations\")\n",
@@ -1176,14 +1176,14 @@
11761176
" print(\"Method: RoBERTa – Shows semantic relationships based on contextual embeddings\")\n",
11771177
" elif input_data.clustering_method == 2:\n",
11781178
" if input_data.distance_metric == \"cosine\":\n",
1179-
" print(\"Method: Jaccard (cosine) – Uses context window vectors to compute cosine-based similarity between word usage patterns\")\n",
1179+
" print(\"Method: Co-occurrence (cosine) – Uses context window vectors to compute cosine-based similarity between word usage patterns\")\n",
11801180
" elif input_data.distance_metric == \"default\":\n",
1181-
" print(\"Method: Jaccard (default) – Uses binary co-occurrence counts within a context window to capture word overlap\")\n",
1181+
" print(\"Method: Co-occurrence (Jaccard index, default) – Uses binary co-occurrence counts within a context window to capture word overlap\")\n",
11821182
" elif input_data.clustering_method == 3:\n",
11831183
" if input_data.distance_metric == \"cosine\":\n",
11841184
" print(\"Method: PMI (cosine) – Highlights statistically significant word associations using cosine similarity of PMI-weighted context vectors\")\n",
11851185
" elif input_data.distance_metric == \"default\":\n",
1186-
" print(\"Method: PMI (default) – Highlights statistically significant word associations using raw PMI scores\")\n",
1186+
" print(\"Method: PMI (default) – Highlights statistically significant word associations using positive PMI (PPMI) scores\")\n",
11871187
" elif input_data.clustering_method == 4:\n",
11881188
" if input_data.distance_metric == \"raw_weighted\":\n",
11891189
" print(\"Method: TF-IDF (raw weighted) – Uses raw TF-IDF-weighted co-occurrence scores for word associations\")\n",
@@ -1583,14 +1583,14 @@
15831583
" print(\"Method: RoBERTa – Shows semantic relationships based on contextual embeddings\")\n",
15841584
" elif input_data.clustering_method == 2:\n",
15851585
" if input_data.distance_metric == \"cosine\":\n",
1586-
" print(\"Method: Jaccard (cosine) – Uses context window vectors to compute cosine-based similarity between word usage patterns\")\n",
1586+
" print(\"Method: Co-occurrence (cosine) – Uses context window vectors to compute cosine-based similarity between word usage patterns\")\n",
15871587
" elif input_data.distance_metric == \"default\":\n",
1588-
" print(\"Method: Jaccard (default) – Uses binary co-occurrence counts within a context window to capture word overlap\")\n",
1588+
" print(\"Method: Co-occurrence (Jaccard index, default) – Uses binary co-occurrence counts within a context window to capture word overlap\")\n",
15891589
" elif input_data.clustering_method == 3:\n",
15901590
" if input_data.distance_metric == \"cosine\":\n",
15911591
" print(\"Method: PMI (cosine) – Highlights statistically significant word associations using cosine similarity of PMI-weighted context vectors\")\n",
15921592
" elif input_data.distance_metric == \"default\":\n",
1593-
" print(\"Method: PMI (default) – Highlights statistically significant word associations using raw PMI scores\")\n",
1593+
" print(\"Method: PMI (default) – Highlights statistically significant word associations using positive PMI (PPMI) scores\")\n",
15941594
" elif input_data.clustering_method == 4:\n",
15951595
" if input_data.distance_metric == \"raw_weighted\":\n",
15961596
" print(\"Method: TF-IDF (raw weighted) – Uses raw TF-IDF-weighted co-occurrence scores for word associations\")\n",
@@ -2033,14 +2033,14 @@
20332033
" print(\"Method: RoBERTa – Shows semantic relationships based on contextual embeddings\")\n",
20342034
" elif input_data.clustering_method == 2:\n",
20352035
" if input_data.distance_metric == \"cosine\":\n",
2036-
" print(\"Method: Jaccard (cosine) – Uses context window vectors to compute cosine-based similarity between word usage patterns\")\n",
2036+
" print(\"Method: Co-occurrence (cosine) – Uses context window vectors to compute cosine-based similarity between word usage patterns\")\n",
20372037
" elif input_data.distance_metric == \"default\":\n",
2038-
" print(\"Method: Jaccard (default) – Uses binary co-occurrence counts within a context window to capture word overlap\")\n",
2038+
" print(\"Method: Co-occurrence (Jaccard index, default) – Uses binary co-occurrence counts within a context window to capture word overlap\")\n",
20392039
" elif input_data.clustering_method == 3:\n",
20402040
" if input_data.distance_metric == \"cosine\":\n",
20412041
" print(\"Method: PMI (cosine) – Highlights statistically significant word associations using cosine similarity of PMI-weighted context vectors\")\n",
20422042
" elif input_data.distance_metric == \"default\":\n",
2043-
" print(\"Method: PMI (default) – Highlights statistically significant word associations using raw PMI scores\")\n",
2043+
" print(\"Method: PMI (default) – Highlights statistically significant word associations using positive PMI (PPMI) scores\")\n",
20442044
" elif input_data.clustering_method == 4:\n",
20452045
" if input_data.distance_metric == \"raw_weighted\":\n",
20462046
" print(\"Method: TF-IDF (raw weighted) – Uses raw TF-IDF-weighted co-occurrence scores for word associations\")\n",
@@ -2605,7 +2605,7 @@
26052605
" use_custom_stoplist = True\n",
26062606
"\n",
26072607
" # Core Analysis\n",
2608-
" clustering_method = 3 # 1 = RoBERTa, 2 = Jaccard, 3 = PMI, 4 = TF-IDF\n",
2608+
" clustering_method = 3 # 1 = RoBERTa, 2 = Co-occurrence, 3 = PMI, 4 = TF-IDF\n",
26092609
" distance_metric = \"cosine\" \n",
26102610
" \n",
26112611
"# Note on clustering method and distance metric:\n",
@@ -2614,14 +2614,14 @@
26142614
"# - distance_metric is always \"default\" (ignored internally)\n",
26152615
"# - Uses contextual embeddings directly\n",
26162616
"#\n",
2617-
"# 2. Jaccard (clustering_method = 2)\n",
2617+
"# 2. Co-occurrence (clustering_method = 2)\n",
26182618
"# - \"default\": context-window overlap measured by Jaccard index\n",
26192619
"# (set-based, binary overlap score)\n",
26202620
"# - \"cosine\" : context vectors built from co-occurrence counts,\n",
26212621
"# compared using cosine similarity (frequency-sensitive)\n",
26222622
"#\n",
26232623
"# 3. PMI (clustering_method = 3)\n",
2624-
"# - \"default\": classic PMI co-occurrence scores\n",
2624+
"# - \"default\": positive PMI (PPMI) scores (PMI supports \"cosine\" only)\n",
26252625
"# - \"cosine\" : PMI-weighted context vectors compared with cosine similarity\n",
26262626
"# (captures similarity of PMI distributions rather than raw scores)\n",
26272627
"#\n",
@@ -3045,7 +3045,7 @@
30453045
" use_custom_stoplist = True\n",
30463046
"\n",
30473047
" # Core Analysis\n",
3048-
" clustering_method = 2 # 1 = RoBERTa, 2 = Jaccard, 3 = PMI, 4 = TF-IDF\n",
3048+
" clustering_method = 2 # 1 = RoBERTa, 2 = Co-occurrence, 3 = PMI, 4 = TF-IDF\n",
30493049
" distance_metric = \"cosine\" \n",
30503050
" \n",
30513051
" # Note on clustering method and distance metric:\n",
@@ -3241,7 +3241,7 @@
32413241
" - If not provided, the default list will be used.\n",
32423242
"\n",
32433243
"4. Clustering Method & Parameters:\n",
3244-
" - Choose from: 1 = RoBERTa, 2 = Jaccard, 3 = PMI, 4 = TF-IDF.\n",
3244+
" - Choose from: 1 = RoBERTa, 2 = Co-occurrence, 3 = PMI, 4 = TF-IDF.\n",
32453245
" - For methods 2–4, specify distance metric (default or cosine) and context window size.\n",
32463246
"\n",
32473247
"5. Analysis Filters:\n",
@@ -3402,7 +3402,7 @@
34023402
" while True:\n",
34033403
" try:\n",
34043404
" clustering_method = int(\n",
3405-
" input(\"Choose clustering method 1=RoBERTa, 2=Jaccard, 3=PMI, 4=TF-IDF [Default 1]: \").strip() or \"1\"\n",
3405+
" input(\"Choose clustering method 1=RoBERTa, 2=Co-occurrence, 3=PMI, 4=TF-IDF [Default 1]: \").strip() or \"1\"\n",
34063406
" )\n",
34073407
" if clustering_method in (1, 2, 3, 4):\n",
34083408
" break\n",
@@ -3542,9 +3542,9 @@
35423542
],
35433543
"metadata": {
35443544
"kernelspec": {
3545-
"display_name": "cmap_vis_replication",
3545+
"display_name": "Python 3",
35463546
"language": "python",
3547-
"name": "cmap_vis_replication"
3547+
"name": "python3"
35483548
},
35493549
"language_info": {
35503550
"codemirror_mode": {

0 commit comments

Comments
 (0)