lab02_solutions
pdf
keyboard_arrow_up
School
University of California, Berkeley *
*We aren’t endorsed by this school
Course
102
Subject
Statistics
Date
Feb 20, 2024
Type
Pages
13
Uploaded by ProfComputer848
lab02
October 4, 2022
[6]:
# Initialize Otter
import
otter
grader
=
otter
.
Notebook(
"lab02.ipynb"
)
1
Lab 2: Loss and risk
Welcome to the second Data 102 lab!
The goal of this lab is to introduce loss functions in hypothesis testing problems.
The code and responses you need to fill in are represented by
...
. There is additional documentation
for each part as you go along.
1.1
Collaboration Policy
Data science is a collaborative activity. While you may talk with others about the labs, we ask that
you
write your solutions individually
.
If you do discuss the assignments with others please
include their names
in the cell below.
1.2
Submission
NOTE: This lab will be submitted using an auto-grader.
Therefore, the submission
instructions for this lab are different than before.
To submit the lab: 1. Navigate to Kernel > Restart & Run All. Ensure that all public test cases
pass locally. 2. Save your notebook under File > Save and Checkpoint. If you do not save your
notebook, then you might run into issues with the downloaded .zip file. 3. Run the very last cell,
which generates a .zip file for you to download to your local machine. Click the “here” button to
download the .zip file. You may receive an error that the .zip file was unable to be created because
there was an issue with PDF generation.
You need to ensure that you’ve answered all of the
questions that require a manual response. 4. If your work downloads as several independent files
rather than as a .zip, you are likely using Safari on a Mac. Follow these instructions to make sure
you can download your work as a zip: https://macreports.com/how-to-download-zip-files-without-
unzipping/ 5.
Upload this .zip to the correct assignment on Gradescope.
After submitting, the
autograder built-in to the Gradescope assignment will tell you which public test cases you’ve passed
and failed. There are no hidden test cases.
For full credit, this assignment should be completed and submitted before Wednesday,
September 14, 2022 at 11:59 PM. PT
1
1.3
Collaborators
Write the names of your collaborators in this cell.
<Collaborator Name> <Collaborator e-mail>
[7]:
import
matplotlib.pyplot
as
plt
import
numpy
as
np
import
pandas
as
pd
import
seaborn
as
sns
from
scipy.stats
import
norm
import
itertools
from
ipywidgets
import
interact, interactive
import
hashlib
%
matplotlib
inline
sns
.
set(style
=
"dark"
)
plt
.
style
.
use(
"ggplot"
)
def
get_hash
(num):
"""Helper function for assessing correctness"""
return
hashlib
.
md5(
str
(num)
.
encode())
.
hexdigest()
2
Question 1: Custom Loss Functions for Hypothesis Testing
The first question looks at a medical diagnostic decision. For each person that undergoes testing,
the null hypothesis is that they don’t have the virus, and the alternative is that they do.
The null hypothesis
𝐻
0
: Person
𝑋
does not have the virus.
The alternative hypothesis
𝐻
1
: Person
𝑋
has the virus.
Suppose that you devise a test which takes some measurements from each test subject and then
computes a corresponding p-value.
Last week, we looked at several approaches for controllling False Positive Rate (FPR), Family Wise
Error Rate (FWER) and False Discovery Rate (FDR). However, they all have some drawbacks for
medical decision making: FPR and FWER do not depend on the prevalence of the disease and
neither of them allows a decision maker to consider different misclassification costs arising from
false-negative and false-positive diagnoses.
When making medical decisions, wrong diagnoses carry different costs.
Deciding that a patient
does not have the virus when in reality they do is a
False Negative
. The potential consequences
of such a decision are severe: lack of treatment, risk of infecting others, and even premature death.
On the other hand, deciding that a patient has the virus when in reality they don’t is a
False
Positive
. The potential consequences of that include distress, unnecesary treatment and costs of
subsequent testing.
This is certainly not ideal, but less severe than the consequences of a false
negative.
2
We’ve previously evaluated decisions in terms of their TPR and FPR, and showed how ROC curves
demonstrate the trade-off curve between the two quantities. We saw that it is not always clear how
to choose the best trade-off.
A very popular way of choosing the trade-off, and simultaneously comparing different procedures,
is the idea of
risk
that we learnt in Lecture 5.
Here, the analyst constructs a loss function by
specifying the
cost
of making each type of mistake.
2.0.1
Question 1a
Let’s assume that we estimate the cost of making a false negative mistake to be
𝑘
-times larger than
the cost of a false positive. We can express that via a
loss function
, shown below:
⎧
{
⎨
{
⎩
𝑙(𝐷 = 1|𝑅 = 0) = 1
𝑙(𝐷 = 0|𝑅 = 1) = ?
𝑙(𝐷 = 0|𝑅 = 0) = 𝑙(𝐷 = 1|𝑅 = 1) = 0
What should be the value of
?
in the equation above?
Assign your answer to the variable
question_mark
below
as a string
.
[8]:
question_mark
=
'k'
# SOLUTION
[9]:
grader
.
check(
"q1ai"
)
[9]:
q1ai results: All test cases passed!
Do FPR and FWER depend on the prevalence of the disease?
Type your answer here, replacing this text.
SOLUTION:
No, see text above.
Above, you were given one example of when the consequences of a False Negative is more severe
than the consequences of a False Positive. Come up with one example of the opposite: when the
consequences of a False Positive is more severe than the consequences of a False Negative.
Type your answer here, replacing this text.
SOLUTION:
E.g. granting someone security clearance.
2.1
1.b: Compute average empirical loss
Assume we have a sample of
𝑁
patients for which a test outputs the following confusion matrix:
Decision = 0
Decision = 1
Reality = 0
TN
FP
Reality = 1
FN
TP
3
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
2.1.1
Compute the average loss this procedure incurs by summing up the losses for
every mis-diagnosis and then dividing by the total number of tests.
[10]:
def
compute_average_loss
(results_dictionary, factor_k):
""" Function that computes average loss for a given confusion matrix and a
␣
↪
multiplicative
factor_k that compares the consequences of false nagatives and false
␣
↪
positives.
Inputs:
results_dictionary : a dictionary with the counts of TP, FP, TN and
␣
↪
FN
factor_k : float, quantifies the ratio of the negative consequences
␣
↪
of
false negatives compared to false positives
Outputs:
average_loss : float
"""
TP_count
=
results_dictionary[
'TP_count'
]
FP_count
=
results_dictionary[
'FP_count'
]
TN_count
=
results_dictionary[
'TN_count'
]
FN_count
=
results_dictionary[
'FN_count'
]
# BEGIN SOLUTION
N
=
TP_count
+
TN_count
+
FP_count
+
FN_count
average_loss
=
(FP_count
+
FN_count
*
factor_k)
/
N
return
average_loss
# END SOLUTION
[11]:
grader
.
check(
"q1b"
)
[11]:
q1b results: All test cases passed!
2.2
1.c: Compute the average loss (empirical risk) with respect to various levels
𝛼
In this part, we will use a simple test that rejects the null hypothesis whenever the p-value of a
patient is smaller than some level
𝛼
.
Our goal is to investigate the performance of the test at different levels with respect to the custom
loss defined in
1.b
.
Recall the naive test from Lab 01:
[12]:
def
alpha_threshold_decisions
(p_values, alpha):
"""
4
Returns decisions on p-values using naive thresholding.
Inputs:
p_values: array of p-values
alpha: threshold (significance level)
Returns:
decisions: binary array of same length as p-values, where
␣
↪
`decisions[i]` is 1
if `p_values[i]` is deemed significant at level `alpha`, and 0 otherwize
"""
decisions
=
p_values
<=
alpha
return
decisions
Let’s also bring in from Lab 01 the function that computes the counts of TP, TN, FP, FN by
comparing the decision to the reality.
[13]:
def
report_results
(decisions, reality):
"""
Produces a dictionary with counts for the true positives, true negatives,
false negatives, and false positives from the input `decisions`
and `reality` arrays.
Inputs:
decision: array of 0/1 values where 1 indicates that patient has the
␣
↪
virus.
reality: array of 0/1 values where 1 indicates a draw from the
␣
↪
alternative.
Outputs: a dictionary of TN, TP, FN, and FP counts.
"""
TP_count
=
np
.
sum(decisions
*
reality)
TN_count
=
np
.
sum((
1-
decisions)
*
(
1-
reality))
FP_count
=
np
.
sum((decisions)
*
(
1-
reality))
FN_count
=
np
.
sum((
1-
decisions)
*
(reality))
results_dictionary
=
{
"TN_count"
: TN_count,
"TP_count"
: TP_count,
"FN_count"
: FN_count,
"FP_count"
: FP_count,
}
return
results_dictionary
First, we will generate ground truth data.
Assume there are
𝑁
subjects, out of which a fraction truly have the virus. This fraction is known
as
prevalence
:
ℙ{𝑅 = 1}
.
5
The function below generates p-values associated with each test subject.
[14]:
def
generate_ground_truth
(N, prevalence):
""" Creates simulated p-values corresponding to N subjects at a
specified disease prevalence level"""
rs
=
np
.
random
.
RandomState(
1
)
reality
=
rs
.
binomial(
1
, prevalence, N)
p_values
= 1 -
norm
.
cdf(rs
.
randn(N)
+
reality)
return
(p_values, reality)
[15]:
N
= 10000
prevalence
= 0.1
p_values, reality
=
generate_ground_truth(N, prevalence)
2.2.1
In the cell below complete the function that computes the average loss (empir-
ical risk) for an
𝛼
level test.
[16]:
# TODO: complete the function
def
compute_alpha_average_loss
(p_values, reality, alpha, factor_k):
"""
Computes the observed average loss for an alpha level test.
Inputs:
p_values: array of floats, p-value[i] is the p-values associated with
␣
↪
test subject i.
reality: array of 0/1s
alpha: float, threshold for rejecting the null hypothesis
factor_k: float, quantifies the ratio of the negative consequences of
false negatives compared to false positives
Outputs:
average_loss: float, average observed loss
"""
# HINT: Your code should take advantage of functions already defined in
␣
↪
this notebook.
# BEGIN SOLUTION
decisions
=
alpha_threshold_decisions(p_values, alpha)
results
=
report_results(decisions, reality)
average_loss
=
compute_average_loss(results, factor_k)
return
average_loss
# END SOLUTION
[17]:
grader
.
check(
"q1c"
)
[17]:
q1c results: All test cases passed!
6
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
2.3
1.d Investigate the average loss plot for different levels of disease prevalence
The function below generates ground truth for a sample of 10000 subjects for a given disease
prevalence. It then computes the average loss for diagnostic decisions at level
𝛼
, where
𝛼 ∈ [0, 1]
.
Finally, it plots the resulting average loss (y axis) at a level
𝛼
(x axis).
[18]:
# Run this as is after completing the `compute_alpha_average_loss` function
# Do not modify
def
plot_average_loss
(prevalence, factor_k):
N
= 10000
# generate ground truth
p_values, reality
=
generate_ground_truth(N, prevalence)
# vary alpha from 0 to 1
alpha_array
=
np
.
arange(
0
,
1
,
0.05
)
# compute average loss for each alpha
average_loss_array
=
[compute_alpha_average_loss(p_values, reality, alpha,
␣
↪
factor_k)
for
alpha
in
alpha_array]
optimal_alpha
=
alpha_array[np
.
argmin(average_loss_array)]
plt
.
figure(figsize
=
(
10
,
6
))
plt
.
plot(alpha_array, average_loss_array, label
=
'Average Loss'
)
plt
.
axvline(x
=
optimal_alpha, ls
=
'--'
, label
=
'Optimal $
\\
alpha$'
,
␣
↪
c
=
'green'
)
plt
.
xlabel(
'$
\\
alpha$ level'
)
plt
.
ylabel(
'Average Loss'
)
plt
.
legend()
plt
.
show()
[19]:
# Visualize interactive plot: Do not modify
interactive_plot
=
interactive(plot_average_loss, prevalence
=
(
0.0
,
0.11
,
0.01
),
␣
↪
factor_k
=
(
0
,
100
,
5
))
interactive_plot
interactive(children=(FloatSlider(value=0.05, description='prevalence', max=0.
↪
11, step=0.01), IntSlider(value=…
Fix the
prevalence
of the disease at
0.05
(
5%
). Using the slider in the interactive plot above, try
out different values for the multiplicative
factor_k
. What do you notice? How would you adjust
your diagnosic procedure based on the value of
factor_k
? What combination of
factor_k
and
𝛼
gives you the lowest possible loss, and why?
Type your answer here, replacing this text.
SOLUTION
: Changing the value of
factor_k
changes the
𝛼
level that minimizes the average
loss.
The level
𝛼
that minimizes the average loss at
prevalence
= 0.05
changes depending on
factor_k
: as
factor_k
increases, the
𝛼
level should also increase to obtain the minimal loss and
vice versa.
The combination of
factor_k
and
𝛼
with the lowest loss is
𝑘 = 0, 𝛼 = 0
.
A
factor_k
of zero
corresponds to not penalizing false negatives, and so the optimal decision rule is to always return
𝐷 = 0
.
7
Fix
factor_k
at
50
(meaning that the negative consequence of a false negative are 50 times larger
than the negative consequences of a false positive). Using the slider in the interactive plot above,
try out different values for the true prevalence of the disease. What do you notice? How would
you adjust your diagnostic procedure based on the prevalence of the disease? What combination
of prevalence and
𝛼
gives you the lowest possible loss, and why?
Type your answer here, replacing this text.
SOLUTION
: Changing the value of
prevalence
changes the
𝛼
level that minimizes the average
loss. The level
𝛼
that minimizes the average loss at
factor_k
= 50
changes depending on
factor_k
:
as
prevalence
increases, the
𝛼
level should also increase to obtain the minimal loss and vice versa.
An average loss of
0
is achievable when
prevalence
equals either
0
or
1
. In this case, all
𝑅
take
on the same value and so we can get every decision right with a threshold of
𝛼 = 0
and
𝛼 = 1
respectively.
3
Question 2.
In the previous question you played the role of a test designer or device manufacturer that needs to
find an appropriate way to calibrate the test such that it minimizes some desired loss. In this part
put yourself in the shoes of a medical professional who is using this testing device without really
knowing all the internals of it.
The test kit claims a certain specificity (
1 − 𝐹𝑃𝑅
) and sensitivity (
1 − 𝐹𝑁𝑅
).
Assume you have a new patient that came in and tested positive (you have only the binary output
of the test). Your goal is to determine whether or not to put this patient through treatment.
To answer this we will make the following assumptions: - Assume as in part 1, that getting a false
negative is
𝑘
times worse than getting a false positive. - Assume that you know the
prevalence
of
this disease. - Assume that the test has a certain
specificity
and
sensitivity
.
3.1
2.a Compute the posterior
Complete the function below to compute the posterior probability that the patient truly has the
disease conditioned on a positive test result: namely, compute
ℙ{𝑅 = 1|𝐷 = 1}
as a function of
prevalence
,
sensitivity
and
specificity
.
Hint: We’ve already seen this in HW1 and discussion 2
[20]:
def
compute_posterior_probability
(prevalence, sensitivity, specificity):
"""
Computes the posterior probability that the patient trully has the disease
conditioned on a positive test result.
Inputs:
prevalence: float, fraction of the population that has the disease
sensitivity: float, 1 - false negative rate
specificity: float, 1 - false positive rate
Outputs:
8
posterior probability: probability that the patient has the disease
␣
↪
given a positive test result
"""
# BEGIN SOLUTION
TP
=
sensitivity
FP
= 1 -
specificity
# END SOLUTION
posterior_probability
=
(TP
*
prevalence)
/
(TP
*
prevalence
+
FP
*
␣
↪
(
1-
prevalence))
# SOLUTION
return
round
(posterior_probability,
3
)
[21]:
grader
.
check(
"q2a"
)
[21]:
q2a results: All test cases passed!
[22]:
# Let's compute a few posterior probabilities
prevalence
=
[
0.001
,
0.1
]
sensitivity
= 0.98
specificity
= 0.99
print
(
'Conditioned on a positive test result, with sensitivity
{}
and
␣
↪
specificity
{}
:'
.
format(sensitivity, specificity))
print
(
'For a low prevalence disesase (
{}
), the posterior probability that the
␣
↪
test subject is truly positive is
{:.3f}
'
.
format
(prevalence[
0
], compute_posterior_probability(prevalence[
0
],
␣
↪
sensitivity, specificity)))
print
(
'For a high prevalence disesase (
{}
), the posterior probability that the
␣
↪
test subject is truly positive is
{:.3f}
'
.
format
(prevalence[
1
], compute_posterior_probability(prevalence[
1
],
␣
↪
sensitivity, specificity)))
Conditioned on a positive test result, with sensitivity 0.98 and specificity
0.99:
For a low prevalence disesase (0.001), the posterior probability that the test
subject is truly positive is 0.089
For a high prevalence disesase (0.1), the posterior probability that the test
subject is truly positive is 0.916
3.2
2.b Compute expected loss function with respect to posterior distribution
Given that the test returned a positive result (that
𝐷 = 1
), you can make one of two posible
decisions: -
𝑇 = 1
: start the treatment -
𝑇 = 0
: do not start the treatment despite the positive
test result
Similarly to Question 1, let’s assume that we estimate the cost of not treating a truly sick patient
to be
𝑘
times larger than the cost of treating a patient that is not truly sick.
Recall from lecture that a loss function takes in a hidden state of the world
𝜃
(in this case, that’s
the reality
𝑅
: whether or not the patient is sick), and a decision
𝛿
(in this case, that’s
𝑇
: whether
9
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
or not to treat). Our loss function has the formula:
⎧
{
⎨
{
⎩
ℓ(𝑅 = 0, 𝑇 = 1) = 1
ℓ(𝑅 = 1, 𝑇 = 0) = 𝑘
ℓ(𝑅 = 0, 𝑇 = 0) = ℓ(𝑅 = 1, 𝑇 = 1) = 0
3.2.1
Compute the expected loss for each treatment decision, given that someone
tested positive:
𝔼[𝑙(𝑅, 𝑇 = 0)|𝐷 = 1] = ?
𝔼[𝑙(𝑅, 𝑇 = 1)|𝐷 = 1] = ?
Hint: Think carefully about what is random here. What’s it’s distribution?
[23]:
def
compute_expected_loss
(treatment, posterior_probability, factor_k):
"""
Compute the expected loss for the treatment.
Inputs:
treatment: int 0/1 (0-no treatment, 1-treatment)
posterior_probability: float, probability that the patient is truly
␣
↪
sick given positive test result
k_factor : float, quantifies the ratio of the negative consequences of
false negatives compared to false positives
"""
# BEGIN SOLUTION
if
treatment
== 1
:
expected_loss
= 1 -
posterior_probability
else
:
expected_loss
=
factor_k
*
posterior_probability
return
expected_loss
# END SOLUTION
[24]:
grader
.
check(
"q2b"
)
[24]:
q2b results: All test cases passed!
3.3
2.c Loss and Risk
Is the quantity you computed above a frequentist risk, a Bayesian posterior risk, or neither? Explain
why in two sentences or less.
Type your answer here, replacing this text.
SOLUTION
: Bayesian posterior risk. Calculated based on Bayesian concepts.
10
3.4
2.d Decide whether or not to administer the treatment by comparing the
expected losses in each case.
Compare the cost for
treatment T=1
and
no treatment T=0
and choose the option with lower
expected loss.
[25]:
# TODO: complete the function
def
make_decision
(posterior_probability, factor_k):
"""
Make a decisions to adminster or not the treatment: T=1 or T=0 .
Inputs:
posterior_probability: float, probability that the patient is truly
␣
↪
sick given positive test result
k_factor : float, quantifies the ratio of the negative consequences of
false negatives compared to false positives
Outputs:
treatment: int, 0/1
"""
# BEGIN SOLUTION
loss_treat
=
compute_expected_loss(
1
, posterior_probability, factor_k)
loss_no_treat
=
compute_expected_loss(
0
, posterior_probability, factor_k)
treatment
= 1
if
loss_treat
<
loss_no_treat
else
0
return
treatment
# END SOLUTION
[26]:
grader
.
check(
"q2d"
)
[26]:
q2d results: All test cases passed!
[27]:
import
matplotlib.image
as
mpimg
img
=
mpimg
.
imread(
'baby_otter.jpg'
)
imgplot
=
plt
.
imshow(img)
imgplot
.
axes
.
get_xaxis()
.
set_visible(
False
)
imgplot
.
axes
.
get_yaxis()
.
set_visible(
False
)
plt
.
show()
11
To double-check your work, the cell below will rerun all of the autograder tests.
[28]:
grader
.
check_all()
[28]:
q1ai results: All test cases passed!
q1b results: All test cases passed!
q1c results: All test cases passed!
q2a results: All test cases passed!
q2b results: All test cases passed!
q2d results: All test cases passed!
3.5
Submission
Make sure you have run all cells in your notebook in order before running the cell below, so that
all images/graphs appear in the output. The cell below will generate a zip file for you to submit.
Please save before exporting!
12
Your preview ends here
Eager to read complete document? Join bartleby learn and gain access to the full version
- Access to all documents
- Unlimited textbook solutions
- 24/7 expert homework help
[29]:
# Save your notebook first, then run this cell to export your submission.
grader
.
export()
<IPython.core.display.HTML object>
13
Related Documents
Recommended textbooks for you
Glencoe Algebra 1, Student Edition, 9780079039897...
Algebra
ISBN:9780079039897
Author:Carter
Publisher:McGraw Hill
Big Ideas Math A Bridge To Success Algebra 1: Stu...
Algebra
ISBN:9781680331141
Author:HOUGHTON MIFFLIN HARCOURT
Publisher:Houghton Mifflin Harcourt
Holt Mcdougal Larson Pre-algebra: Student Edition...
Algebra
ISBN:9780547587776
Author:HOLT MCDOUGAL
Publisher:HOLT MCDOUGAL
Elementary Geometry for College Students
Geometry
ISBN:9781285195698
Author:Daniel C. Alexander, Geralyn M. Koeberlein
Publisher:Cengage Learning
Mathematics For Machine Technology
Advanced Math
ISBN:9781337798310
Author:Peterson, John.
Publisher:Cengage Learning,
Recommended textbooks for you
- Glencoe Algebra 1, Student Edition, 9780079039897...AlgebraISBN:9780079039897Author:CarterPublisher:McGraw HillBig Ideas Math A Bridge To Success Algebra 1: Stu...AlgebraISBN:9781680331141Author:HOUGHTON MIFFLIN HARCOURTPublisher:Houghton Mifflin HarcourtHolt Mcdougal Larson Pre-algebra: Student Edition...AlgebraISBN:9780547587776Author:HOLT MCDOUGALPublisher:HOLT MCDOUGAL
- Elementary Geometry for College StudentsGeometryISBN:9781285195698Author:Daniel C. Alexander, Geralyn M. KoeberleinPublisher:Cengage LearningMathematics For Machine TechnologyAdvanced MathISBN:9781337798310Author:Peterson, John.Publisher:Cengage Learning,
Glencoe Algebra 1, Student Edition, 9780079039897...
Algebra
ISBN:9780079039897
Author:Carter
Publisher:McGraw Hill
Big Ideas Math A Bridge To Success Algebra 1: Stu...
Algebra
ISBN:9781680331141
Author:HOUGHTON MIFFLIN HARCOURT
Publisher:Houghton Mifflin Harcourt
Holt Mcdougal Larson Pre-algebra: Student Edition...
Algebra
ISBN:9780547587776
Author:HOLT MCDOUGAL
Publisher:HOLT MCDOUGAL
Elementary Geometry for College Students
Geometry
ISBN:9781285195698
Author:Daniel C. Alexander, Geralyn M. Koeberlein
Publisher:Cengage Learning
Mathematics For Machine Technology
Advanced Math
ISBN:9781337798310
Author:Peterson, John.
Publisher:Cengage Learning,