xbe.at

Python / Python for ML and AI

Exploring the Wait-Time Paradox with Python

6 min read, 14 sections

Contents
  1. Introduction to Wait-Time Analysis
  2. Generating Random Wait Times
  3. Plotting Wait Times
  4. Curve Fitting with Exponential Distribution
  5. Limitations of Exponential Distribution
  6. Comparing Distributions
  7. Understanding the Wait-Time Paradox
  8. Visualizing the Wait-Time Paradox
  9. Exploring Other Distributions
  10. Comparing Multiple Distributions
  11. Goodness-of-Fit Tests
  12. Interpreting Goodness-of-Fit Results
  13. Practical Applications
  14. Conclusion

Introduction to Wait-Time Analysis

Have you ever wondered why the longer you wait on hold, the more time you expect to keep waiting? This phenomenon is known as the "wait-time paradox," and it can be explored using Python programming and data analysis techniques. In this presentation, we will delve into curve fitting, plotting, and understanding exponential and Weibull distributions to gain insights into this intriguing phenomenon.

import numpy as np
import matplotlib.pyplot as plt

Generating Random Wait Times

To analyze wait times, we first need to generate random wait-time data. We can use the exponential distribution, which is commonly used to model wait times in queuing systems.

# Generate random wait times from an exponential distribution
wait_times = np.random.exponential(scale=5, size=1000)

Plotting Wait Times

Let's visualize the wait-time data using a histogram to get a better understanding of its distribution.

# Plot a histogram of wait times
plt.hist(wait_times, bins=30, edgecolor='black')
plt.xlabel('Wait Time')
plt.ylabel('Frequency')
plt.title('Distribution of Wait Times')
plt.show()

Curve Fitting with Exponential Distribution

We can fit an exponential distribution to the wait-time data using the scipy.stats module and compare it to the actual data.

from scipy.stats import expon

# Fit an exponential distribution to the data
params = expon.fit(wait_times)
fitted_pdf = expon.pdf(wait_times, *params)

# Plot the fitted distribution against the data
plt.hist(wait_times, bins=30, density=True, alpha=0.5, label='Data')
plt.plot(wait_times, fitted_pdf, 'r-', label='Exponential Fit')
plt.legend()
plt.show()

Limitations of Exponential Distribution

While the exponential distribution provides a good starting point, it may not accurately capture the wait-time paradox. Let's explore another distribution that better models this phenomenon.

from scipy.stats import exponweib

# Fit a Weibull distribution to the data
params = exponweib.fit(wait_times, floc=0)
fitted_pdf = exponweib.pdf(wait_times, *params)

# Plot the fitted distribution against the data
plt.hist(wait_times, bins=30, density=True, alpha=0.5, label='Data')
plt.plot(wait_times, fitted_pdf, 'r-', label='Weibull Fit')
plt.legend()
plt.show()

Comparing Distributions

Let's compare the exponential and Weibull distributions side by side to see which one better captures the wait-time data.

# Generate wait times from exponential and Weibull distributions
exp_times = np.random.exponential(scale=5, size=1000)
weib_times = exponweib.rvs(*params, size=1000)

# Plot the distributions
fig, ax = plt.subplots(1, 2, figsize=(12, 4))
ax[0].hist(exp_times, bins=30, density=True, alpha=0.5, label='Exponential')
ax[0].set_title('Exponential Distribution')
ax[1].hist(weib_times, bins=30, density=True, alpha=0.5, label='Weibull')
ax[1].set_title('Weibull Distribution')
plt.show()

Understanding the Wait-Time Paradox

The wait-time paradox suggests that the longer you wait, the more time you expect to keep waiting. Let's explore this phenomenon by simulating a queuing system.

# Simulate a queuing system
queue = []
for i in range(1000):
    wait_time = np.random.weibull(a=2, scale=10)
    queue.append(wait_time)
    if i % 10 == 0:
        print(f"After waiting {i} seconds, the expected remaining wait time is {sum(queue) / len(queue)}")

Visualizing the Wait-Time Paradox

Let's plot the expected remaining wait time as a function of the time already waited to visualize the wait-time paradox.

# Simulate a queuing system and record expected remaining wait times
waited_times = []
expected_times = []
queue = []
for i in range(1000):
    wait_time = np.random.weibull(a=2, scale=10)
    queue.append(wait_time)
    waited_times.append(i)
    expected_times.append(sum(queue) / len(queue))

# Plot the wait-time paradox
plt.plot(waited_times, expected_times)
plt.xlabel('Time Waited (seconds)')
plt.ylabel('Expected Remaining Wait Time (seconds)')
plt.title('Wait-Time Paradox')
plt.show()

Exploring Other Distributions

While the Weibull distribution provides a better fit for the wait-time data, there are other distributions that can be explored, such as the log-normal distribution.

from scipy.stats import lognorm

# Fit a log-normal distribution to the data
params = lognorm.fit(wait_times, floc=0)
fitted_pdf = lognorm.pdf(wait_times, *params)

# Plot the fitted distribution against the data
plt.hist(wait_times, bins=30, density=True, alpha=0.5, label='Data')
plt.plot(wait_times, fitted_pdf, 'r-', label='Log-normal Fit')
plt.legend()
plt.show()

Comparing Multiple Distributions

