typola

typola: probabilistic models over linguistic typology source data.

Public API organized in layers that can be used independently:

  • typola.sources — describe and acquire raw typology datasets (WALS, Grambank, …)

  • typola.prep — parse raw CLDF data into a canonical Typology

  • typola.estimators— pluggable count-to-probability strategies (MLE, Laplace, Jeffreys, …)

  • typola.models — probabilistic models: marginal, conditional, joint

  • typola.query — high-level querying / drill-down API

Typical usage:

from typola import load, query, estimators

wals = load("wals")                       # → Typology
dist = query(wals, target="81A",          # Order of Subject and Verb
             given={"family": "Austronesian"},
             estimator=estimators.laplace(alpha=0.5))
dist.to_frame()                           # DataFrame of (code, name, prob)
class typola.Conditional(typology: Typology, target: str, given: str, *, condition: Mapping[str, Any] | None = None, parameter_conditions: Mapping[str, Any] | None = None, estimator: Estimator | None = None, drop_missing: bool = True)[source]

CPT for P(target | given), over languages of the typology.

Each row is a value of the given parameter; the row is a Distribution over values of the target parameter, built from the joint count table by applying the estimator row-wise.

The matrix form is also exposed as a DataFrame via .as_matrix().

Example

>>> from typola import load, estimators
>>> from typola.models import Conditional
>>> wals = load("wals")
>>> cpt = Conditional(wals, target="83A", given="82A",
...                   estimator=estimators.laplace(0.5))
>>> cpt.as_matrix().head()         # rows = 82A codes, cols = 83A codes
>>> cpt.p_given("82A-1").top_k(3)  # distribution over 83A when 82A=82A-1
as_matrix() DataFrame[source]

CPT as a DataFrame (rows = given code, cols = target code).

mutual_information(*, base: float = 2.0) float[source]

Pointwise MI I(target; given) in bits.

Computed from the estimator-smoothed joint via row-normalized CPT and the corresponding marginal over given. Useful for ranking which parameter pairs actually co-vary.

p_given(given_value) Distribution[source]

Distribution over target values given given_value.

class typola.Marginal(typology: Typology, parameter: str, *, condition: Mapping[str, Any] | None = None, parameter_conditions: Mapping[str, Any] | None = None, estimator: Estimator | None = None, drop_missing: bool = True)[source]

Build a Distribution over one parameter’s values.

This is the entry point for P(parameter value | condition). The condition is any filter on language metadata columns (see Typology.filter_languages). The count→probability strategy is specified by estimator.

Example

>>> from typola import load, estimators
>>> from typola.models import Marginal
>>> wals = load("wals")
>>> dist = Marginal(
...     wals, "81A",
...     condition={"Family": "Austronesian"},
...     estimator=estimators.laplace(0.5),
... ).distribution
>>> dist.top_k(3)
class typola.Typology(name: str, languages: DataFrame, parameters: DataFrame, codes: DataFrame, values: DataFrame, citation: str = '', metadata: dict = <factory>)[source]

A categorical typology dataset in canonical form.

name

Short identifier like "wals" or "grambank".

Type:

str

languages

One row per language. Indexed by Language_ID. Expected columns include Name, Macroarea, Latitude, Longitude, Glottocode, Family.

Type:

pd.DataFrame

parameters

One row per parameter (grammatical feature). Indexed by Parameter_ID. Expected columns: Name, Description.

Type:

pd.DataFrame

codes

One row per possible value for a parameter. Indexed by Code_ID. Expected columns: Parameter_ID, Name, Description, Number.

Type:

pd.DataFrame

values

Long-format observations: one row per (language, parameter) with the observed value. Columns: Language_ID, Parameter_ID, Value, Code_ID, and any source/comment columns.

Type:

pd.DataFrame

citation

A bibliographic citation string for the dataset.

Type:

str, optional

metadata

Any additional metadata (CLDF metadata JSON, download info, etc.).

Type:

dict, optional

code_labels(parameter: str) Series[source]

