Domain features (raw signals → model-ready)¶
This is where ml4 does what a generic AutoML tool can't. It doesn't treat a
column like 137.118.191.41 or 513 LYNN ST,Hurt,VA,24563 as an opaque string
to hash — it knows what the value means and applies domain knowledge to pull
out the pieces that matter, compute relationships between columns, and hand the
model dozens of typed, explainable features. All of this is
leakage-safe by construction: the parsers are
row-local and stateless, so they fit once and leak nothing.
1. A raw, messy frame¶
Real signup / support data arrives as raw strings — free text, packed tags, composite fields, timestamps. Here every column is exactly as captured:
import pandas as pd
df = pd.DataFrame({
# --- identity & network ---
"ip_string": ["71.87.248.253", "72.87.248.253", "203.0.113.9", "10.0.0.4"],
"email": ["alex.m@gmail.com", "user@mailinator.com", "a@b", "jane.doe@acme.co"],
"signup_url": ["https://acme.co/promo?ref=x", "http://bit.ly/2xyz",
"https://192.168.0.1/", "https://shop.acme.co/cart"],
"user_agent": ["Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120",
"Dalvik/2.1.0 (Linux; Android 10; SM-A515U1)",
"myApp/2.8.9 iPhone", ""],
# --- geography ---
"billing_addr": ["513 LYNN ST,Hurt,VA,24563", "1306 S COOPER ST,KOKOMO,IN,46902",
"1016 SW 29TH ST,OKLAHOMA CITY,OK,73109", "PO BOX 22,TUCSON,AZ,85757"],
"home_zip": ["02467", "02002", "12345", "02135"],
"ship_zip": ["02368", "02467", "02135", "02445"], # a second zip → distance features
"account_owner":["Alex Morgan", "Carter Henderson", "Jamie Small", "Robin Abulafia"],
# --- support-ticket text ---
"subject": ["Refund request for duplicate payment", "Upgrade mobile plan tier",
"Cannot log in after reset", "Downgrade business voice package"],
"description": ["The promotional discount was not applied to my account.",
"Customer would like a faster tier; add an additional line.",
"Password reset email never arrives; blocked at login.",
"Update the billing address and primary contact email."],
"tags": ["billing,refund,urgent", "plan,upsell", "auth,login,bug", "billing,account"],
# --- timestamps ---
"created_at": pd.to_datetime(["2026-03-22", "2026-02-09", "2026-02-14", "2026-04-04"]),
"resolved_at": pd.to_datetime(["2026-03-24", "2026-02-11", "2026-02-14", "2026-04-10"]),
"escalated": [1, 0, 1, 0],
})
2. Route each column to its domain¶
DataConfig (on cfg.data) routes each raw column to the right parser. Nothing
is auto-detected — you assign the domain:
from parleml_ml4 import AutoSupervised, Tasks
from parleml_ml4.config import presets
cfg = presets.quick_explore()
cfg.ml_task = Tasks.BINARY_CLASSIFICATION
cfg.data.target_column = "escalated"
# --- network & identity ---
cfg.data.ip_domain = ["ip_string"] # → country / ASN / org / network type / private / bogon
cfg.data.email_domain = ["email"] # → domain, role / disposable / typo flags, entropy
cfg.data.url_domain = ["signup_url"] # → subdomain / domain / TLD, shortener / IP-literal, path
cfg.data.useragent_domain = ["user_agent"] # → browser / OS / device class, bot flag
# --- geography ---
cfg.data.address_domain = ["billing_addr"] # → number / street / type / city / state / PO-box
cfg.data.zip_domain = ["home_zip", "ship_zip"] # two zips → prefix / place / state + DISTANCE
cfg.data.names_domains = [["account_owner"]] # → known-name, ranks, length / script flags
# --- free text & packed tokens ---
cfg.data.text_domain = ["subject", "description"] # → TF-IDF → SVD topics + per-term target lift
cfg.data.embedding_domain = ["description"] # → neural sentence embeddings, reduced
cfg.data.mt_domain = ["tags"] # comma-separated bags → multi-token target encoding
# --- time ---
cfg.data.time_domain = ["created_at", "resolved_at"] # → calendar parts, weekend / holiday flags
cfg.data.base_time_columns = ["created_at"] # anchor → days-since recency
3. What each domain extracts (the gains)¶
Every raw column becomes many typed features — not one blind hash:
| Raw column | Domain | ml4 extracts / computes |
|---|---|---|
ip_string |
IP | country, region, city, ASN / org, network type, IPv6 / private / bogon flags |
email |
local / domain parts, role / disposable / typo-squat flags, entropy | |
signup_url |
URL | subdomain / domain / TLD, shortener / IP-literal flags, path depth |
user_agent |
User-Agent | browser / OS / device class, bot flag |
billing_addr |
Address | number, street, street-type, city, state, PO-box heuristic |
home_zip, ship_zip |
Postal (×2) | prefix / place / state plus the geographic DISTANCE between the two |
account_owner |
Names | known-name flag, popularity ranks, synthetic-name (repeat / mixed-script) flags |
subject, description |
Text | TF-IDF → SVD topics, per-term target lift, neural embeddings |
tags |
Multi-token | each comma-separated tag target-encoded from the packed bag |
created_at, resolved_at |
Datetime (×2) | calendar parts, weekend / business-hour, holiday flags, days-since anchor |
Relationships across columns, not just within one
With two postal columns in zip_domain, ml4 derives the distance between
home_zip and ship_zip (a classic fraud signal), plus match / prefix-match
flags. The match step also emits cross-source consistency flags — e.g.
"the billing city disagrees with the IP-geolocated city". See
Stateless domain encoders.
4. Fit — parsing happens automatically¶
No manual regexes, gazetteers, or token pipelines: the IP became geo / ASN columns, the address split into street / city / state, the two zips produced a distance, the UA unpacked into OS / device class, the free text became topics + embeddings, the tags were target-encoded per token, and the timestamps became calendar + recency features — every one traced in the feature recipe for audit.
IP features need a MaxMind database — but degrade gracefully
The ip_domain geo / ASN features need the MaxMind GeoLite2 databases, which
aren't bundled for licensing reasons. Unlike a hard failure, ml4 degrades
to null for those features (with a one-time warning) and still emits the
stdlib flags (private, bogon, IPv6). Set the databases up per the
reference-data guide, or leave ip_domain=[].
See the FE suite guide, the
stateless and stateful
encoder catalogues, and the Geography & reference data guide
for the MaxMind setup and the country setting.
Next: Geography & reference data · Stateless domain encoders