vertiq
Telecommunications

Telecommunications

Predict subscriber churn and recharge behaviour, and estimate next-period usage.

Data mapping

Entity
subscriber
Group
circle or region
Profile
generic; configure time windows with verticals.register
SOURCE COLUMNSVERTIQ DATA CONTRACTAbonneDate UsageUsage TypeConsoCirclePlanEntity · identifierEvent · timestampEvent · typeEvent · valueEntity · groupEvent · attributes%Y-%m-%d
Vertiq LM can propose this mapping from the header and sample rows. Column names, value types and the date format are validated against the data before use.

Supported analyses

Reference implementation

from datetime import datetime, timedelta
from vertiq import plugins, rules
from vertiq.mapping import Mapping, apply, repair
from vertiq.tasks import predict_event, predict_value

# rows: the source export as a list of dicts, e.g. list(csv.DictReader(open("export.csv")))
mapping = Mapping.parse({"entity": "Abonne", "time": "Date Usage", "type": "Usage Type", "value": "Conso", "group": "Circle", "attrs": ["Plan"], "date_format": "%Y-%m-%d"})
m, notes = repair(mapping, rows)      # validates column names, value types and date format against the rows
ds, problems = apply(m, rows)         # rows that fail to load are reported, not imputed

@plugins.feature("telco")
def usage_trend(entity, before, cut):   # receives only events recorded before the cutoff
    m1 = sum(e.value for e in before if e.at >= cut - timedelta(days=30))
    m2 = sum(e.value for e in before if cut - timedelta(days=60) <= e.at < cut - timedelta(days=30))
    return {"usage_ratio": (m1 + 1) / (m2 + 1)}

task = predict_event(ds, target="recharge", window_days=30, pack="telco")
print(task.status, task.report())     # "trained" only if the model outperformed the baseline on held-out entities
if task.status == "trained":
    print(task.score("9812345670"))  # probability with contributing factors

size = predict_value(ds, target="data", window_days=30, pack="telco")
print(size.status, size.report())

flags = rules.run(ds, [
    rules.repeat(1, type="complaint"),   # two complaints from one subscriber in a day
])
print(flags["summary"])

This code is executed by the test suite (tests/test_guides.py) against generated records with these column names.

Recommended plugin

usage_trend: A month-on-month decline in usage commonly precedes churn.

Validation rules

  • rules.repeat(1, type="complaint"): two complaints from one subscriber in a day

Implementation notes

  • Pseudonymise phone numbers before they are used as identifiers.

Validation

  • Telecom tables in the Vertiq LM mapping evaluation
  • Every deployment: the evaluation gate measures each model on the organisation's own held-out records before promotion.
← Supply chain and logisticsEnergy and utilities →