Commit Graph
117 Commits
Author SHA1 Message Date
wassnameandClaudypoo b8982f7494 WVS map uses shared plot_value_map; big5 value axes bipolar
The WVS map's ~70 lines of pole-signpost/hull/textalloc rendering were a copy of
what plot_value_map now does -- call the shared renderer instead (WVS + instruments
one code path). big5 value-axis poles named at both ends (Reserved<->Exploratory,
Volatile<->Stable) so every value map reads as a bipolar contrast, not a unipolar
low<->high.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-05 07:29:42 +08:00
wassnameandClaudypoo 3431ab40f0 WVS map: write model cache after each model (kill-safe), bigger star palette
The cache was written once at the very end, so a killed run (session teardown)
discarded every sampled model. Persist after each model instead, and expand the
model-star palette to 14 so a large model panel doesn't silently drop stars past
the 6th via zip truncation.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-05 07:18:02 +08:00
wassnameandClaudypoo a2043d3377 WVS map: on-map LLM labels (textalloc) + corner-extreme outlier labels
Replace the model legend with textalloc-placed on-map labels (leader lines, coloured
to each star), and route country labels through the same textalloc pass so Pakistan/
Nigeria/Egypt no longer collide. outlying_countries now returns the corner-most
society in each diagonal direction (top-right/bottom-left/...) instead of the n
farthest from the centroid, which bunched on one side and left the bottom-left corner
(Egypt) unlabelled.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-05 06:47:40 +08:00
wassnameandClaudypoo 8a8c7b0fca WVS map: model legend + deterministic cache key (was re-calling APIs every run)
The E-vector cache keyed on Python's builtin hash(), which is salted per process
(PYTHONHASHSEED), so the signature changed every run and the cache never hit across
processes -- silently re-spending on the OpenRouter API each time. Switch to a
stable hashlib key. LLM stars now go in a lower-right legend instead of colliding
inline labels (they cluster in one corner, which IS the result).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 23:13:21 +08:00
wassnameandClaudypoo 19ce742ad4 WVS map: crosshairs through human median, no ticks, pole arrows on the crosshairs
Economist style: drop the axis ticks, move the neutral crosshair from an arbitrary
0.5 to the human-society median on each axis, and anchor each pole signpost's arrow
to its median crosshair (blended data/axes transform) so the four directions read
against the typical society. Pole labels all horizontal.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 21:41:51 +08:00
wassnameandClaudypoo b1ff08a337 WVS map: generic zone/label selection + Economist pole signposts
Replace hardcoded zone lists with geometric rules that work on any map:
- maps.select_spread_zones: greedy max-coverage on hull areas -- seed the
  largest zone, add whichever contributes the most new non-overlapping area.
  Drops central/covered zones (Orthodox) and keeps the corner cultures.
- maps.outlying_countries: the n countries farthest from the centroid, unioned
  with named landmarks + one representative (most-central member) per drawn zone
  so every region has at least one identifiable label.
- draw_zone_hulls: edge-only coloured outline (no fill), contour only for 2+
  member groups, label anchored to the hull's top vertex.

WVS map: four arrowed pole signposts (Traditional/Secular-Rational/Survival/
Self-expression) in a padded inner margin so they don't collide with title/ticks;
model stars use a palette disjoint from the zone colours.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 21:37:42 +08:00
wassnameandClaudypoo abe43ad593 WVS map: labeled Inglehart-Welzel axes + Economist-style convex-hull zones
Replace the blind ipsative-PCA projection with two named IW axes built from
GlobalOpinionQA WVS items (tinymfv.iw_axes): X = Survival<->Self-expression
(homosexuality, trust, political action), Y = Traditional<->Secular-Rational
(religion importance+belief, abortion, child autonomy). Each item is oriented to
its axis-positive pole by reading the option order, so a reversed row can't flip a
country. Human anchors land where the published IW map puts them (Sweden top-right,
Nigeria/Pakistan bottom-left, East Asia secular-but-survival top-left).

