{% extends "base.html" %}
{% from "_macros.html" import weight %}
{% set active = "model:" ~ entity_type %}
{% block title %}{{ entity_type|capitalize }} model{% endblock %}
{% block topbar %}{{ icon("chart-dots") }} {{ entity_type|capitalize }} model
{% if source %}{{ source }}{% endif %}{% endblock %}
{% block content %}
{% if fs is none %}
No model yet. One is fitted on the first run with enough observations.
{% else %}
Strong edge at
{{ "%.1f"|format(threshold) }} bits
floor {{ profile.min_strong_weight }}
Contradiction at or below
{{ "%.1f"|format(t_low) }} bits
between: contested
Match rate among candidates
{{ "%.3f"|format(fs.lam) }}
λ, fitted by EM
Comparisons
{{ comparisons|length }}
{% if fs.unlearned %}unlearned: {{ fs.unlearned|join(', ') }}{% else %}all learned{% endif %}
Each comparison sorts a pair into one level. A level's weight is log₂(m/u): how much more often it occurs among matching pairs (m) than among random pairs (u). Weights add up; caps hold levels that also occur between related but distinct entities at or below a ceiling.
{% for c in comparisons %}
{{ icon("scale", 14) }} {{ c.name }} {{ c.features|join(', ') }}
| Level | m | u | Weight (bits) | Notes |
{% for l in c.levels %}
| {{ l.label }} | {{ "%.4f"|format(l.m) }} | {{ "%.5f"|format(l.u) }} | {{ weight(l.weight) }} |
{% if l.cap is not none %}capped at {{ l.cap }} {% endif %}{% if l.relationship %}relationship signal{% endif %} |
{% endfor %}
{% endfor %}
{% endif %}
{{ icon("adjustments-horizontal", 14) }} Profile {{ profile.ref.ref }}
| Attribute | Type | Cardinality | Sensitivity | To external models |
{% for name, a in profile.attributes.items() %}
| {{ icon(ATTRIBUTE_ICONS.get(name, 'circle-dashed'), 14) }} {{ name }} | {{ a.data_type }} | {{ a.cardinality }} | {{ a.sensitivity }} | {{ a.external_model_policy }} |
{% endfor %}
{% endblock %}