Semantic web understanding @ Contentsquare · 2018 – 2024

Zone Taxonomy

Automatically naming the zones of any web page,
straight from its DOM.

DOM tree inzone label per node outserved on TritonSlim Frikha
The product problem

Every page is made of zones

cta_homepage menu search_bar cta_access_cart product_picture product_name product_price cta_add_to_cart reviews footer

A zoning = the flagged zones of a page

Zones with a business meaning are flagged so they can be monitored: each gets its own metrics, and any automatic analysis can use them as page context.

Each zone has a name and a type

NameType
search-field__inputsearch_bar

The name is free text chosen by whoever flags the zone. The type comes from a shared taxonomy.

Zone Taxonomy predicts the type of every node of a page: the labels on the left.

Zone TaxonomyProduct problem
The product problem

Zoning by hand doesn't scale

shop.example.com/cart 0.9% 14.5% 1.9% Shopping bag 1 Continue to checkout Zones list× hnf-header__logo search-field__input Log in or sign up Wish list 2 Shopping bag Continue to checkout product_imageContainer 2

Today in the zoning editor (sketch): open the page, click each element ①, give it a name in the zones list ②. Repeat for every zone, on every page.

Creating zonings is:

1

Too manual: every zone is clicked and named by a person.

2

Cumbersome and time-consuming, page after page.

3

A human bottleneck for every feature that depends on zonings.

GoalFor a given web page, spot and classify the interesting zones, automatically.

auto-RZT pipeline
batch zoning of all retail projects, every two weeks
Labeling extension
live zone suggestions while the labeling team tags pages
Zone TaxonomyProduct problem
The product problem

A taxonomy that depends on the page type

The zones you expect on a checkout page are not the ones you expect on a product page. The label space is defined per page category.

17

page categories

71

distinct zone labels

314

(page category, zone) pairs

Zones defined per page category

checkout 44product 30my_account 30 form 29category 24search 23 cart 22other 17home 13 store_locator 11information_legals 11press_news 10 help_support 10favorites_wishlist 10confirmation 10 careers_applications 10brand_image 10

Plus one background class everywhere: others

Any node that is not a zone. Every page category's label list starts with it.

Zone TaxonomyProduct problem
The product problem · Data

The training set: an annotation campaign

Phase 1 · Kick-start

Data analysts

Internal analysts annotated first, to kick-start the taxonomy and the first models.

Phase 2 · Scale

Labelling company

A labelling company then annotated at scale, same taxonomy.

Rule: annotators tag the biggest node that contains only the zone. Each page is captured with its DOM (HTML, visibility, boxes) and a screenshot.

7,357

annotated pages

320

website domains (final)

~23

pages per domain

4.7M

DOM nodes

187k

labelled zones (4%)

~640

nodes per page

Pages per page category · labelled zones

Chart and node/zone counts: raw m2 extraction (327 domains), before training filters. Final dataset: 320 domains. Dataset versions: v0 Oct 2022, v1 Jan 2024.

Zone TaxonomyData
The product problem · Data

7,357 pages, but only 320 websites

Pages of one site share its templates: they differ only locally (content, a block or two). The big differences are between sites.

320 domains

is the real size of the training set: ≈ 23 pages per domain

1

Variability lives between websites. Markup, CSS naming, language and layout are set per site.

2

More pages of a known site add little. More data points, but not much new variability.

3

Split by domain. If a site were in both train and validation, the model would be scored on templates it has memorised (leakage). Domains are assigned so each zone type keeps a ~75/25 train/validation balance.

4

So validation measures the real task: zoning websites the model has never seen.

Zone TaxonomyData variability
The product problem

Why it's hard

96%

of nodes are background

Only ~4% of nodes carry a zone label: a heavily imbalanced problem.

320

websites, not 7k pages

Each site has its own markup, CSS naming and language. Pages of one site vary only locally.

~640

nodes per page

On average; training pages have 20 to 5,000 visible nodes, serving accepts up to 10,000.

⧉

zones are nested

One visual zone spans several nested nodes. Which one "is" the zone?