Models answer the same items via the answer-token reader (single-digit option labels
so the 1-10 justifiable scale stays single-token); coords are the same axis-mean.

Add maps.draw_zone_hulls: tight rounded convex hulls (not inflated disc unions),
zone-coloured dots, outlier-only labels, white-haloed region names -- the Economist
grammar. draw_zone_regions stays for the instrument maps' within-country spread.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 21:26:25 +08:00
wassnameandClaudypoo ea796dee9a Cache WVS model E-vectors; impute collapsed questions for projection
Cache model E-vectors keyed by the exact question block, so iterating on the zone
style re-projects + re-draws without re-hitting the API (~20 min of calls). A
question a model didn't answer coherently (NaN) is imputed with the human average
at projection so one collapse doesn't drop the whole model dot.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 20:54:56 +08:00
wassnameandClaudypoo 44c1fa0595 Zone regions: merged union of natural per-country shapes; turn off 16pf
Replace stacked translucent discs (which darkened at overlaps) with a shapely
union per zone -> one merged shape, uniform alpha. Each country's territory is now
its REAL spread ellipse from its respondent/haze cloud (natural varying shape), not
a fixed disc; sizes are rescaled so the median country ~ a legible radius (raw
within-country spread >> between-country, would fill the plot). Every country sits
in its zone, 2-country zones have area. MFV/WVS (country means only) fall back to a
fixed disc. 16pf turned off (unreadable even at 6 macro zones). Adds shapely to the
maps extra.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 20:52:25 +08:00
wassnameandClaudypoo f39a0763ab Add WVS/Inglehart-Welzel culture map placing LLMs among societies
wvs_map.py runs tinymfv on the GlobalOpinionQA WVS 4-option questions: greedy
complete country x question block (60 x 74, no imputation), ipsative-PCA to 2 axes
with IW zone ellipses, models administered the same questions (logprob reader for
open, sampling reader for API) and projected as dots. Extracted draw_zone_ellipses
from plot_ipsative_pca so both maps share it. Human map reproduces the Economist
layout: African-Islamic/South-Asia (survival) left, English-Speaking/Protestant
Europe (self-expression) right, Confucian/Latin America/Orthodox separating.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 20:37:02 +08:00
wassnameandClaudypoo 2af00b374c Extract IW zone taxonomy to tinymfv.zones, extend to WVS 90 countries
Second consumer (the WVS map) needs the same curated zone data, so move it out of
the showcase script into the package rather than duplicate it (avoids drift in
research data). Extended IW_ZONE to cover all 90 WVS countries + SAR/name-variant
aliases. Showcase script now imports zones_for from tinymfv.zones.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 20:26:44 +08:00
wassnameandClaudypoo b2532acd90 Switch zone blobs to country-mean covariance ellipses, fit PCA on means
Per feedback the individual-respondent contours filled the frame (within >>
between variance). Now each IW zone is a ~1.6-sigma covariance ellipse over its
member country-mean dots, with an eigenvalue floor so 1-2 country zones get a
visible blob instead of a dot/line (fixes big5 SG/PK orphans). PCA now fits on the
country means M so the axes are between-country and zones separate. mfq2/big5/mfv
read cleanly; humor still overlaps (real negative result: humor country profiles
don't cluster the IW way).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 20:22:23 +08:00
wassnameandClaudypoo 40d08f8d7a Establish P4 WVS map data foundation (GlobalOpinionQA)
Probe + artifact: the WVS subset of Anthropic/llm_global_opinions is 353 questions
over 90 countries (212 questions with >=40 countries), matching tinymfv's MC +
human-anchor shape and dense enough for an Economist-scale map. Documents the
selections parse recipe and the open axis-definition fork (literal IW 10-question
factor model vs shared-question ipsative PCA) before model-run compute.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 19:43:24 +08:00
wassnameandClaudypoo f5efbd24bd Add sampling readout for logprob-less API models (OpenRouter)
read_api.read_items_sampled samples N chat completions at temperature and uses the
empirical answer frequency as the per-item categorical p, emitting the same row
shape the logprob reader does -- so E/profile/entropy flow through the identical
per_item_categorical + reducers and a frontier model without logprobs drops onto
the same map. pmass_allowed becomes the parse rate (sampling coherence gate); C/LO
are omitted by design (log of a frequency has -inf zeros). This is the Economist's
'average of ten responses' method.

UAT (docs/reviews/p3_api_sampling_uat.md): E_mc == E_logprob to <=0.01 (unbiased),
llama-3.1-8b sampled E lands on the same [1,5] scale, parse-rate gate flags
off-format draws.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 19:39:18 +08:00
wassnameandClaudypoo 2c2dd9b9bf Add MFQ-2 per-zone p90 respondent ellipses to ipsative map
respondent_profiles now returns countries alongside profiles; plot_ipsative_pca
gains respondent_zones -> a p90 Gaussian ellipse per IW zone of the projected
Atari respondent cloud (edge-only, no scipy). mfq2 uses these real-respondent
ellipses; the other instruments keep country-mean hulls. Journal notes the
finding: individual profiles overlap across cultures (within >> between variance),
so only the country-mean hull reproduces the Economist's clean zone blobs.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 19:25:52 +08:00
wassnameandClaudypoo 0e7178dfbd Add Inglehart-Welzel zone hulls + outlier labels to ipsative maps
Echoes the Economist WVS 'Godless hippies' chart: shaded convex-hull blobs per
IW cultural zone (inline 2D hull, no scipy dep so the maps extra stays
matplotlib-only) and bold-first labels for named outliers. Caller owns the zone
taxonomy + name/ISO2 normalizer, fails loud on unmapped countries; the corrupt
'(nu' big5 row is explicitly excluded with a warning.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-07-04 19:16:41 +08:00
wassname 061ce8a4f6 Export MFQ2 sample logprobs for N bootstrap 2026-07-01 06:24:13 +08:00
wassname 9fc3852a8a Require explicit showcase steering anchor 2026-06-30 14:08:16 +08:00
wassname fe3b0aff2c Gate showcase paths on contrast and margin 2026-06-30 14:01:59 +08:00
wassname 0d7654506c Add showcase effect table summarizer 2026-06-30 13:50:39 +08:00
wassname 6fcdfea30f Support sampled survey reads and MFV c-grid plots 2026-06-30 13:28:20 +08:00
wassname d8941f47ac Rewrite README around profile plots 2026-06-30 12:38:20 +08:00
wassname 0bea238224 Rewrite README around datasets and maps 2026-06-29 20:51:54 +08:00
wassnameandClaudypoo f1d23b338e plots: range+map only for every instrument; legend = c-multiplier not full desc
- drop splom/splom_zoom/range_zoom (ordinal) and the MFV dlogit dumbbell; every
  instrument now yields exactly map_pca_ipsative + range, uniform.
- range pole label is now 'c=+1'/'c=-1' (the multiplier); the full steer desc
  stays in the title only (was crammed into each pole annotation).

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-26 04:30:02 +08:00
wassnameandClaudypoo 3fcdda4516 plots: drop redundant foundation_dcontrast dumbbell
The range plot already shows the per-foundation steer (human cloud + AI base
dot + +C/-C arrows) with the human anchor the dumbbell lacks; dcontrast plotted
the same delta on the C-nats scale and failed the eraser test. C stays the
measurement in the CSV/foundations table, just not a separate panel.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-26 04:13:12 +08:00
wassname 6594cc212d api: clarify eval readout names 2026-06-25 20:22:04 +08:00
wassname 4b38de685e cleanup: remove legacy dataset creation artifacts 2026-06-25 20:21:49 +08:00
wassnameandClaudypoo 2d76166cbd showcase: add ordinal steer-effect plot (delta-contrast C dumbbell)
The E map/range are for human comparison; this new per-instrument foundation_dcontrast
figure shows the steer in the sensitive contrast readout (steered minus base C, +C vs -C),
the ordinal twin of the MFV dlogit dumbbell. read_profiles gains a value_col so it reads
either E ('mean') or C. This is the figure that shows what we steered for; the E range hides it.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-25 19:20:25 +08:00
wassnameandClaudypoo 2160304541 plots: MFV reuses shared ipsative map + range in z-space; fix range coherence-gate
MFV got two bespoke figures (z-emphasis bars + dlogit dumbbell). Per GPT-5.5 code
review, reuse the geometry not the ordinal semantics: a _mfv_zspace adapter feeds the
same plot_ipsative_pca + plot_range the ordinal instruments use, in z-scored relative-
emphasis space (logit-violation and 1-5 wrongness cannot share a raw axis). Keep the
dlogit dumbbell as a raw-magnitude diagnostic; drop the bespoke map_emphasis.

Also fix a real bug the review found: plot_ordinal gated the map/SPLOM trajectory to
coherent c (pmass >= 0.95*base) but still passed ALL cs to range/range_zoom, so the
figures disagreed on which poles were valid. Range/zoom now use the same coh_cs.
plot_range gains an ylabel param (MFV is z-space, not 1-M); draw_steer asserts sorted
cs; MFV asserts only Social Norms is dropped.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-25 15:51:40 +08:00
wassnameandClaudypoo eb433f1cdc plot showcase: relative coherence gate + persona vec_label
Trajectory coherence gate was absolute (pmass<0.9); make it relative -- keep a
c only if pmass >= 95% of the base (c=0) pmass, else drop it entirely (no hollow
markers). Read vec_label from summary.json so non-authority personas label
correctly instead of the hardcoded "Authority/Care axis".

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-25 09:09:02 +08:00
wassnameandClaudypoo a2fe33ac53 maps: foundation SPLOM + minimap, crop synthetic-haze maps to societies+steer
- plot_splom: KxK pairs-plot (mfq2 real joint only -- others ship independent-
  marginal haze that would fabricate off-diagonal correlation). lower=joint
  scatter w/ AI base->steer trajectory, diag=marginal+AI rules, upper=Pearson r
  sized by |r|. Ordered by PC1 loading so binding (authority/loyalty) cluster.
  full + AI-zoom (macro/micro). NaN-safe at collapsed poles.
- ipsative map: synthetic haze is far wider than the societies, so it now crops to
  societies+steer (haze clips) and adds a 'full space' minimap with a viewport
  rectangle -- readable big5/16pf/humor maps with macro context kept.
- compass labels via textalloc (was overlapping); NaN-safe crop.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-25 08:45:01 +08:00
wassnameandClaudypoo 9b13db3390 maps: multi-C trajectory overlay on ipsative map (path + hollow-at-incoherent + adaptive compass)
Driver writes the signed c-multiplier per row; plotter feeds the full c-sweep to
the range (already multi-c capable) and a connected path to the map. Headline
arrows point to calibrated c=+-1; trajectory dots at |c|>1 extend beyond, growing
with |c|, drawn hollow where admin pmass fell below the coherence floor. Compass
moves to the least-crowded corner so the +c arm (which heads toward its own
loading) stops colliding with it.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-25 08:35:29 +08:00
wassnameandClaudypoo 50bdf8d235 plot: automatic MFV foundation-emphasis map vs human cultures
MFV had only the dlogit dumbbell, no human comparison. Add plot_mfv_map: per-
foundation relative emphasis (z across foundations) of model base/+C/-C against
the 5 MFV human cultures (JimenezLeal+Yamada), z-scoring each profile so the
model's logit scale and humans' 1-5 wrongness compare by pattern. Social Norms
dropped (no human norm). Shows the model over-weights Care/Authority vs humans
and +C lowers Authority emphasis. Keeps the dumbbell too.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-25 07:33:42 +08:00
wassnameandClaudypoo 0e92e66415 maps: human haze on all ipsative maps (synthetic resample for big5/16pf/humor)
Split the PCA-fit basis from the scattered cloud in plot_ipsative_pca: add a
'haze' arg so instruments with only society-level mean+sd get a backdrop
(marginal Normal resample per country) without that resample dictating the
axes. mfq2 keeps its real Atari respondents (fit + haze). Previously only mfq2
had any human scatter; big5/16pf/humor showed bare society dots.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-25 07:30:37 +08:00
wassnameandClaudypoo 3ece864460 add word-readout diagnostic (confirm validation-table 0.826 under old method)
Throwaway probe (like probe_mfv_think_budget): reuses the current _rollout core but
gathers foundation-WORD first tokens + word-keyed schema + no rev-reversal -- the
pre-e4e0f4d readout that produced the 82.6% validation number. Canonical evaluate()
stays digit-only. Confirms whether the showcase model matches the validation table
under the table's own method.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-25 04:22:14 +08:00
wassnameandClaudypoo 58377ae863 probe: add n_samples/temperature for BMA top1 test
Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-25 03:34:34 +08:00
wassnameandClaudypoo aa1ca1800f add MFV think-budget probe to test case-(c) collapse diagnosis
MFV pmass=0.1664 == 44/264 non-closing rows. Sweeps think budget to confirm the
collapse is guided.py case (c) (closed-think discards the forced read) and
whether a short budget recovers coherence without a researched-semantics change.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-24 21:26:47 +08:00
wassnameandClaudypoo d20f717251 maps: respondent-haze ipsative map + glossed axes (port from mft_honesty)
plot_ipsative_pca gains an optional respondents arg: when given it fits the
ipsative PCA basis on the individual cloud (3902 Atari respondents) and scatters
them behind the society dots, with an envelope-core crop, matching the
mft_honesty fig_pca_ipsative the project standardized on. Axis labels carry a
foundation-loading gloss. respondents=None keeps the old society-only behavior.

Bundles atari_study2_raw.csv + a respondent_profiles loader (keying verbatim
from Atari Code_Study2.R) so tinymfv owns the data, no mft_honesty dependency.
plot_steer_showcase passes respondents for mfq2 only.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-24 15:49:24 +08:00
wassnameandClaudypoo d8af90c6e3 scripts: plot a steering run across all instruments (dogfood the maps)
Consume a steering-lite all-instrument run dir and render, per instrument,
tinymfv's ipsative map + range + zoom (ordinal) and a per-foundation Delta-logit
dumbbell (MFV), against the bundled human cloud. The showcase that exercises
tinymfv.maps end-to-end on real steering before publishing the lib.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-24 13:21:49 +08:00
wassname fde697130d Merge branch 'main' of https://github.com/wassname/tinymfv 2026-06-18 21:32:07 +08:00
wassnameandClaudypoo 6e60bc2c53 forced_choice: print informedness; drop stale nll_prompt refs
nll_prompt was removed from per_row in f585864 but the script still read it,
crashing the smoke test. Remove the dead refs and surface the new
informedness scalar alongside top1_acc.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
2026-06-18 19:47:21 +08:00
wassname 49751fbeab refactor: update evaluation metrics to include pmass_allowed and nll_json 2026-05-21 06:05:16 +00:00
wassname e3b663d7f7 proofread 2026-05-13 10:48:28 +08:00
wassname 9abddaeac5 return pmass 2026-05-08 16:36:36 +08:00
wassname 0e4443398b clean 2026-05-08 16:14:07 +08:00
wassname 845484483d misc 2026-05-08 16:06:41 +08:00
wassname b20ec56a09 forced-choice unification: drop legacy llm_/calibrated_, normalize human_*, justfile->09 2026-05-08 16:02:25 +08:00
wassname d827a1f873 rename 2026-05-08 15:37:31 +08:00
wassname 0442935279 clean 2026-05-08 15:33:29 +08:00
wassname 8dfaf299ca rename 2026-05-08 15:30:06 +08:00