Back to writing

Predictive Lead Scoring: Prioritize Your Best Opportunities with AI

5 min read

The Manual Lead Qualification Problem

Sales teams waste 50%+ of their time on leads that won't convert:

Cost: Millions in lost revenue and wasted sales capacity.

AI-Powered Lead Scoring

Feature Engineering

def extract_lead_features(lead_id: str) -> dict:
    """Convert lead data into ML features"""
    
    lead = get_lead(lead_id)
    
    return {
        # Firmographic
        'company_size': lead['employee_count'],
        'industry': lead['industry'],
        'revenue': lead['annual_revenue'],
        'location': lead['country'],
        
        # Behavioral
        'website_visits': count_visits(lead_id, days=30),
        'pages_viewed': count_page_views(lead_id),
        'time_on_site': sum_time_on_site(lead_id),
        'demo_requested': lead['demo_request'],
        
        # Engagement
        'email_opens': count_opens(lead_id),
        'email_clicks': count_clicks(lead_id),
        'content_downloaded': count_downloads(lead_id),
        'webinar_attended': lead['webinar_attendance'],
        
        # Intent signals
        'pricing_page_views': count_pricing_views(lead_id),
        'case_study_views': count_case_studies(lead_id),
        'competitor_research': detect_competitor_searches(lead_id),
        
        # Fit
        'matches_icp': calculate_icp_match(lead),
        'technology_stack': get_tech_stack(lead['domain']),
        'growth_indicators': get_growth_signals(lead)
    }

Training Conversion Model

import xgboost as xgb

def train_conversion_model():
    """Predict lead-to-customer conversion"""
    
    # Historical leads
    leads = get_all_leads(months=12)
    
    X = []
    y = []
    
    for lead_id in leads:
        features = extract_lead_features(lead_id)
        converted = lead_converted_to_customer(lead_id)
        
        X.append(features)
        y.append(1 if converted else 0)
    
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, stratify=y
    )
    
    # Handle class imbalance
    scale_pos_weight = (y_train == 0).sum() / (y_train == 1).sum()
    
    model = xgb.XGBClassifier(
        max_depth=6,
        learning_rate=0.1,
        n_estimators=100,
        scale_pos_weight=scale_pos_weight
    )
    
    model.fit(X_train, y_train)
    
    # Evaluate
    y_pred_proba = model.predict_proba(X_test)[:, 1]
    auc = roc_auc_score(y_test, y_pred_proba)
    
    print(f"Model AUC: {auc:.3f}")
    
    return model

Deal Size Prediction

def train_deal_size_model():
    """Predict expected contract value"""
    
    closed_deals = get_closed_deals(months=12)
    
    X = []
    y = []
    
    for deal_id in closed_deals:
        lead_id = deal_to_lead(deal_id)
        features = extract_lead_features(lead_id)
        contract_value = get_contract_value(deal_id)
        
        X.append(features)
        y.append(contract_value)
    
    model = xgb.XGBRegressor()
    model.fit(X, y)
    
    return model

Automated Lead Scoring

Real-Time Scoring

def score_lead(lead_id: str) -> dict:
    """Calculate lead score and priority"""
    
    features = extract_lead_features(lead_id)
    
    # Load models
    conversion_model = load_model('conversion_model.pkl')
    deal_size_model = load_model('deal_size_model.pkl')
    
    # Predictions
    conversion_prob = conversion_model.predict_proba([features])[0][1]
    expected_value = deal_size_model.predict([features])[0]
    
    # Combined score
    lead_score = conversion_prob * expected_value
    
    # Categorize
    if conversion_prob > 0.7 and expected_value > 50000:
        priority = 'A - Enterprise'
    elif conversion_prob > 0.5:
        priority = 'B - High Intent'
    elif expected_value > 20000:
        priority = 'C - High Value'
    else:
        priority = 'D - Nurture'
    
    return {
        'lead_score': lead_score,
        'conversion_probability': conversion_prob,
        'expected_deal_size': expected_value,
        'priority': priority,
        'recommended_action': get_recommended_action(priority)
    }

Intelligent Routing

def route_lead(lead_id: str):
    """Assign to appropriate sales rep"""
    
    score = score_lead(lead_id)
    
    if score['priority'] == 'A - Enterprise':
        # Route to senior AE
        assign_to = get_senior_ae_with_capacity()
        send_alert(assign_to, f"Hot enterprise lead: {lead_id}")
        
    elif score['priority'] == 'B - High Intent':
        # Route to available AE
        assign_to = get_ae_with_capacity()
        
    else:
        # SDR nurture
        assign_to = get_sdr()
    
    assign_lead(lead_id, assign_to)
    
    return {
        'assigned_to': assign_to,
        'reason': score['priority']
    }

Behavioral Triggers

Intent Signal Detection

