Predictive Lead Scoring Explained, with Real Code
How predictive scoring learns from won and lost deals, with a runnable Python model and how to read its results
Predictive lead scoring explained in plain English, plus a complete Python model: train it, score leads 0-100 and check it on unseen data.
Predictive lead scoring uses your past won and lost deals to learn which lead behaviours and attributes predict a sale, then gives every new lead a probability score so your team contacts the likeliest buyers first. Unlike rule-based scoring, where someone guesses that a pricing-page visit is worth ten points, the weights come from your own data and are re-checked against outcomes.
This guide explains how it works, what data you need, and then walks through a complete working model in Python that you can run yourself. If you are choosing criteria for a manual model first, read lead scoring criteria: build a model sales trusts. For the overview of model types, see predictive lead scoring: how the models work. This post is the hands-on version: how a predictive model is actually built and checked, with code.
What is predictive lead scoring?
Predictive lead scoring is a statistical model that estimates the likelihood that a lead will become a customer. It looks at leads you have already won or lost, finds the patterns that separated them, and applies those patterns to new leads.
The output is usually a number from 0 to 100, which you can read as "how similar is this lead to the ones that bought". That number is then used to route, prioritise or nurture, for example sending high scores to a salesperson within minutes and low scores to an automated email sequence.
How is it different from rule-based scoring?
- Rule-based scoring relies on human judgement. You assign points to actions and attributes, add them up and set a threshold. It is transparent and quick to start, but the weights are guesses and drift out of date.
- Predictive scoring learns the weights from outcomes. It can capture combinations and weightings people would not think of, and it can be retrained as behaviour changes.
Predictive scoring is not magic and it is not always better. It needs enough history, it inherits any bias in that history, and it needs maintenance. A good rule-based model is a sensible starting point and a useful benchmark to beat.
What data do you need?
Outcomes
You need a clear label for each historical lead: won or lost. Define "won" precisely, for example "became a paying customer within 90 days of creation", and apply the same definition to every lead.
Features
Features are the facts about each lead that the model can learn from. They fall into three groups:
- Behaviour: page views, email clicks, demo requests, replies, time since last activity.
- Profile: company size band, role seniority, region, lead source.
- Timing: how quickly the lead moved between steps, and how recent the activity is.
Volume
There is no single magic number, but the model needs a meaningful number of both won and lost leads. If you have only a handful of wins, a simple rule-based model plus careful review will usually serve you better until you have more history.
Avoid leaking the answer
Do not include anything that is only known after the outcome, such as "contract sent" or "opportunity amount". The model will look brilliant in testing and be useless on new leads, because those facts do not exist yet when a lead arrives. Use only information available at the moment you want to score.
A working predictive lead scoring model in Python
The script below creates a synthetic lead history so it runs anywhere, trains a logistic regression model, scores unseen leads from 0 to 100 and checks how well the scores separate buyers from non-buyers. In real use, you replace the synthetic dataset with an export from your CRM using the same column layout. It uses scikit-learn's LogisticRegression, which is simple, fast and explainable.
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
rng = np.random.default_rng(42)
n = 5000
# 1. Synthetic lead history (stand-in for an export from your CRM)
leads = pd.DataFrame({
"pricing_views": rng.poisson(1.2, n),
"email_clicks": rng.poisson(2.0, n),
"demo_requested": rng.binomial(1, 0.08, n),
"days_since_last_visit": rng.integers(0, 60, n),
"company_size_band": rng.integers(1, 5, n), # 1 = smallest, 4 = largest
})
# Hidden "truth" used only to create the won/lost label for this demo
signal = (-3.2
+ 0.55 * leads.pricing_views
+ 0.12 * leads.email_clicks
+ 2.0 * leads.demo_requested
- 0.03 * leads.days_since_last_visit
+ 0.35 * leads.company_size_band)
leads["won"] = rng.binomial(1, 1 / (1 + np.exp(-signal)))
# 2. Split BEFORE fitting so the test set stays unseen
X = leads.drop(columns="won")
y = leads["won"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=7, stratify=y)
# 3. Fit a simple, explainable model
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
# 4. Score the unseen leads: probability of winning, as 0-100
test = X_test.copy()
test["score"] = (model.predict_proba(X_test)[:, 1] * 100).round()
test["won"] = y_test
# 5. Check it
print("Overall win rate:", round(y_test.mean() * 100, 1), "%")
print("AUC:", round(roc_auc_score(y_test, test["score"]), 3))
top = test.sort_values("score", ascending=False).head(len(test) // 10)
print("Win rate in top 10% of scores:", round(top["won"].mean() * 100, 1), "%")
bottom = test.sort_values("score").head(len(test) // 10)
print("Win rate in bottom 10% of scores:", round(bottom["won"].mean() * 100, 1), "%")
for name, coef in zip(X.columns, model.coef_[0]):
print(f"{name:24s} {coef:+.2f}")
What the code does, step by step
1. Create the lead history
Five features describe each lead: pricing-page views, email clicks, whether a demo was requested, days since the last visit and a company size band. The "won" label is generated from a hidden formula only so this demo has a real pattern to find. With your own data, the label comes from your CRM and you skip that block.
2. Split before you fit
The data is split into a training set and a test set before any learning happens. The test set plays the role of new, unseen leads. Evaluating on the same data you trained on would flatter the model.
3. Fit an explainable model
Logistic regression learns one weight per feature. Positive weights push a lead's probability up, negative weights push it down. That makes the result easy to explain to a sales team, which matters for adoption.
4. Turn probabilities into scores
The model outputs a probability of winning between 0 and 1. Multiplying by 100 gives a familiar score. You can then set thresholds, for example "hot" above a chosen cut-off, based on how many leads your team can actually work.
5. Check it on unseen leads
Two checks matter most. AUC tells you how well scores rank winners above losers, where 0.5 is no better than chance and 1.0 is perfect. The top-and-bottom comparison shows what the business cares about: do the highest-scored leads actually win more often than the lowest?
What the output looked like when we ran it
We ran the script exactly as written, using the fixed random seeds shown. Remember this is synthetic data, so the numbers show how to read the output, not what you should expect in your own pipeline.
- The overall win rate in the test set was 14.4%.
- The AUC was 0.72.
- In the top 10% of scores, the win rate was 46.4%. In the bottom 10% it was 2.4%.
The learned weights also matched the pattern we built in: a requested demo carried the largest positive weight (about +2.07), pricing views were next (about +0.59), and days since the last visit pulled scores down slightly (about -0.03 per day). This is the useful part of a simple model. You can see why a lead scored high.
The key takeaway is the gap between the top and bottom groups. A team working only the top tenth of this list would meet far more buyers per hour than a team working leads in random order.
Turning the model into a live process
- Export a clean history from your CRM with a consistent definition of won and lost.
- Train and validate using a holdout set, and compare against your current rule-based score as a benchmark.
- Write scores back to a field on the lead record automatically, with a timestamp and model version.
- Act on the score: route high scores to a salesperson quickly, nurture the middle, and keep a human review path for borderline cases.
- Monitor and retrain on a regular schedule, and whenever your offer, pricing or lead sources change.
Common pitfalls
- Data leakage: including facts that are only known after the outcome.
- Tiny or lopsided history: too few wins to learn from reliably.
- Judging by accuracy alone: when most leads lose, a model can look accurate by predicting "lost" every time. Use AUC and top-versus-bottom comparisons instead.
- Bias in the past: if past sellers ignored certain leads, the model may learn to ignore them too. Review what the model rewards.
- Set and forget: behaviour changes, so scores drift. Schedule retraining and checks.
- No action attached: a score nobody uses is just a number. Tie each band to a clear next step.
How Insyrge can help you grow
Insyrge designs and builds AI lead scoring that works inside the CRM your team already uses. We prepare and clean your historical data, build and validate the model against your current scoring, write scores back to lead records and set up routing so the best leads reach your team fast. We then monitor performance and retrain as your pipeline changes. The aim is simple: more of your team's time on the leads most likely to buy. See our AI lead qualification service or contact us to discuss your lead data.
Related reading: lead scoring metrics: know if your model works and AI lead scoring: learn from your CRM history.
Frequently asked questions
What is predictive lead scoring in simple terms?
It is a model trained on your past won and lost leads that gives each new lead a score showing how likely it is to buy. The score is used to decide who to contact first.
How much data do I need for predictive lead scoring?
You need a meaningful number of both won and lost leads, with consistent definitions. If you only have a few wins, start with a rule-based model and gather more history before moving to a predictive one.
Is logistic regression good enough?
For many teams, yes. It is fast, explainable and often a strong baseline. More complex models can add accuracy, but you should only adopt them if they clearly beat the simple model on held-out data and you can still explain the results.
How often should I retrain the model?
Set a regular schedule, and retrain sooner when your offer, pricing, audience or lead sources change. Monitor the top-versus-bottom win-rate gap, because a shrinking gap is an early sign of drift.
Can I use the sample code on my own leads?
Yes. Replace the synthetic dataset with a CRM export using the same kinds of columns, and keep the split-before-fit and evaluation steps. Check your data protection obligations before exporting personal data.
Will predictive scoring replace my sales team's judgement?
No. It prioritises attention. People still decide how to approach each lead, and their feedback on scores is useful input for improving the model.
Need Help Implementing This in Your Business?
Our certified Zoho consultants and automation experts can help you design and deploy custom workflows tailored to your operations.
Book Free Consultation