9.4.2. Lab#
Use this assignment to practice the chapter’s concepts and coding skills in runnable Python code.
Sign in from the account menu before you start working on the assignment.
Write and run your code directly in the coding cells.
Multiple submissions are allowed. The highest score is kept.
Follow one store’s loyalty-program investigation. First assess the membership rate, then the regional mix, then the decisions made from test results. The simulation uses a fixed seed so everyone can check the same output. Twenty repetitions keep the arithmetic visible here; an actual analysis would use many more, especially near a cutoff.
For each result, identify the model being tested and the direction of evidence. A result about the membership rate does not automatically answer a separate question about regional representation.
### Question 1: Observed Test Statistic
# A store's model says 20% of customers join its loyalty program.
# In a random sample of 400 customers, 98 joined.
# 1. Compute the observed percent of program members.
# 2. Compute the test statistic: the distance between the observed percent
# and the model's 20%, | observed percent - 20 |, rounded to 2 decimals.
# Print exactly:
# Observed percent: 24.5
# Test statistic: 4.5
import numpy as np
import pandas as pd
members = 98
sample_size = 400
model_percent = 20
### Your code starts here.
### Your code ends here.
Observed percent: 24.5
Test statistic: 4.5
### Question 2: Total Variation Distance
# A loyalty program should reflect the store's customer base. The table shows the
# share of all customers in each region and the share in a separate sample
# of 100 program members.
# 1. Compute the absolute difference between the two distributions for each region.
# 2. Compute the total variation distance (TVD): the sum of the absolute
# differences divided by 2, rounded to 2 decimals.
# Print exactly:
# TVD: 0.1
import numpy as np
import pandas as pd
regions = pd.DataFrame({
"region": ["North", "Central", "South"],
"all_customers": [0.40, 0.35, 0.25],
"members": [0.30, 0.40, 0.30],
})
### Your code starts here.
### Your code ends here.
TVD: 0.1
### Question 3: P-value From a Simulation
# Continue the regional-mix investigation from Question 2.
# Null: members are selected independently with the population's regional shares.
# Large TVDs are evidence against that model. Simulate 20 samples of 100 members.
# 1. Start an empty list. In each repetition, generate new counts with
# rng.multinomial(sample_size, population).
# 2. Compute each TVD as the sum of absolute differences between simulated
# counts and expected_counts, divided by (2 * sample_size). Append it.
# This is the same TVD formula, expressed in counts rather than proportions.
# 3. Convert the list to a pandas Series. Count TVDs >= observed_tvd,
# then divide that count by the number of simulations for the p-value.
# Print exactly:
# At least as large: 4
# P-value: 0.2
import numpy as np
import pandas as pd
rng = np.random.default_rng(17)
sample_size = 100
population = np.array([0.40, 0.35, 0.25])
expected_counts = sample_size * population
observed_tvd = 0.10
repetitions = 20
### Your code starts here.
### Your code ends here.
At least as large: 4
P-value: 0.2
### Question 4: Applying the Conventions
# The same store tests three policies intended to support the loyalty program.
# Apply these conventional evidence labels, then consider the business question below:
# p-value below 0.01 -> "highly significant"
# p-value below 0.05 -> "significant"
# otherwise -> "not significant"
# Before seeing results, the team selected a 5% significance level.
# A label summarizes evidence against the null, not the size or value of a gain.
# For discussion: free shipping adds an estimated $200 monthly contribution
# before its $1,000 monthly operating cost. Does p = 0.003 justify rollout?
# Explain in a comment; print one line per test, in table order.
# Print exactly:
# Free shipping: highly significant
# Loyalty email: significant
# New layout: not significant
import numpy as np
import pandas as pd
tests = pd.DataFrame({
"policy": ["Free shipping", "Loyalty email", "New layout"],
"p_value": [0.003, 0.04, 0.21],
})
### Your code starts here.
### Your code ends here.
Free shipping: highly significant
Loyalty email: significant
New layout: not significant
### Question 5: False Alarms
# The store checks its test process with 20 A/A tests of its loyalty signup page.
# Each compares the page with an identical copy of itself,
# so the null hypothesis (no difference) is true in every test.
# 1. Count the tests whose p-value is below the 0.05 cutoff. Each one is a
# Type I error (a false alarm).
# 2. Compute the false-alarm rate: that count divided by the number of tests.
# Print exactly:
# False alarms: 1
# False-alarm rate: 0.05
import numpy as np
import pandas as pd
p_values = pd.Series([0.280, 0.783, 0.988, 0.986, 0.883, 0.913, 0.708, 0.554, 0.923, 0.031,
0.370, 0.606, 0.478, 0.793, 0.195, 0.062, 0.127, 0.963, 0.133, 0.226])
### Your code starts here.
### Your code ends here.
False alarms: 1
False-alarm rate: 0.05