Case Study 1.1: The Houston Rockets' Analytical Revolution

Overview

This case study examines how the Houston Rockets, under General Manager Daryl Morey (2007-2020), became the most analytically-driven organization in the NBA and fundamentally changed how teams approach shot selection.


Background

When Daryl Morey was hired as the Houston Rockets' General Manager in 2007, he brought a different perspective to basketball operations. With an MBA from MIT Sloan and a background in consulting rather than playing or traditional scouting, Morey approached basketball as an optimization problem.

His core insight was simple: basketball teams should maximize expected points per possession. This led to identifying which shots were most efficient and building a team designed to take those shots.


The Data Analysis

Shot Efficiency by Zone

Morey's analytics team analyzed shot efficiency across different court locations. Their findings, consistent with broader research, showed dramatic efficiency differences:

Shot Zone Approximate FG% Expected Points
Restricted Area (0-4 ft) 62% 1.24
Paint (Non-RA) (4-14 ft) 40% 0.80
Mid-Range (14 ft - 3PT line) 40% 0.80
Corner Three 39% 1.17
Above-the-Break Three 35% 1.05
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# Shot efficiency data
shot_zones = pd.DataFrame({
    'Zone': ['Restricted Area', 'Paint (Non-RA)', 'Mid-Range',
             'Corner Three', 'Above-Break Three'],
    'FG_Pct': [0.62, 0.40, 0.40, 0.39, 0.35],
    'Point_Value': [2, 2, 2, 3, 3]
})

# Calculate expected points
shot_zones['Expected_Points'] = shot_zones['FG_Pct'] * shot_zones['Point_Value']

# Visualize
fig, ax = plt.subplots(figsize=(10, 6))
colors = ['#2ecc71', '#e74c3c', '#e74c3c', '#3498db', '#3498db']
bars = ax.bar(shot_zones['Zone'], shot_zones['Expected_Points'], color=colors)
ax.axhline(y=1.0, color='gray', linestyle='--', label='1.0 Expected Points')
ax.set_ylabel('Expected Points per Attempt')
ax.set_title('Shot Efficiency by Zone')
ax.set_ylim(0, 1.4)

for bar, val in zip(bars, shot_zones['Expected_Points']):
    ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.02,
            f'{val:.2f}', ha='center', fontsize=10)

plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.legend()
plt.savefig('shot_efficiency.png', dpi=150)
plt.show()

The "Moreyball" Shot Distribution

Based on this analysis, Morey's Rockets aimed to: 1. Maximize layups and dunks: Highest efficiency shots 2. Maximize three-point attempts: High expected value 3. Eliminate mid-range shots: Lowest efficiency

This became known as "Moreyball"—a shot distribution clustered at the rim and behind the three-point line, with minimal mid-range attempts.


Implementation

Player Acquisition Strategy

Morey built rosters specifically designed for this shot profile:

James Harden (acquired 2012) Harden's ability to draw fouls, score at the rim, and create three-point opportunities made him the ideal Moreyball player. His step-back three-pointer became signature.

Role Players The Rockets consistently signed players who could: - Shoot corner threes at high volume - Finish at the rim - Space the floor

Players like Trevor Ariza, P.J. Tucker, and Eric Gordon fit this mold perfectly.

Avoiding "Empty Stats" The Rockets avoided players whose value came from inefficient mid-range shooting, regardless of reputation.

# Example: Comparing player fit with Moreyball philosophy

def moreyball_fit_score(player_stats):
    """
    Calculate how well a player fits Moreyball philosophy.

    Args:
        player_stats: Dictionary with shooting data
            - rim_attempts: Shots at rim as % of total
            - three_attempts: Three-pointers as % of total
            - midrange_attempts: Mid-range as % of total
            - rim_pct: FG% at rim
            - three_pct: 3P%

    Returns:
        Fit score from 0-100
    """
    # Weight shot distribution (higher rim and 3PT = better)
    distribution_score = (
        player_stats['rim_attempts'] * 0.4 +
        player_stats['three_attempts'] * 0.4 +
        (1 - player_stats['midrange_attempts']) * 0.2
    ) * 100

    # Weight efficiency (higher = better)
    efficiency_score = (
        (player_stats['rim_pct'] / 0.65) * 0.5 +  # 65% at rim is excellent
        (player_stats['three_pct'] / 0.40) * 0.5   # 40% from 3 is excellent
    ) * 100

    return min(100, (distribution_score * 0.6 + efficiency_score * 0.4))

