Chapter 20: Key Takeaways - Recruiting Analytics

Quick Reference Summary

This chapter covered applying analytics to college football recruiting, from prospect evaluation to program efficiency measurement.


Core Concepts

Star Rating Distributions

Star Rating National Count/Year Historical Starter Rate Draft Rate
5-star ~30 85% 55%
4-star ~320 65% 22%
3-star ~1,800 35% 6%
2-star ~5,000 12% 1.5%

Key Metrics

Metric Definition Typical Range
Composite Rating Combined rating (0.8-1.0) 0.8500-0.9999
Blue Chip Ratio (4★ + 5★) / Total Roster 20-60%
Development Efficiency Actual Outcomes / Expected 0.5-1.5
Class Points Sum of recruit ratings × 100 150-350 per class

Essential Formulas

Reliability Weight for Ratings

reliability = seasons_of_college_data / (seasons + 2)

Example: After 2 seasons
reliability = 2 / (2 + 2) = 0.5

Expected Starters from Class

expected_starters = Σ(recruits_by_star × starter_rate_by_star)

Example: 2 five-stars, 10 four-stars, 12 three-stars
expected = 2×0.85 + 10×0.65 + 12×0.35 = 12.4 starters

Development Efficiency

efficiency = actual_outcomes / expected_outcomes

efficiency > 1.0: Outperforming
efficiency < 1.0: Underperforming

Competition-Adjusted Statistics

adjusted_stat = raw_stat × (base_factor + adjustment × competition_factor)

Example: Y/C from smaller state
adjusted_ypc = 8.0 × (0.70 + 0.30 × 0.85) = 7.64

Code Patterns

Basic Prospect Evaluation

def evaluate_prospect(measurables: dict,
                     rating: float,
                     position: str) -> dict:
    """Evaluate a prospect."""

    # Physical score (position-specific)
    physical_score = calculate_physical_fit(measurables, position)

    # Rating score (normalized to 0-100)
    rating_score = (rating - 0.80) * 500

    # Composite
    composite = 0.35 * rating_score + 0.65 * physical_score

    return {
        'composite_score': composite,
        'physical_score': physical_score,
        'rating_score': rating_score,
        'projection': get_projection(composite)
    }

Position Needs Analysis

def analyze_needs(roster: pd.DataFrame,
                 targets: dict) -> dict:
    """Analyze roster needs by position."""
    needs = {}

    for position, target in targets.items():
        current = roster[roster['position'] == position]
        departing = current[current['class_year'] == 'SR']
        returning = len(current) - len(departing)

        if returning < target['min']:
            needs[position] = 'critical'
        elif returning < target['max']:
            needs[position] = 'moderate'
        else:
            needs[position] = 'low'

    return needs

Efficiency Calculation

def calculate_efficiency(recruits: pd.DataFrame) -> float:
    """Calculate development efficiency."""

    # Expected outcomes by star rating
    expected_rates = {5: 0.85, 4: 0.65, 3: 0.35, 2: 0.12}

    expected = sum(
        expected_rates.get(int(r['star_rating']), 0.20)
        for _, r in recruits.iterrows()
    )

    actual = recruits['became_starter'].sum()

    return actual / expected if expected > 0 else 1.0

Position-Specific Guidelines

Physical Profile Standards

Position Height Range Weight Range 40-Time Range
QB 6'2"-6'6" 210-240 4.5-5.0
RB 5'8"-6'1" 195-225 4.35-4.6
WR 5'10"-6'4" 180-220 4.30-4.55
OT 6'4"-6'8" 290-330 5.0-5.4
EDGE 6'2"-6'6" 240-275 4.5-4.8
CB 5'9"-6'2" 180-205 4.3-4.5

Development Timelines

Position Typical Start Year Notes
RB/WR Year 1-2 Earliest contributors
CB/S Year 2 Scheme learning
LB Year 2-3 Physical development
OL Year 2-3 Technique intensive
QB Year 2-3 System mastery
DL Year 2-3 Strength requirements

Common Pitfalls

1. Over-Relying on Star Ratings

Wrong: Only recruiting 4-5 star players

# BAD - stars only
targets = recruits[recruits['star_rating'] >= 4]

Right: Consider efficiency and fit

# GOOD - rating + fit + need
targets = recruits[
    (recruits['composite_rating'] >= 0.88) &
    (recruits['position'].isin(critical_needs)) &
    (recruits['fit_score'] >= 70)
]

2. Ignoring Competition Level

Wrong: Raw stat comparison

# BAD - raw stats
best_rb = prospects.sort_values('ypc', ascending=False)

Right: Adjusted comparison

# GOOD - adjusted for competition
prospects['adj_ypc'] = prospects.apply(
    lambda x: adjust_for_competition(x['ypc'], x['classification']),
    axis=1
)
best_rb = prospects.sort_values('adj_ypc', ascending=False)

3. Neglecting Position Needs

Wrong: BPA without balance

# BAD - pure BPA
class_selection = top_available[:25]

Right: Needs-aware selection

# GOOD - balanced approach
class_selection = optimize_class(
    available,
    position_needs,
    scholarship_limit=25
)

Evaluation Checklist

Before Recruiting

  • [ ] Analyze current roster composition
  • [ ] Identify position needs by urgency
  • [ ] Set target class composition
  • [ ] Establish evaluation criteria

Prospect Evaluation

  • [ ] Verify measurables from multiple sources
  • [ ] Adjust statistics for competition
  • [ ] Evaluate physical fit for position
  • [ ] Consider development timeline
  • [ ] Assess scheme fit

Class Analysis

  • [ ] Calculate total class points
  • [ ] Verify position distribution
  • [ ] Project class impact by year
  • [ ] Compare to historical classes

Post-Signing

  • [ ] Track development against projections
  • [ ] Calculate efficiency metrics
  • [ ] Identify evaluation improvements
  • [ ] Update models with outcomes

Quick Reference Tables

Recruiting Class Size Guidelines

Situation Target Size Notes
Stable roster 20-22 Replace normal attrition
Rebuilding 25 Maximum allowed
Post-sanctions 15-18 Scholarship limits
Strong retention 18-20 Less replacement needed

Commit Probability Benchmarks

Stage Typical Probability
Offered 5-15%
Unofficial visit 15-25%
Official visit 30-50%
Crystal ball leader 50-70%
Soft commit 70-85%
Hard commit 85-95%

Efficiency Interpretation

Efficiency Score Interpretation
> 1.30 Elite development program
1.10 - 1.30 Above average
0.90 - 1.10 Average
0.70 - 0.90 Below average
< 0.70 Development concerns

Red Flags

Warning signs in recruiting evaluation:

  1. Self-reported measurables only: Verify at camps
  2. No verified film: Limited evaluation basis
  3. Single-season production: Small sample size
  4. Weak competition: Inflated statistics
  5. Multiple transfers: Fit concerns
  6. Academic issues: Eligibility risk
  7. Character concerns: Program fit

Next Steps

After mastering recruiting analytics, proceed to: - Chapter 21: Win Probability Models - Chapter 22: Machine Learning Applications - Chapter 23: Network Analysis in Football