Series mapping Code_ID → human-readable name for a parameter.

counts(parameter: str, *, condition: Mapping[str, Any] | None = None, parameter_conditions: Mapping[str, Any] | None = None, drop_missing: bool = True) Series[source]

Count languages by code for a parameter, optionally conditioned.

Returns a Series indexed by Code_ID (for parameters that use codes) or by raw Value (when no codes are defined), with integer counts. Codes present in the parameter’s code table but not observed are included with count 0.

Parameters:
  • parameter (str) – Parameter ID or name (via parameter_id).

  • condition (mapping, optional) – Filter on languages columns, see filter_languages.

  • parameter_conditions (mapping, optional) – Filter to languages whose other-parameter values match, see filter_languages.

  • drop_missing (bool) – If True, ignore rows with NaN / missing / “?” values (common in Grambank).

filter_languages(condition: Mapping[str, Any] | None = None, *, parameter_conditions: Mapping[str, Any] | None = None) Index[source]

Return Language_IDs matching language-metadata AND parameter-value conditions.

Parameters:
  • condition (mapping, optional) –

    Filter on languages columns, {column: value_or_iterable_or_callable}:

    • scalar (str / int / bool) → exact match

    • list/tuple/set → membership

    • callable → predicate applied to the column value

  • parameter_conditions (mapping, optional) –

    Filter to languages whose values for given parameters match. Keys are parameter IDs or names; values can be a single code ID, a Value, or an iterable of acceptable codes/values. Example:

    parameter_conditions={"83A": "83A-2"}            # OV order
    parameter_conditions={"81A": ["81A-1", "81A-2"]} # SOV or SVO
    

  • IDs. (An empty/None condition + empty parameter_conditions → all language)

joint_counts(param_a: str, param_b: str, *, condition: Mapping[str, Any] | None = None, parameter_conditions: Mapping[str, Any] | None = None, drop_missing: bool = True) DataFrame[source]

Co-occurrence count table for two parameters.

Rows = codes of param_a, columns = codes of param_b. Counts are over languages that have non-missing values for both parameters.

parameter_id(key: str) str[source]

Resolve a parameter by ID or by (case-insensitive) name prefix.

Raises KeyError if nothing matches.

property parameter_names: Series

Series mapping Parameter_ID → Name.

values_for(parameter: str) DataFrame[source]

Return the values DataFrame filtered to a single parameter.

typola.load(name_or_spec: str | SourceSpec, *, local_path: str | Path | None = None, download_if_missing: bool = True, verbose: bool = True) Typology[source]

Load a typology by name.

Parameters:
  • name_or_spec (str or SourceSpec) – The registered name (e.g. "wals") or a spec object.

  • local_path (path-like, optional) – If given, skip download/cache and load from this directory instead. The path can point at the CLDF directory or any ancestor up to the dataset root.

  • download_if_missing (bool) – If False and the source is not cached, raise instead of downloading.

typola.load_from_cldf_dir(path: str | Path, *, name: str | None = None, citation: str = '') Typology[source]

Alias: load a typology from a local CLDF directory with no download.

typola.query(typology: Typology, target: str, *, given: str | None = None, given_value: Any | None = None, condition: Mapping[str, Any] | None = None, parameter_conditions: Mapping[str, Any] | None = None, estimator: Estimator | None = None, drop_missing: bool = True) Distribution | Conditional[source]

Ask a probabilistic question about the typology.

Parameters:
  • typology (Typology)

  • target (str) – Parameter ID or name to ask about.

  • given (str, optional) – Parameter ID or name to condition on. If given without given_value, the full CPT is returned. With given_value, the row distribution is returned.

  • given_value (any, optional) – A specific code/value of the given parameter.

  • condition (mapping, optional) – Filter on language metadata (see Typology.filter_languages).

  • estimator (Estimator, optional) – Count-to-probability strategy. Defaults to Jeffreys.

Returns:

  • Distribution – When given is None, or given and given_value are both set.

  • Conditional – When given is a parameter and given_value is omitted.