---
title: "The Future That Could Have Been: Turning Web Text into Semantic Stock Betas"
description: "Learn how semantic-factors turns NOSIBLE World web text into transparent daily risk factors and stock-specific betas for quantitative research."
url: "https://nosible.com/blog/the-future-that-could-have-been-turning-web-text-into-semantic-stock-betas"
---

[Risk Indicator](https://nosible.com/blog/tag/risk-indicator)

[Artificial Intelligence](https://nosible.com/blog/tag/artificial-intelligence)

[Machine Learning](https://nosible.com/blog/tag/machine-learning)

[NOSIBLE World](https://nosible.com/blog/tag/nosible-world)

# The Future That Could Have Been: Turning Web Text into Semantic Stock Betas

[Stuart Reid](https://www.linkedin.com/in/stuartgordonreid/)

2026-08-05

11 min read

Copy as Markdown

![Thirty semantic factors rendered as daily time series on a dark grid, from geopolitical risk to firm-level political risk.](https://nosible.com/images/2026/08/semantic-factors-hero.png)

Markets move on wars, tariffs, pandemics, elections, and central bank decisions. These events are reported in text. The problem? Risk models cannot read. They are built from prices and financial statements because that is what we could measure when they were invented. Today we are releasing the fix.

Today we're proud to announce the release of `semantic-factors`, an open-source Python library that turns NOSIBLE World coverage into daily risk factors and stock-level betas. Simply define a risk in plain text. The package quantifies it every day going back more than a decade. All you need is a NOSIBLE World API key.

[Explore the 30 semantic factors](https://nosible.com/semantic-factors) or [read the package on GitHub](https://github.com/NosibleAI/semantic-factors).

## Risk models cannot read

In 1973, [Robert Merton's ICAPM](https://breesefine7110.tulane.edu/wp-content/uploads/sites/16/2015/10/Merton-Int.-CAPM.pdf) showed that equilibrium expected returns compensate investors for exposure to shocks that change future investment opportunities. What the theory left unresolved was empirical identification: which state variables summarize the information investors actually possess?

Contemporary empirical finance largely worked with structured return data, under genuine computational constraints. Fifty years later, news text provides a new measurement layer. As [Bybee, Kelly, and Su](https://doi.org/10.1093/rfs/hhad042) put it, ICAPM risk is tied to news about state variables tracking wealth and future investment opportunities.

[Fama and MacBeth's 1973 empirical work](https://www.efalken.com/LowVolClassics/famaMacBeth73.pdf) used structured monthly percentage returns and described the balance between computation costs and the desire to reform portfolios frequently. That was a sensible research design for its time. It also left a clear opening for a new measurement layer built from dated observations of what is happening in the world.

Researchers have published more than 400 factors. The [A Census of the Factor Zoo](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3341728) shows why a factor needs careful definition, transparent construction, and honest validation. Research on [factor decay](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2156623) shows why signals need to be monitored after publication. The [replication literature](https://academic.oup.com/rfs/article/33/5/2019/5236964) is a reminder that a result is more useful when other researchers can reproduce the construction.

Text contains information that prices and filings do not. A news report can describe a military escalation, an export restriction, a new epidemic, or a change in central-bank language before the event has a clean financial representation. The problem is turning that language into a dated, comparable measurement without hiding the research choices or obscuring the researcher's judgment.

NOSIBLE World provides the point-in-time event archive. `semantic-factors` provides the definition layer. Together they let a quant researcher ask a direct question: what did the world say about this risk on each day in the archive?

## A worked example: geopolitical risk

The gallery below shows the public package-rendered outputs for 30 example semantic factors. The geopolitical-risk definition uses 24 relevance anchors and 3 polarity pairs. The full definition is visible in the [semantic-factors explorer](https://nosible.com/semantic-factors#explorer), where the anchors, polarity sentences, code, research references, CSV, and chart can be inspected together.

The following is a complete runnable example using the full geopolitical-risk definition. It uses the same public World search path as the published example and requires a NOSIBLE API key plus an OpenRouter API key to recompute the series.

```
import os
from pathlib import Path

from semantic_factors import SemanticFactor

anchors = [
    "Military forces attack, invade, or occupy another sovereign state's territory.",
    "Fighting expands across new fronts and into populated civilian areas.",
    "A ceasefire collapses and sustained combat operations resume.",
    "Air strikes or naval attacks hit another country's territory.",
    "A government sends troops and weapons across an international border to begin hostilities.",
    "Armed forces exchange direct fire across a disputed frontier zone.",
    "An organised group bombs or shoots civilians to cause terror.",
    "A state-backed group sabotages a cross-border pipeline used by a rival government.",
    "An armed proxy attacks shipping, airports, or energy facilities abroad.",
    "Armed attackers seize a civilian district and hold it against national security forces.",
    "An armed cross-border movement attacks a border post and demands political concessions.",
    "Security services report a credible plot against major government buildings.",
    "Two governments exchange threats and move toward an open confrontation.",
    "A territorial dispute worsens and both claimants reinforce their garrisons.",
    "Diplomatic talks break down and each government withdraws its ambassador.",
    "Rival warships or aircraft conduct dangerous manoeuvres near each other.",
    "A government issues an ultimatum demanding the withdrawal of foreign troops from disputed territory.",
    "Rival states expel diplomats and suspend their longstanding treaties.",
    "An attempted coup challenges control of an elected national government.",
    "Security forces lose control of major cities during mass protests.",
    "A disputed election leads to violence between rival armed movements.",
    "Armed factions fight each other for control of national territory.",
    "A government collapses and no authority can enforce public order.",
    "Insurgents seize provinces and the national army withdraws from them.",
]

poles = [
    (
        [
            "Direct interstate combat is occurring between organized armed forces.",
        ],
        [
            "No direct interstate combat is occurring between organized armed forces.",
        ],
    ),
    (
        [
            "An organized political-violence attack against civilians is active.",
        ],
        [
            "No organized political-violence attack against civilians is active.",
        ],
    ),
    (
        [
            "Two governments have severed diplomatic relations during an active security dispute.",
        ],
        [
            "Two governments maintain diplomatic relations during an active security dispute.",
        ],
    ),
]

factor = SemanticFactor(
    name="gpr_global",
    anchors=anchors,
    poles=poles,
    filters=None,
    floor=0.30,
    aggregate="max",
)

output = Path("output")
output.mkdir(parents=True, exist_ok=True)

factor.compute(
    weights="netlocs",
    residualize=False,
    stabilize=True,
    polarity_weighted=True,
    start_from="2015-01-01",
    stop_at="2026-06-26",
    api_key=os.environ["NOSIBLE_API_KEY"],
    embed_api_key=os.environ["OPENROUTER_API_KEY"],
)

factor.to_csv(
    path=str(output / "gpr_global.csv"),
)

factor.plot(
    title="Geopolitical risk",
    annotate=False,
    path=str(output / "gpr_global.png"),
)
```

The full geopolitical-risk definition has 24 relevance anchors and 3 polarity pairs. Inspect and edit every sentence in the [semantic-factors explorer](https://nosible.com/semantic-factors#explorer), then replace them with your own research question.

## From a factor to a stock beta

Once the factor has been computed, estimate a stock-specific loading by aligning the factor and market data on the same weekly clock:

```
r_i,t = alpha_i + beta_market,i * r_market,t
         + beta_semantic,i * Delta F_t + epsilon_i,t
```

Here, r_i,t is the stock return, r_market,t is the SPY return, and Delta F_t is the change in the weekly semantic factor. The beta input uses the same 0.25-0.50, k=6 squash as the public charts, followed by the 30-day log1p geometric mean. The seven-day average shown for presentation is not used in the regression because it adds avoidable lag. The calculation uses EODHD adjusted closes, SPY.US as the market control, and standardizes the weekly factor change over the overlapping regression window. The published GPR example has 586 overlapping weekly observations.

These are real historical OLS outputs from the public example, not placeholder values:

| Stock | Role | GPR semantic beta |
| --- | --- | --- |
| RTX.US | defense | +0.110% |
| LMT.US | defense | +0.199% |
| CAT.US | industrial | +0.027% |
| DAL.US | airline | +0.066% |

These values use one signal definition across every stock. The defense names have positive loadings in this sample, while the industrial and airline estimates are smaller. That is the kind of cross-sectional difference the factor is intended to expose, not a hand-written interpretation of one company.

A positive loading means the stock tended to have a higher return when the standardized weekly factor change was positive, after controlling for the market in this specification. A negative loading means the opposite association. A beta is a conditional historical association, not a claim that the factor caused the return or that the relationship will persist.

The [semantic-factors page](https://nosible.com/semantic-factors) lets you switch between all 30 factors and inspect their company beta outputs. The numbers belong to a measurement window, model specification, and data source. They are inputs for research, not investment recommendations or promises about future performance.

This is not a one-to-one reproduction of the published GPR methodology. The corpus, event definitions, anchors, threshold, weighting, polarity construction, and aggregation are different. The point is to make a new semantic factor possible, inspectable, and reproducible from the World data.

## See the 30 semantic factors

These are package-rendered outputs from the current public snapshot, not mock data. Click any chart to open the full-resolution image. The same definitions, code, and downloadable data are available in the [semantic-factors explorer](https://nosible.com/semantic-factors#explorer).

[![Geopolitical risk semantic factor chart](https://nosible.com/data/semantic-factors/plots/gpr_global.png?v=20260805) Geopolitical risk semantic factor chart 01 / Geopolitical risk](https://nosible.com/data/semantic-factors/plots/gpr_global.png?v=20260805)

[![Trade policy uncertainty semantic factor chart](https://nosible.com/data/semantic-factors/plots/tpu_us.png?v=20260805) Trade policy uncertainty semantic factor chart 02 / Trade policy uncertainty](https://nosible.com/data/semantic-factors/plots/tpu_us.png?v=20260805)

[![Pandemic and health risk semantic factor chart](https://nosible.com/data/semantic-factors/plots/pandemic_health_us.png?v=20260805) Pandemic and health risk semantic factor chart 03 / Pandemic and health risk](https://nosible.com/data/semantic-factors/plots/pandemic_health_us.png?v=20260805)

[![Sanctions and export controls semantic factor chart](https://nosible.com/data/semantic-factors/plots/sanctions_us.png?v=20260805) Sanctions and export controls semantic factor chart 04 / Sanctions and export controls](https://nosible.com/data/semantic-factors/plots/sanctions_us.png?v=20260805)

[![Recession nowcast semantic factor chart](https://nosible.com/data/semantic-factors/plots/recession_nowcast_us.png?v=20260805) Recession nowcast semantic factor chart 05 / Recession nowcast](https://nosible.com/data/semantic-factors/plots/recession_nowcast_us.png?v=20260805)

[![Oil supply risk semantic factor chart](https://nosible.com/data/semantic-factors/plots/oil_supply_risk.png?v=20260805) Oil supply risk semantic factor chart 06 / Oil-supply risk](https://nosible.com/data/semantic-factors/plots/oil_supply_risk.png?v=20260805)

[![Supply chain pressure semantic factor chart](https://nosible.com/data/semantic-factors/plots/supply_chain_pressure.png?v=20260805) Supply chain pressure semantic factor chart 07 / Supply-chain pressure](https://nosible.com/data/semantic-factors/plots/supply_chain_pressure.png?v=20260805)

[![Economic policy uncertainty semantic factor chart](https://nosible.com/data/semantic-factors/plots/epu_us.png?v=20260805) Economic policy uncertainty semantic factor chart 08 / Economic policy uncertainty](https://nosible.com/data/semantic-factors/plots/epu_us.png?v=20260805)

[![Financial stress semantic factor chart](https://nosible.com/data/semantic-factors/plots/financial_stress_global.png?v=20260805) Financial stress semantic factor chart 09 / Financial stress](https://nosible.com/data/semantic-factors/plots/financial_stress_global.png?v=20260805)

[![Energy security semantic factor chart](https://nosible.com/data/semantic-factors/plots/energy_security_us.png?v=20260805) Energy security semantic factor chart 10 / Energy security](https://nosible.com/data/semantic-factors/plots/energy_security_us.png?v=20260805)

[![Inflation attention semantic factor chart](https://nosible.com/data/semantic-factors/plots/inflation_attention_us_current.png?v=20260805) Inflation attention semantic factor chart 11 / Inflation attention](https://nosible.com/data/semantic-factors/plots/inflation_attention_us_current.png?v=20260805)

[![Climate policy uncertainty semantic factor chart](https://nosible.com/data/semantic-factors/plots/climate_policy_uncertainty_us.png?v=20260805) Climate policy uncertainty semantic factor chart 12 / Climate-policy uncertainty](https://nosible.com/data/semantic-factors/plots/climate_policy_uncertainty_us.png?v=20260805)

[![Bank regulation uncertainty semantic factor chart](https://nosible.com/data/semantic-factors/plots/bank_reg_uncertainty_us.png?v=20260805) Bank regulation uncertainty semantic factor chart 13 / Bank-regulation uncertainty](https://nosible.com/data/semantic-factors/plots/bank_reg_uncertainty_us.png?v=20260805)

[![Fiscal uncertainty semantic factor chart](https://nosible.com/data/semantic-factors/plots/fiscal_uncertainty_us.png?v=20260805) Fiscal uncertainty semantic factor chart 14 / Fiscal uncertainty](https://nosible.com/data/semantic-factors/plots/fiscal_uncertainty_us.png?v=20260805)

[![Country geopolitical risk semantic factor chart](https://nosible.com/data/semantic-factors/plots/gpr_us.png?v=20260805) Country geopolitical risk semantic factor chart 15 / Country geopolitical risk](https://nosible.com/data/semantic-factors/plots/gpr_us.png?v=20260805)

[![Bilateral tension semantic factor chart](https://nosible.com/data/semantic-factors/plots/bilateral_tension_us.png?v=20260805) Bilateral tension semantic factor chart 16 / Bilateral tension](https://nosible.com/data/semantic-factors/plots/bilateral_tension_us.png?v=20260805)

[![Nuclear threat semantic factor chart](https://nosible.com/data/semantic-factors/plots/nuclear_threat_us.png?v=20260805) Nuclear threat semantic factor chart 17 / Nuclear threat](https://nosible.com/data/semantic-factors/plots/nuclear_threat_us.png?v=20260805)

[![Food security semantic factor chart](https://nosible.com/data/semantic-factors/plots/food_security_us.png?v=20260805) Food security semantic factor chart 18 / Food security](https://nosible.com/data/semantic-factors/plots/food_security_us.png?v=20260805)

[![Commodity supply risk semantic factor chart](https://nosible.com/data/semantic-factors/plots/commodity_supply_risk_us.png?v=20260805) Commodity supply risk semantic factor chart 19 / Commodity supply risk](https://nosible.com/data/semantic-factors/plots/commodity_supply_risk_us.png?v=20260805)

[![Sovereign distress semantic factor chart](https://nosible.com/data/semantic-factors/plots/sovereign_distress_us.png?v=20260805) Sovereign distress semantic factor chart 20 / Sovereign distress](https://nosible.com/data/semantic-factors/plots/sovereign_distress_us.png?v=20260805)

[![Risk on risk off semantic factor chart](https://nosible.com/data/semantic-factors/plots/risk_off_global.png?v=20260805) Risk on risk off semantic factor chart 21 / Risk-on / risk-off](https://nosible.com/data/semantic-factors/plots/risk_off_global.png?v=20260805)

[![Migration policy semantic factor chart](https://nosible.com/data/semantic-factors/plots/migration_policy_us.png?v=20260805) Migration policy semantic factor chart 22 / Migration policy](https://nosible.com/data/semantic-factors/plots/migration_policy_us.png?v=20260805)

[![Currency crisis semantic factor chart](https://nosible.com/data/semantic-factors/plots/currency_crisis_usd.png?v=20260805) Currency crisis semantic factor chart 23 / Currency crisis](https://nosible.com/data/semantic-factors/plots/currency_crisis_usd.png?v=20260805)

[![Cyber risk semantic factor chart](https://nosible.com/data/semantic-factors/plots/cyber_risk_us.png?v=20260805) Cyber risk semantic factor chart 24 / Cyber risk](https://nosible.com/data/semantic-factors/plots/cyber_risk_us.png?v=20260805)

[![Terrorism and unrest semantic factor chart](https://nosible.com/data/semantic-factors/plots/terror_unrest_us.png?v=20260805) Terrorism and unrest semantic factor chart 25 / Terrorism and unrest](https://nosible.com/data/semantic-factors/plots/terror_unrest_us.png?v=20260805)

[![Partisan conflict semantic factor chart](https://nosible.com/data/semantic-factors/plots/partisan_conflict_us.png?v=20260805) Partisan conflict semantic factor chart 26 / Partisan conflict](https://nosible.com/data/semantic-factors/plots/partisan_conflict_us.png?v=20260805)

[![Monetary policy uncertainty semantic factor chart](https://nosible.com/data/semantic-factors/plots/mpu_fed.png?v=20260805) Monetary policy uncertainty semantic factor chart 27 / Monetary policy uncertainty](https://nosible.com/data/semantic-factors/plots/mpu_fed.png?v=20260805)

[![Equity volatility tracker semantic factor chart](https://nosible.com/data/semantic-factors/plots/equity_volatility_us.png?v=20260805) Equity volatility tracker semantic factor chart 28 / Equity volatility tracker](https://nosible.com/data/semantic-factors/plots/equity_volatility_us.png?v=20260805)

[![Firm level political risk semantic factor chart](https://nosible.com/data/semantic-factors/plots/firm_political_risk_us.png?v=20260805) Firm level political risk semantic factor chart 29 / Firm-level political risk](https://nosible.com/data/semantic-factors/plots/firm_political_risk_us.png?v=20260805)

[![Hawk dove sentiment semantic factor chart](https://nosible.com/data/semantic-factors/plots/fed_hawk_dove.png?v=20260805) Hawk dove sentiment semantic factor chart 30 / Hawk-dove sentiment](https://nosible.com/data/semantic-factors/plots/fed_hawk_dove.png?v=20260805)

Download the [combined 30-factor daily CSV](https://nosible.com/data/semantic-factors/nosible-macro-risk-indicators-daily.csv), inspect the [full semantic-factor page](https://nosible.com/semantic-factors), or open the [package repository on GitHub](https://github.com/NosibleAI/semantic-factors).

## What you can do with it

With `semantic-factors`, a quant team can:

- monitor a risk vendors do not cover in the language your team uses;
- measure a developing exposure before it appears in a conventional risk report;
- build differentiated signals from a transparent research definition;
- compare the same concept across countries, sectors, or event scopes;
- rerun the measurement when the question changes without waiting for vendors.

The library is useful for research that begins with a question rather than a ticker. What does escalation look like in the news? How does a supply shock appear in the text? Which companies have historically moved with the resulting time series?

## Why not just ask an LLM?

An answer from an LLM is not a dated time series. It is difficult to reproduce, difficult to audit, and usually disconnected from a fixed historical corpus.

`semantic-factors` uses a point-in-time World archive, explicit sentences, a declared threshold, and a deterministic aggregation path. The output can be inspected event by event. The definition can be versioned. The CSV can be downloaded. The chart can be regenerated. A colleague can challenge an anchor or a polarity pair and rerun the measurement.

This makes the system useful for research workflows where the question matters as much as the number. It does not remove judgment. It puts judgment where a researcher can see, test, challenge, and carefully revise it.

## Get started

Install the open-source package:

```
python -m pip install "semantic-factors[plot]"
```

To recompute a factor, you need access to NOSIBLE World and an embedding provider:

```
export NOSIBLE_API_KEY=nos_sk_...
export OPENROUTER_API_KEY=sk-or-...
```

The public page includes a snapshot of the 30 worked examples so you can inspect the definitions and outputs without recomputing them. When you are ready to build your own, start with a concept, write the sentences, and run the package.

[Explore the 30 semantic factors](https://nosible.com/semantic-factors) [Start a NOSIBLE trial](https://nosible.com/start-trial) [View the package on GitHub](https://github.com/NosibleAI/semantic-factors)

For fifty years, quantitative researchers have turned observations into factors. Now the observation can begin with the words describing what is happening in the world.

[All Research](https://nosible.com/blog)

Related Research

![Signed contrast number line separating systemic and idiosyncratic risk](https://nosible.com/images/2026/06/walkthrough_step9_number_line.png)

[Artificial Intelligence](https://nosible.com/blog/tag/artificial-intelligence)

[Machine Learning](https://nosible.com/blog/tag/machine-learning)

[Risk Indicator](https://nosible.com/blog/tag/risk-indicator)

[NOSIBLE World](https://nosible.com/blog/tag/nosible-world)

### [Two Tricks for Turning Sentence Embeddings into Clean Features](https://nosible.com/blog/the-contrastive-geometry-of-risk)

2026-06-18

14 min read

![Daily NOSIBLE Trade Policy Uncertainty index compared with the published index](https://nosible.com/images/2026/06/nosible-tpu-daily.png)

[Artificial Intelligence](https://nosible.com/blog/tag/artificial-intelligence)

[Machine Learning](https://nosible.com/blog/tag/machine-learning)

[Risk Indicator](https://nosible.com/blog/tag/risk-indicator)

[NOSIBLE World](https://nosible.com/blog/tag/nosible-world)

### [An Embedding-Based Approach to Trade and Economic Policy Uncertainty](https://nosible.com/blog/an-embedding-based-approach-to-trade-and-economic-policy-uncertainty)

2026-06-17

23 min read

![S&P 500 news-stress overlay with drawdown and signal thresholds](https://nosible.com/images/2026/06/news-stress-overlay-hero.png)

[Trading Signals](https://nosible.com/blog/tag/trading-signals)

[Risk Indicator](https://nosible.com/blog/tag/risk-indicator)

[NOSIBLE World](https://nosible.com/blog/tag/nosible-world)

### [Turning News into a Risk-On/Risk-Off Equity Signal](https://nosible.com/blog/turning-news-into-a-risk-on-risk-off-equity-signal)

2026-06-16

9 min read

> Learn how semantic-factors turns NOSIBLE World web text into transparent daily risk factors and stock-specific betas for quantitative research.

**URL:** https://nosible.com/blog/the-future-that-could-have-been-turning-web-text-into-semantic-stock-betas