Let's compare the exponential, Weibull, and log-normal distributions side by side to see which one best captures the wait-time data.

# Generate wait times from different distributions
exp_times = np.random.exponential(scale=5, size=1000)
weib_times = exponweib.rvs(*params, size=1000)
lognorm_times = lognorm.rvs(*params, size=1000)

# Plot the distributions
fig, ax = plt.subplots(1, 3, figsize=(18, 4))
ax[0].hist(exp_times, bins=30, density=True, alpha=0.5, label='Exponential')
ax[0].set_title('Exponential Distribution')
ax[1].hist(weib_times, bins=30, density=True, alpha=0.5, label='Weibull')
ax[1].set_title('Weibull Distribution')
ax[2].hist(lognorm_times, bins=30, density=True, alpha=0.5, label='Log-normal')
ax[2].set_title('Log-normal Distribution')
plt.show()

Goodness-of-Fit Tests

To quantitatively assess the fit of different distributions to the wait-time data, we can perform goodness-of-fit tests, such as the Kolmogorov-Smirnov test or the Anderson-Darling test.

from scipy.stats import kstest, anderson

# Perform Kolmogorov-Smirnov test
exp_ks_stat, exp_ks_pvalue = kstest(wait_times, 'expon', args=params)
weib_ks_stat, weib_ks_pvalue = kstest(wait_times, 'exponweib', args=params)
lognorm_ks_stat, lognorm_ks_pvalue = kstest(wait_times, 'lognorm', args=params)

print(f"Exponential KS test: statistic={exp_ks_stat:.4f}, p-value={exp_ks_pvalue:.4f}")
print(f"Weibull KS test: statistic={weib_ks_stat:.4f}, p-value={weib_ks_pvalue:.4f}")
print(f"Log-normal KS test: statistic={lognorm_ks_stat:.4f}, p-value={lognorm_ks_pvalue:.4f}")

# Perform Anderson-Darling test
exp_ad_stat, exp_ad_pvalue, _ = anderson(wait_times, dist='expon', args=params)
weib_ad_stat, weib_ad_pvalue, _ = anderson(wait_times, dist='exponweib', args=params)
lognorm_ad_stat, lognorm_ad_pvalue, _ = anderson(wait_times, dist='lognorm', args=params)

print(f"\nExponential AD test: statistic={exp_ad_stat:.4f}, p-value={exp_ad_pvalue:.4f}")
print(f"Weibull AD test: statistic={weib_ad_stat:.4f}, p-value={weib_ad_pvalue:.4f}")
print(f"Log-normal AD test: statistic={lognorm_ad_stat:.4f}, p-value={lognorm_ad_pvalue:.4f}")

Interpreting Goodness-of-Fit Results

The goodness-of-fit test results can help us determine which distribution provides the best fit for the wait-time data. Lower test statistic values and higher p-values indicate a better fit.

# Print the best-fitting distribution based on test results
best_dist = min([('exponential', exp_ks_stat, exp_ad_stat),
                 ('weibull', weib_ks_stat, weib_ad_stat),
                 ('lognormal', lognorm_ks_stat, lognorm_ad_stat)],
                key=lambda x: x[1] + x[2])

print(f"\nThe best-fitting distribution for the wait-time data is: {best_dist[0]}")

Practical Applications

Understanding the wait-time paradox and modeling wait times accurately can have practical applications in various domains, such as customer service, queuing systems, and resource allocation.

# Simulate a queuing system and optimize resource allocation
queue = []
service_rate = 5  # Number of customers served per minute
for i in range(1000):
    wait_time = np.random.weibull(a=2, scale=10)
    queue.append(wait_time)
    if sum(queue) > service_rate * 60:
        print(f"Queue is getting too long, allocating more resources at time {i} minutes.")
        service_rate += 2

Conclusion

In this presentation, we explored the wait-time paradox and demonstrated how Python programming and data analysis techniques can be used to model and understand this phenomenon. By fitting various distributions to wait-time data and performing goodness-of-fit tests, we gained insights into the underlying patterns and characteristics of wait times. These insights can be applied in practical scenarios, such as optimizing resource allocation in queuing systems and improving customer service.

More in Python for ML and AI

  1. Fractal Dimension Analysis of Images using Python9 min

    Fractal dimension is a measure of complexity that quantifies how a pattern's detail changes with scale. In image analysis, it can reveal intricate structures...

  2. Exploring the Mathematical Thriller Pi Movie Using Python:8 min

    "Pi" is a psychological thriller film directed by Darren Aronofsky. The movie follows Max Cohen, a mathematician who believes he has discovered a 216-digit...

  3. Game Theory in Python7 min

    Game theory is a mathematical framework used to analyze strategic interactions between rational decision-makers. It helps understand the behavior of...

  4. Exploring the Infinite: Mathematics, Philosophy, and Python:4 min

    The concept of infinity has fascinated mathematicians and philosophers for millennia. It represents something that goes beyond any finite quantity or...

  5. Generating Unique Random Numbers in Python7 min

    Understanding how to generate unique random numbers is crucial for various applications, from sampling to simulation. The simplest approach uses Python's...

  6. Exploring the Equal Scores Paradox with Python4 min

    The Equal Scores Paradox is a counterintuitive phenomenon that arises in certain scoring systems, particularly in the context of educational assessments or...