<div class="price-wrap"> ← annotated as product_price <span class="price"> ← same price, one level in <b>100€</b> ← the text itself </span> </div>

All three nodes show the same price. The rule tags the biggest node holding only the zone, yet a model may answer one level in. This is the granularity problem; it comes back in the deep dive.

Zone TaxonomyProduct problem
The modeling solution · Design choices

Two choices that shape the solution

1 · What should the model read?

Hand-crafted features

✓ simple, interpretable

✗ tied to the label set, slow to explore

✗ the problem outgrows the features

Computer vision on screenshots

✓ strong pretrained backbones

✓ detection / segmentation models

✗ rendering cost; zone boxes are already known

chosen

The HTML itself, as text

✓ independent of the label set

✓ no rendering needed

✗ a model to craft from scratch

2 · What should it predict?

One zone at a time

✓ simpler modelling and training

✗ no access to parents or neighbours

✗ which snippet: with or without children? Labels differ from user annotations

chosen

Every node of the page at once

✓ sees parents and children; each node keeps only its own HTML

✓ training labels = user annotations

✗ page batching, dynamic tree graphs, long gradient paths

→ Read each node's own HTML, and classify all the nodes of the page together along the DOM tree.
Zone TaxonomyModeling: design choices
The modeling solution

Node classification on a tree

Input: the page's DOM tree (each node's own HTML + visibility) and its page category. Output: one label per node: a zone, or others.

Page DOM tree + page category 1 Node encoder HTML, id, class, attributes, text → 64-d per node 2 Tree context masked tree attention branch + siblings → context per node 3 Page-category head softmax over the zones of that page type 4 Grouping one node per nested cluster → final zones what the node says where the node sits what this page type allows one answer per zone
Zone TaxonomyModeling: overview
Modeling deep dive · 1 Node encoder

What the model reads from a node

Each node's own HTML snippet (without its children) is split into five signals.

<a class="btn add-to-cart" id="atc-btn" title="Add to cart" role="button">Add to cart</a>
SignalWhat is extractedTokensLength
Markup<a class="btn add-to-cart" id="atc-btn" … role="button"></a>characters400
idatc-btncharacters20
classbtn add-to-cartcharacters80
AttributesAdd to cart|button (title, alt, role, type, itemprop, name, label, placeholder, aria-label)characters25
Displayed textAdd to cart → multilingual BERT word-piece embeddings (frozen), text flavourword pieces20 × 768

Characters come from a 102-symbol vocabulary (printable ASCII + padding + unknown). Lengths were fixed from the observed length distributions.

Zone TaxonomyModeling: inputs
Modeling deep dive · 1 Node encoder

One signal, end to end: a character CNN

Same recipe for every signal. Markup and attributes use k = 3, 5, 7, 9; id, class and text use k = 3, 5. Text starts from 768-d BERT word-piece vectors instead of 8-d character embeddings.

markup 64 id 64 class 64 attributes 64 text 64 →dense · dropout 0.3→64-d local vector
Zone TaxonomyModeling: node encoder
Modeling deep dive · 2 Tree context · first version

A node is understood by its surroundings

Pass 1 · leaves → root Pass 2 · root → leaves h=2 h=0 h=1 h=0 children summed into parent "what is inside me" parent context pushed down "where do I sit"

Based on the Child-Sum Tree-LSTM: K. S. Tai, R. Socher, C. D. Manning, Improved Semantic Representations From Tree-Structured Long Short-Term Memory Networks, ACL 2015, arXiv:1503.00075.

Child-sum TreeLSTM: each node combines its own local vector with the summed states of its children, using forget gates per child.

↑

Upward pass computes nodes level by level by height: all leaves at once, then their parents, … up to the root.

↓

Downward pass runs a second TreeLSTM from the root, fed with the upward states, with a residual memory link.

node = [ local (64) ‖ h↑ + h↓ (64) ] → 128-d

A price node now knows it sits under a product block, next to a title and a button.

First version. Replaced by masked tree attention: next slide.

Zone TaxonomyModeling: tree context
Modeling deep dive · 2 Tree context · current version

