Get started
Install and first report
The decision engine is pure Python with no dependencies. One command turns exported tables into a written report; the same steps are available as functions.
Install
pip install vertiq # the decision engine
pip install "vertiq[excel]" # also read .xlsx and .xls exports
pip install "vertiq[lm]" # Vertiq LM tooling (Apple Silicon)A report from exported files
Write a small config naming the files; nothing else is required. Vertiq proposes the mapping from the values, finds how the files join, checks everything against the rows, and writes what it can say and what it cannot say yet.
{"records": {"file": "orders.xlsx"},
"items": {"file": "order_lines.xlsx"},
"entity_table": {"file": "customers.xlsx"},
"noun": "orders", "currency": "₹", "entities": "customers"}vertiq-report config.json --out report.md
What the report contains
- Loading notes: the mapping used, what was checked, rows skipped and why
- What happened: the last period against the one before
- Patterns: every comparison tested, with false-discovery control
- Items bought together, when there are line items
- Predictions that passed the evaluation gate, or the reason they did not
Shapes it recognises
- Records with a separate line-item file (orders and order lines)
- A single line-item file (one row per item)
- One row per entity (a customer list, an asset register)
- Exports with title rows, totals rows and misnamed file types
- Large line-item exports: hundreds of thousands of lines and catalogues of thousands of products
In Python
from vertiq.report import read_table
from vertiq.tables import propose
from vertiq.mapping import repair, apply
from vertiq.tasks import predict_event
from vertiq import patterns, narrate
rows = read_table("orders.xlsx") # CSV or Excel; header found below titles
m, notes = propose(rows) # mapping proposed from the values
m, more = repair(m, rows) # checked against every row
ds, problems = apply(m, rows) # summary rows skipped, placeholder ids kept apart
for f in patterns.find(ds, noun="orders")["found"]:
print(f["text"]) # tested patterns, under false-discovery control
task = predict_event(ds, target="record", window_days=30)
print(narrate.gate(task.report())) # promoted, kept, or why there is not enough data
Domain knowledge goes in as plugins (features, rules, learners), and every addition is judged by the same evaluation gate. See the architecture and the industry guides.