# Example players
harden_2019 = {
    'rim_attempts': 0.28,
    'three_attempts': 0.45,
    'midrange_attempts': 0.12,
    'rim_pct': 0.64,
    'three_pct': 0.368
}

traditional_big = {
    'rim_attempts': 0.35,
    'three_attempts': 0.05,
    'midrange_attempts': 0.40,
    'rim_pct': 0.60,
    'three_pct': 0.30
}

print(f"James Harden Moreyball Fit: {moreyball_fit_score(harden_2019):.1f}")
print(f"Traditional Big Moreyball Fit: {moreyball_fit_score(traditional_big):.1f}")

Offensive System Design

The Rockets' offense was built to generate specific shot types:

Isolation-Heavy Attack Rather than complex motion offenses, the Rockets relied on Harden's ability to create in isolation. This might seem counter-intuitive, but: - Harden's iso efficiency was elite - It generated fouls at a historic rate - It created open three-pointers for teammates

Small Ball By 2020, the Rockets went fully "small ball," playing 6'5" P.J. Tucker at center. This: - Maximized floor spacing - Eliminated inefficient post-up plays - Created more rim attack opportunities


Results

Team Performance

Season Wins Off Rating Rank 3PA/Game 3PA Rank
2016-17 55 3rd 40.3 1st
2017-18 65 1st 42.3 1st
2018-19 53 4th 45.4 1st
2019-20 44 5th 45.3 1st

The Rockets consistently had elite offenses and led the league in three-point attempts.

Individual Success

James Harden's individual statistics under Moreyball:

  • Scoring Titles: 3 consecutive (2018-2020)
  • Points Per Game: 36.1 in 2018-19 (highest since 1987)
  • True Shooting %: Consistently among league leaders
  • MVP: 2018
# Harden's scoring evolution
harden_seasons = pd.DataFrame({
    'Season': ['2016-17', '2017-18', '2018-19', '2019-20'],
    'PPG': [29.1, 30.4, 36.1, 34.3],
    'TS%': [0.613, 0.619, 0.616, 0.626],
    'Three_Attempts': [9.3, 10.0, 13.2, 12.4],
    'FT_Attempts': [10.9, 10.1, 11.0, 11.8]
})

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# Scoring and efficiency
ax1 = axes[0]
ax1.bar(harden_seasons['Season'], harden_seasons['PPG'], color='#BA0C2F')
ax1.set_ylabel('Points Per Game')
ax1.set_title('Harden Scoring by Season')
ax1.set_ylim(0, 40)

# Shot attempts
ax2 = axes[1]
width = 0.35
x = np.arange(len(harden_seasons['Season']))
ax2.bar(x - width/2, harden_seasons['Three_Attempts'], width, label='3PA', color='#3498db')
ax2.bar(x + width/2, harden_seasons['FT_Attempts'], width, label='FTA', color='#2ecc71')
ax2.set_xlabel('Season')
ax2.set_ylabel('Attempts per Game')
ax2.set_title('Harden 3PA and FTA by Season')
ax2.set_xticks(x)
ax2.set_xticklabels(harden_seasons['Season'])
ax2.legend()

plt.tight_layout()
plt.savefig('harden_evolution.png', dpi=150)
plt.show()

Critiques and Limitations

Playoff Performance

Despite regular season success, the Rockets never won a championship under Morey. Critics pointed to:

Playoff Defense - Small ball lineups were exploited by teams with dominant bigs - Three-point shooting became less reliable under playoff pressure

Variance in Shooting - Three-point shooting has high variance - In Game 7 of the 2018 Western Conference Finals, the Rockets missed 27 consecutive three-pointers