From TreeLSTM to tree attention

The TreeLSTM runs one step per tree level, twice. Masked attention updates every node at once: parallel and much faster on GPU. Context is still taken in two directions, as two attention tracks:

↕

Branch track (vertical). A node attends to its ancestors and descendants within a hop limit: 6 hops in the real model (1 in this illustration). Farther ones are masked; they don't help the decision.

↔

Sibling track (horizontal). A node attends to the other children of its parent: what sits next to it.

softmax( QKᵀ/√d + M ) V  ·  M = 0 kept, −∞ masked

Real model: two stacked layers bring in first-degree cousins: in layer 1 the grandparent gathers its descendants, in layer 2 the node reads its grandparent. Heavily inspired by TrENC, not identical (±6-hop branch, 2 layers).

Based on TrENC: Li et al., Extracting Shopping Interest-Related Product Types from the Web, arXiv:2305.14549 (2023): path + sibling attention on DOM trees.

Zone TaxonomyModeling: tree attention
Modeling deep dive · 3 Decision

One head per page category

node vector cart head · others, add_promo_code, … product headothers, product_price, cta_add_to_cart, … checkout head · others, card_number, … … one per page category

Each head is small: Linear → sigmoid → Linear → softmax over that page category's zone list.

The page category is an input: it selects which head answers, so a product page can never be given a checkout-only zone.

All page categories share the encoder and the tree-context block, so knowledge transfers across page types.

In training, the loss is masked per head: each node only trains the head of its own page category.

Zone TaxonomyModeling: decision
Modeling deep dive · Training

Learning when 96% of nodes are background

Focal loss

−y · log p · (1 − p)γ, γ = 2

Easy, confidently-correct nodes (most "others") contribute little; the hard ones drive learning.

Prior-aware start

softmax(bias) = others share

Output biases are initialised so the untrained model already predicts "others" at its true frequency, so no wasted early epochs.

Page-category weights

w = max count / count

Page types with fewer training nodes weigh more in the loss.

Invisible nodes give context, not loss

Fully invisible subtrees are removed. Remaining invisible nodes still pass through the tree model but are masked out of the loss and metrics.

One page per step, 16 accumulated

Adam (lr 3·10⁻³), learning rate halved on plateau, early stopping on validation F0.5.

Zone TaxonomyModeling: training
Modeling deep dive · Granularity

"Nearly right" is a real situation

div.price-wrap span.price annotated here b 100€

One price on screen, three nested nodes, one annotation: by rule, the biggest node holding only the zone. If the model answers one level in, it still found the zone.

The near-zone idea is used in three places:

Training · near-zone soft labels

Don't punish the model hard for the levels next to a zone; teach how likely each one is to be the zone.

Evaluation · near-zone tolerance

Score the zone as found when the prediction lands one level off, and count each zone only once.

Serving · grouping

Return one node per nested cluster, with the others listed as synonyms.

Zone TaxonomyGranularity
Granularity · Training

Near-zone soft labels

div.product div.gallery img div.price-wrap span.price b labelled: product_price by rule: the biggest zone node near-certitude · d = 1 target 99% price · weight 0.97 near-certitude · d = 2 target 97% price · weight 0.87 incertitude · d = 1 target 76% others · weight 0.03 sibling branch: not a neighbour → plain "others", full weight
■ near-certitude: single-child chain, ≤ 6 hops ■ incertitude: ≤ 10 hops, ≤ 2 extra branches

Around every labelled node, its ancestors and descendants that are labelled "others" get a soft target and a loss weight, both functions of the tree distance d:

s(d) = tanh(d² / 101.5)
NodeSoft targetLoss weight
near-certitude
likely the same zone
zone: 0.25(1−s)+0.75
99% at d=1 · 80% at d=6
1 − s
incertitude
ambiguous
others: 0.25·s+0.75
76% at d=1 · 95% at d=6
s
labelled node · far nodesone-hot1
Zone TaxonomyGranularity: training
Granularity · Evaluation

An evaluation that measures "zone found"

1

