Homework

12.5.3. Homework#

  • 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.

1. Correlation and Causation

Across 50 stores, the correlation between a product’s price and units sold is -0.85. This shows that raising the price causes demand to fall.

Hide code cell source

### Solution
# False
# Correlation measures association, not causation. Other differences between stores (location, customers, competition) could explain the pattern.

2. Changing Units

Converting both variables to standard units, or measuring sales in dollars instead of thousands of dollars, does not change the correlation coefficient r.

Hide code cell source

### Solution
# True
# r is computed from standard units, so it has no units and does not change when either variable is rescaled.

3. The Regression Effect

The correlation between customers’ monthly visits and their monthly spending is 0.6. A customer whose visits are 2 SDs above average is predicted to spend 1.2 SDs above average.

Hide code cell source

### Solution
# True
# In standard units, the regression prediction is r times x: 0.6 times 2 = 1.2. Predictions are closer to average than the x value is.

4. Least Squares

Among all straight lines that could be drawn through a scatter plot, the regression line has the smallest root mean squared error.

Hide code cell source

### Solution
# True
# That is why the regression line is also called the least squares line.

5. Fan-Shaped Residuals

In a residual plot, the residuals spread out more and more as the fitted values increase. The regression line is equally precise for small and large predictions.

Hide code cell source

### Solution
# False
# Uneven spread (heteroscedasticity) means predictions are less precise where the residuals are larger.
### 6. Price and Units Sold
# A store varied the price of a product over six weeks.
#   1. Compute r between price and units, using standard units (np.mean, np.std).
#   2. Print r rounded to 3 decimals.
# Print exactly:
# r: -0.995
import numpy as np
import pandas as pd

demand = pd.DataFrame({
    "price": [10, 12, 14, 16, 18, 20],
    "units": [48, 45, 39, 36, 30, 27],
})

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
import numpy as np
import pandas as pd

demand = pd.DataFrame({
    "price": [10, 12, 14, 16, 18, 20],
    "units": [48, 45, 39, 36, 30, 27],
})

def standard_units(x):
    return (x - np.mean(x)) / np.std(x)

r = np.mean(standard_units(demand['price']) * standard_units(demand['units']))
print("r:", round(r, 3))
r: -0.995
### 7. Predicting Demand
#   1. Compute the slope and intercept of the regression line of units on price.
#   2. Predict units sold at a price of 15, rounded to 1 decimal
#      (use the unrounded slope and intercept).
# Print exactly:
# Slope: -2.19
# Intercept: 70.29
# Predicted units at 15: 37.5
import numpy as np
import pandas as pd

demand = pd.DataFrame({
    "price": [10, 12, 14, 16, 18, 20],
    "units": [48, 45, 39, 36, 30, 27],
})

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
import numpy as np
import pandas as pd

demand = pd.DataFrame({
    "price": [10, 12, 14, 16, 18, 20],
    "units": [48, 45, 39, 36, 30, 27],
})

def standard_units(x):
    return (x - np.mean(x)) / np.std(x)

def correlation(x, y):
    return np.mean(standard_units(x) * standard_units(y))

def slope(x, y):
    return correlation(x, y) * np.std(y) / np.std(x)

def intercept(x, y):
    return np.mean(y) - slope(x, y) * np.mean(x)

a = slope(demand['price'], demand['units'])
b = intercept(demand['price'], demand['units'])
print("Slope:", round(a, 2))
print("Intercept:", round(b, 2))
print("Predicted units at 15:", round(a * 15 + b, 1))
Slope: -2.19
Intercept: 70.29
Predicted units at 15: 37.5
### 8. Predicting in Standard Units
# Monthly spending has mean $80 and SD $25; r between visits and spending is 0.6.
# A customer's visits are 2.0 SDs above average.
#   1. Predict the customer's spending in standard units: r * (visits in standard units).
#   2. Convert the prediction to dollars: mean + (standard units) * SD.
# Print exactly:
# Predicted spend (standard units): 1.2
# Predicted spend: 110.0
import numpy as np
import pandas as pd

r = 0.6
visits_su = 2.0
spend_mean = 80
spend_sd = 25

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
import numpy as np
import pandas as pd

r = 0.6
visits_su = 2.0
spend_mean = 80
spend_sd = 25

spend_su = r * visits_su
print("Predicted spend (standard units):", spend_su)
print("Predicted spend:", spend_mean + spend_su * spend_sd)
Predicted spend (standard units): 1.2
Predicted spend: 110.0
### 9. How Far Off Are the Predictions?
#   1. Compute the fitted values of the regression line of units on price.
#   2. Compute the RMSE: sqrt(mean of (actual - fitted) ** 2), rounded to 2 decimals.
# Print exactly:
# RMSE: 0.72
import numpy as np
import pandas as pd

demand = pd.DataFrame({
    "price": [10, 12, 14, 16, 18, 20],
    "units": [48, 45, 39, 36, 30, 27],
})

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
import numpy as np
import pandas as pd

demand = pd.DataFrame({
    "price": [10, 12, 14, 16, 18, 20],
    "units": [48, 45, 39, 36, 30, 27],
})

def standard_units(x):
    return (x - np.mean(x)) / np.std(x)

def correlation(x, y):
    return np.mean(standard_units(x) * standard_units(y))

def slope(x, y):
    return correlation(x, y) * np.std(y) / np.std(x)

def intercept(x, y):
    return np.mean(y) - slope(x, y) * np.mean(x)

fitted = slope(demand['price'], demand['units']) * demand['price'] + intercept(demand['price'], demand['units'])
print("RMSE:", round(np.sqrt(np.mean((demand['units'] - fitted) ** 2)), 2))
RMSE: 0.72
### 10. Does the Spread Grow?
# Residuals from a regression of delivery cost on distance, sorted by fitted value.
#   1. Compute the SD (np.std) of the residuals for the 5 smallest fitted values
#      and for the 5 largest, each rounded to 2 decimals.
#   2. Print whether the SD for the largest fitted values is more than twice the other.
# Print exactly:
# SD (small fitted): 1.47
# SD (large fitted): 7.4
# Spread grows: True
import numpy as np
import pandas as pd

diag = pd.DataFrame({
    "fitted": [20, 25, 30, 35, 40, 45, 50, 55, 60, 65],
    "residual": [1, -1, 2, -2, 1, -6, 7, -8, 9, -7],
})

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
import numpy as np
import pandas as pd

diag = pd.DataFrame({
    "fitted": [20, 25, 30, 35, 40, 45, 50, 55, 60, 65],
    "residual": [1, -1, 2, -2, 1, -6, 7, -8, 9, -7],
})

small = round(np.std(diag['residual'].iloc[:5]), 2)
large = round(np.std(diag['residual'].iloc[5:]), 2)

print("SD (small fitted):", small)
print("SD (large fitted):", large)
print("Spread grows:", large > 2 * small)
# Predictions for long distances are much less precise (heteroscedasticity).
SD (small fitted): 1.47
SD (large fitted): 7.4
Spread grows: True