Predictability - Opponents could game-plan specifically for the Rockets' tendencies - Lack of mid-range threat made defense easier

League Adaptation

As other teams adopted similar approaches, the Rockets' advantage diminished: - League-wide three-point attempts increased - Defenses improved at contesting threes - The "innovation premium" disappeared


Lessons Learned

What Worked

  1. Evidence-based decision making: Using data to challenge conventional wisdom
  2. Commitment to philosophy: Fully implementing insights rather than half-measures
  3. Player acquisition alignment: Building rosters that fit the system
  4. Efficiency focus: Maximizing expected points per possession

What Could Have Been Better

  1. Flexibility: Too rigid adherence to shot profile
  2. Defensive investment: Offense-heavy roster construction
  3. Playoff adjustments: Inability to adapt when system was countered

Analysis Questions

  1. Expected Value Calculation: If a team increases three-point attempts by 10 per game while decreasing mid-range attempts by 10, how many additional points per game would they expect to score, assuming league-average percentages?

  2. Variance Analysis: Calculate the standard deviation of points scored on 40 three-point attempts vs. 40 mid-range attempts, assuming league-average percentages. Which has more variance?

  3. Roster Construction: Design a hypothetical 5-man lineup optimized for Moreyball principles. What skills would you prioritize at each position?

  4. Counter-Strategy: If you were coaching against the Rockets, how would you design your defensive game plan?

  5. Modern Application: How have other teams adapted Moreyball principles? Are any current teams running a similar philosophy?


Code Solution: Variance Analysis

import numpy as np
from scipy import stats

def shot_variance_analysis(n_shots, fg_percentage, points_per_make):
    """
    Analyze variance in scoring from a shot type.

    Args:
        n_shots: Number of attempts
        fg_percentage: Field goal percentage
        points_per_make: Points per made shot (2 or 3)

    Returns:
        Dictionary with expected points, variance, and confidence interval
    """
    # Each shot is a binomial trial
    expected_makes = n_shots * fg_percentage
    expected_points = expected_makes * points_per_make

    # Variance of sum of binomial trials
    variance_makes = n_shots * fg_percentage * (1 - fg_percentage)
    variance_points = variance_makes * (points_per_make ** 2)
    std_points = np.sqrt(variance_points)

    # 95% confidence interval
    ci_lower = expected_points - 1.96 * std_points
    ci_upper = expected_points + 1.96 * std_points

    return {
        'expected_points': expected_points,
        'std_points': std_points,
        'variance': variance_points,
        'ci_95': (ci_lower, ci_upper)
    }

# Compare 40 threes vs 40 mid-range shots
three_pt_analysis = shot_variance_analysis(40, 0.36, 3)
midrange_analysis = shot_variance_analysis(40, 0.40, 2)

print("40 Three-Point Attempts:")
print(f"  Expected Points: {three_pt_analysis['expected_points']:.1f}")
print(f"  Std Dev: {three_pt_analysis['std_points']:.2f}")
print(f"  95% CI: ({three_pt_analysis['ci_95'][0]:.1f}, {three_pt_analysis['ci_95'][1]:.1f})")

print("\n40 Mid-Range Attempts:")
print(f"  Expected Points: {midrange_analysis['expected_points']:.1f}")
print(f"  Std Dev: {midrange_analysis['std_points']:.2f}")
print(f"  95% CI: ({midrange_analysis['ci_95'][0]:.1f}, {midrange_analysis['ci_95'][1]:.1f})")

Conclusion

The Houston Rockets under Daryl Morey demonstrated both the power and limitations of analytics-driven basketball. Their approach proved that systematic application of efficiency principles could produce elite regular-season offenses and individual statistical performances. However, their championship drought also showed that analytics alone cannot account for all factors in basketball success, particularly in playoff environments where variance increases and opponents can specifically game-plan.

The Moreyball era's most lasting impact may be its influence on the entire league. The three-point revolution that the Rockets championed is now ubiquitous, fundamentally changing how basketball is played at all levels.


This case study is based on publicly available information and analysis. Team-specific internal analytics are not available.