Split by website. No domain is in both train and validation (no template leakage), so the score is about unseen websites. Each (page, zone) pair keeps a ≈75/25 split (±15%).

2

Group predictions like serving does: one node per same-label nested cluster (≤ 8 hops, ≤ 2 extra branches).

3

Near-zone swap. A zone predicted "others" whose neighbour (≤ 3 hops) was predicted with that zone swaps labels with it: the zone counts as found once.

4

Score F0.5 per zone (precision-weighted), averaged over the zones of each page category, then over page categories. This score selects checkpoints and stops training.

Case A · prediction one level off plain scoring div.price-wrapGT price · pred others ✗ span.priceGT others · pred price ✗ → after near-zone swap div.price-wrapGT others · pred others ✓ span.priceGT price · pred price ✓ 1 miss + 1 false alarm becomes 1 hit. Case B · the zone predicted on three levels raw predictions div.price-wrap price 0.81 span.price price 0.62 b price 0.55 → after grouping div.price-wrap price ✓ span.price others b others The zone is counted once: no duplicate false alarms.
Zone TaxonomyGranularity: evaluation
Evaluation · first iteration

First results on unseen websites

76%

custom macro F0.5 on validation websites (96% on training pages)

83.1%

custom macro precision

First dataset: ~400 pages · ~200 websites · 5 page categories · 29 zone types.

F0.5 varies a lot across the 29 zone types

≈ 95%
add-to-cart CTAbreadcrumb · categorysearch bar · cartfirst name · account creation
≈ 90%
search bar · categoryproduct picture · categorysurname · account creationsearch bar · homebreadcrumb · productsearch bar · product
down to ≈ 20%
rare zone types
How the scores are computed (validation nodes)
per zone type z:  Pz = TP/(TP+FP)  ·  Rz = TP/(TP+FN)
                  F0.5z = 1.25·Pz·Rz / (0.25·Pz + Rz)
per page category c:  F0.5c = meanz∈Zc F0.5z  ·  Pc = meanz∈Zc Pz
custom macro:  F0.5 = meanc F0.5c  ·  precision = meanc Pc

Zc = zone types of page category c, others excluded, with support > 0. β = 0.5 weighs precision more than recall.

Zone TaxonomyEvaluation: first results
From prediction to product

Serving: one answer per zone

1

Drop fully invisible subtrees; keep each node's own HTML.

2

Vectorize, run the model, take the page category's head.

3

Group same-label nested clusters: keep the most confident node; the others become its prediction_synonyms.

4

Return the labelled nodes with their confidence, keyed by the caller's node ids (cs_path or xpath).

POST /v2/models/zone_taxonomy/infer DOM tree + page category → zones

In the labeling Chrome extension

ZONE TAXONOMY 1 Page type Cart▾ 2 Launch Zone Taxonomy 3 Display labels

pick the page type, launch, display labels

shop.example.com/cart My cart Product picture 94.8% Product picture 94.8%

predicted zones drawn on the live page, with confidence ("Product picture 94.8%") · sketch

Zone TaxonomyServing
Recap

Zone Taxonomy in four ideas

1

Read every node

Character CNNs over markup, id, class, attributes, plus text.

2

Use the whole tree

Masked tree attention along branches and siblings: what's inside, where it sits.

3

Respect the page type

One head per page category, one shared backbone.

4

Near-zone aware

Soft labels to train, tolerant scoring to evaluate, grouping to serve.

Trained on 320 websites, measured on sites it has never seen: DOM tree in, one confident answer per zone out.

Zone TaxonomyThank you · questions
Sources

To go further

Also referenced

Tree-LSTM (first tree-context version): K. S. Tai, R. Socher, C. D. Manning, Improved Semantic Representations From Tree-Structured Long Short-Term Memory Networks, ACL 2015, arXiv:1503.00075.

Tree attention design: Y. Li, C. Lockard, P. Shiralkar, C. Zhang, Extracting Shopping Interest-Related Product Types from the Web, arXiv:2305.14549 (2023).

Zone TaxonomySources
← → navigate · F fullscreen