def detect_buying_signals(lead_id: str):
    """Identify high-intent actions"""
    
    recent_activity = get_activity(lead_id, days=7)
    
    signals = {
        'pricing_spike': recent_activity['pricing_views'] > 3,
        'demo_request': 'demo_request' in recent_activity['actions'],
        'competitor_comparison': 'competitor' in recent_activity['searches'],
        'case_study_deep_dive': recent_activity['case_study_time'] > 300,
        'multiple_stakeholders': len(recent_activity['unique_visitors']) > 1
    }
    
    if any(signals.values()):
        # High intent - prioritize
        notify_sales(lead_id, signals)
    
    return signals

Automated Outreach

def trigger_automated_outreach(lead_id: str):
    """Send personalized message based on behavior"""
    
    score = score_lead(lead_id)
    behavior = get_recent_behavior(lead_id)
    
    if behavior['action'] == 'pricing_page_view' and behavior['count'] > 2:
        # Interested in pricing
        template = """
        Hi {name},
        
        I noticed you've been checking out our pricing.
        Happy to walk you through our plans and answer any questions.
        
        {calendar_link}
        """
    
    elif behavior['action'] == 'case_study_view':
        # Researching solutions
        template = """
        Hi {name},
        
        Saw you read about {case_study_company}'s success.
        We've helped {similar_companies} achieve similar results.
        
        Want to discuss your use case?
        """
    
    send_email(lead_id, personalize_template(template, lead_id))

Measuring Impact

ROI Calculation

def calculate_lead_scoring_roi():
    """Measure value of AI scoring"""
    
    # Before AI scoring
    before = {
        'leads_contacted': 10000,
        'conversion_rate': 0.02,
        'avg_deal_size': 25000,
        'sales_capacity_hours': 2000
    }
    
    # After AI scoring
    after = {
        'leads_contacted': 3000,  # Focus on top 30%
        'conversion_rate': 0.06,  # 3x higher (better targeting)
        'avg_deal_size': 40000,   # Bigger deals
        'sales_capacity_hours': 2000
    }
    
    before_revenue = (before['leads_contacted'] * 
                     before['conversion_rate'] * 
                     before['avg_deal_size'])
    
    after_revenue = (after['leads_contacted'] * 
                    after['conversion_rate'] * 
                    after['avg_deal_size'])
    
    lift = (after_revenue - before_revenue) / before_revenue
    
    return {
        'before_revenue': before_revenue,
        'after_revenue': after_revenue,
        'revenue_lift': f"+{lift*100:.0f}%",
        'efficiency_gain': '3x more revenue per sales hour'
    }

Advanced Techniques

Engagement Scoring Over Time

def calculate_engagement_momentum(lead_id: str):
    """Track if interest is increasing"""
    
    activity = get_daily_activity(lead_id, days=30)
    
    # Fit trend line
    days = list(range(30))
    engagement_scores = [calculate_daily_engagement(a) for a in activity]
    
    slope = np.polyfit(days, engagement_scores, 1)[0]
    
    if slope > 0.1:
        return {'momentum': 'accelerating', 'urgency': 'high'}
    elif slope < -0.1:
        return {'momentum': 'declining', 'urgency': 'low'}
    else:
        return {'momentum': 'stable', 'urgency': 'medium'}

Lookalike Modeling

def find_lookalike_leads(converted_customer_id: str):
    """Find similar high-value prospects"""
    
    customer_features = extract_lead_features(converted_customer_id)
    
    # Generate customer embedding
    customer_emb = model.transform([customer_features])
    
    # Find similar leads
    all_leads = get_open_leads()
    lead_embeddings = [model.transform([extract_lead_features(l)]) for l in all_leads]
    
    # Calculate similarity
    similarities = cosine_similarity(customer_emb, lead_embeddings)[0]
    
    # Top 100 most similar
    top_indices = np.argsort(similarities)[-100:]
    
    lookalikes = [all_leads[i] for i in top_indices]
    
    return lookalikes

Implementation Checklist

  1. Collect historical lead + outcome data (6+ months)
  2. Engineer behavioral features
  3. Train conversion + deal size models
  4. Build scoring API
  5. Integrate with CRM
  6. A/B test vs. current process
  7. Measure win rate + deal size improvements

Real Results

B2B companies using AI lead scoring achieve:

Common Mistakes

Start Here

  1. Export 12 months of lead data
  2. Label conversions
  3. Train XGBoost model
  4. Score current pipeline
  5. Route top 20% to sales
  6. Measure conversion lift

AI lead scoring is becoming mandatory for B2B growth. Implement it now.


Tools:

Enjoying this article?

Get deep technical guides like this delivered weekly.

Get AI growth insights weekly

Join engineers and product leaders building with AI. No spam, unsubscribe anytime.

Keep reading