# Inferential Statistics Ib - Frequentism

## Learning objectives

Welcome to the second Frequentist inference mini-project! Over the course of working on this mini-project and the previous frequentist mini-project, you'll learn the fundamental concepts associated with frequentist inference. The following list includes the topics you will become familiar with as you work through these two mini-projects:
* the _z_-statistic
* the _t_-statistic
* the difference and relationship between the two
* the Central Limit Theorem, its assumptions and consequences
* how to estimate the population mean and standard deviation from a sample
* the concept of a sampling distribution of a test statistic, particularly for the mean
* how to combine these concepts to calculate confidence intervals and p-values
* how those confidence intervals and p-values allow you to perform hypothesis (or A/B) tests

## Prerequisites

* what a random variable is
* what a probability density function (pdf) is
* what the cumulative density function is
* a high-level sense of what the Normal distribution

If these concepts are new to you, please take a few moments to Google these topics in order to get a sense of what they are and how you might use them.

These two notebooks were designed to bridge the gap between having a basic understanding of probability and random variables and being able to apply these concepts in Python. This second frequentist inference mini-project focuses on a real-world application of this type of inference to give you further practice using these concepts. 

In the previous notebook, we used only data from a known normal distribution. You'll now tackle real data, rather than simulated data, and answer some relevant real-world business problems using the data.

## Hospital medical charges

Imagine that a hospital has hired you as their data analyst. An administrator is working on the hospital's business operations plan and needs you to help them answer some business questions. This mini-project, as well as the bootstrap and Bayesian inference mini-projects also found in this unit are designed to illustrate how each of the inferential statistics methods have their uses for different use cases. In this assignment notebook, you're going to use frequentist statistical inference on a data sample to answer the questions:
* has the hospital's revenue stream fallen below a key threshold?
* are patients with insurance really charged different amounts than those without?
Answering that last question with a frequentist approach makes some assumptions, or requires some knowledge, about the two groups. In the next mini-project, you'll use bootstrapping to test that assumption. And in the final mini-project of the unit, you're going to create a model for simulating _individual_ charges (not a sampling distribution) that the hospital can use to model a range of scenarios.

We are going to use some data on medical charges obtained from [Kaggle](https://www.kaggle.com/easonlai/sample-insurance-claim-prediction-dataset). For the purposes of this exercise, assume the observations are the result of random sampling from our one hospital. Recall in the previous assignment, we introduced the Central Limit Theorem (CLT), and how it tells us that the distributions of sample statistics approach a normal distribution as $n$ increases. The amazing thing about this is that it applies to the sampling distributions of statistics that have been calculated from even highly non-normal distributions of data. Remember, also, that hypothesis testing is very much based on making inferences about such sample statistics. You're going to rely heavily on the CLT to apply frequentist (parametric) tests to answer the questions in this notebook.


```python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import t
from scipy.stats import norm
from numpy.random import seed
from scipy.stats import stats
medical = pd.read_csv('data/insurance2.csv')
```


```python
medical.shape
```




    (1338, 8)




```python
medical.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>age</th>
      <th>sex</th>
      <th>bmi</th>
      <th>children</th>
      <th>smoker</th>
      <th>region</th>
      <th>charges</th>
      <th>insuranceclaim</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>19</td>
      <td>0</td>
      <td>27.900</td>
      <td>0</td>
      <td>1</td>
      <td>3</td>
      <td>16884.92400</td>
      <td>1</td>
    </tr>
    <tr>
      <th>1</th>
      <td>18</td>
      <td>1</td>
      <td>33.770</td>
      <td>1</td>
      <td>0</td>
      <td>2</td>
      <td>1725.55230</td>
      <td>1</td>
    </tr>
    <tr>
      <th>2</th>
      <td>28</td>
      <td>1</td>
      <td>33.000</td>
      <td>3</td>
      <td>0</td>
      <td>2</td>
      <td>4449.46200</td>
      <td>0</td>
    </tr>
    <tr>
      <th>3</th>
      <td>33</td>
      <td>1</td>
      <td>22.705</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>21984.47061</td>
      <td>0</td>
    </tr>
    <tr>
      <th>4</th>
      <td>32</td>
      <td>1</td>
      <td>28.880</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>3866.85520</td>
      <td>1</td>
    </tr>
  </tbody>
</table>
</div>



__Q:__ Plot the histogram of charges and calculate the mean and standard deviation. Comment on the appropriateness of these statistics for the data.

__A:__


```python
#Histogram of Charges:
medical['charges'].plot(kind = 'hist', edgecolor = 'white', bins= 20, xlim = 0)
plt.xlabel('Medical Charges')
plt.title('Distribution of Medical Charges')
```


```python
mean_charges= np.mean(medical['charges'])
print('Mean Medical Charges:', mean_charges)

std_charges= np.std(medical['charges'], ddof=1)
print('Standard Deviation Medical Charges:', std_charges)

#Plot does notrepresent normal distribution. 
```

    Mean Medical Charges: 13270.422265141257
    Standard Deviation Medical Charges: 12110.011236693994



```python
#Descriptive Statistics: 
medical.describe()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>age</th>
      <th>sex</th>
      <th>bmi</th>
      <th>children</th>
      <th>smoker</th>
      <th>region</th>
      <th>charges</th>
      <th>insuranceclaim</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>count</th>
      <td>1338.000000</td>
      <td>1338.000000</td>
      <td>1338.000000</td>
      <td>1338.000000</td>
      <td>1338.000000</td>
      <td>1338.000000</td>
      <td>1338.000000</td>
      <td>1338.000000</td>
    </tr>
    <tr>
      <th>mean</th>
      <td>39.207025</td>
      <td>0.505232</td>
      <td>30.663397</td>
      <td>1.094918</td>
      <td>0.204783</td>
      <td>1.515695</td>
      <td>13270.422265</td>
      <td>0.585202</td>
    </tr>
    <tr>
      <th>std</th>
      <td>14.049960</td>
      <td>0.500160</td>
      <td>6.098187</td>
      <td>1.205493</td>
      <td>0.403694</td>
      <td>1.104885</td>
      <td>12110.011237</td>
      <td>0.492871</td>
    </tr>
    <tr>
      <th>min</th>
      <td>18.000000</td>
      <td>0.000000</td>
      <td>15.960000</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>1121.873900</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>25%</th>
      <td>27.000000</td>
      <td>0.000000</td>
      <td>26.296250</td>
      <td>0.000000</td>
      <td>0.000000</td>
      <td>1.000000</td>
      <td>4740.287150</td>
      <td>0.000000</td>
    </tr>
    <tr>
      <th>50%</th>
      <td>39.000000</td>
      <td>1.000000</td>
      <td>30.400000</td>
      <td>1.000000</td>
      <td>0.000000</td>
      <td>2.000000</td>
      <td>9382.033000</td>
      <td>1.000000</td>
    </tr>
    <tr>
      <th>75%</th>
      <td>51.000000</td>
      <td>1.000000</td>
      <td>34.693750</td>
      <td>2.000000</td>
      <td>0.000000</td>
      <td>2.000000</td>
      <td>16639.912515</td>
      <td>1.000000</td>
    </tr>
    <tr>
      <th>max</th>
      <td>64.000000</td>
      <td>1.000000</td>
      <td>53.130000</td>
      <td>5.000000</td>
      <td>1.000000</td>
      <td>3.000000</td>
      <td>63770.428010</td>
      <td>1.000000</td>
    </tr>
  </tbody>
</table>
</div>



__Q:__ The administrator is concerned that the actual average charge has fallen below 12000, threatening the hospital's operational model. On the assumption that these data represent a random sample of charges, how would you justify that these data allow you to answer that question? And what would be the most appropriate frequentist test, of the ones discussed so far, to apply?

__A:__ Will justify as under:
1. Calculate Margin of Error using Z score. 
2. Identify if the mean confidence interval is lower than 12000 or higher. 
3. Will use one-sided test.



__Q:__ Given the nature of the administrator's concern, what is the appropriate confidence interval in this case? A one-sided or two-sided interval? Calculate the critical value and the relevant 95% confidence interval for the mean and comment on whether the administrator should be concerned?

__A:__ Appropriate Confidence Interval is one-sided interval ~ 12621 which shows with 95% confidence level that it is higher than the actual average charge of 12000.  


```python
#Calculate Margin of error using Z:
#Margin of Error = z-critical value * standard deviation: 
margin_error_z = norm.ppf(q= 0.975) * (std_charges / (np.sqrt(medical.shape[0]))) #here q = 1- (100%-95%)/2 = 0.975
margin_error_z
```




    648.880286912097




```python
print('Mean Confidence Interval Using Z:', [mean_charges-margin_error_z, mean_charges+margin_error_z]) 
```

    Mean Confidence Interval Using Z: [12621.54197822916, 13919.302552053354]


The administrator then wants to know whether people with insurance really are charged a different amount to those without.

__Q:__ State the null and alternative hypothesis here. Use the _t_-test for the difference between means where the pooled standard deviation of the two groups is given by
\begin{equation}
s_p = \sqrt{\frac{(n_0 - 1)s^2_0 + (n_1 - 1)s^2_1}{n_0 + n_1 - 2}}
\end{equation}

and the *t* test statistic is then given by

\begin{equation}
t = \frac{\bar{x}_0 - \bar{x}_1}{s_p \sqrt{1/n_0 + 1/n_1}}.
\end{equation}

What assumption about the variances of the two groups are we making here?

__A:__ Both groups have same variance. 

__Q:__ Perform this hypothesis test both manually, using the above formulae, and then using the appropriate function from [scipy.stats](https://docs.scipy.org/doc/scipy/reference/stats.html#statistical-tests) (hint, you're looking for a function to perform a _t_-test on two independent samples). For the manual approach, calculate the value of the test statistic and then its probability (the p-value). Verify you get the same results from both.

__A:__ 


```python
#Insured Sample
insured=medical.query('insuranceclaim ==1')

#Uninsured Sample
uninsured = medical.query('insuranceclaim==0')
```


```python
#Mean Insured Charges:
mean_insured= np.mean(insured.charges)
print('Mean Insured Sample:', mean_insured)

#Standard Deviation of Insured Charges: 
std_insured = np.std(insured.charges)
print('Standard Deviation Insured Sample:', std_insured)

#Length of Insured Samples: 
n_insured = len(insured)
print(n_insured)
```

    Mean Insured Sample: 16423.928276537663
    Standard Deviation Insured Sample: 14036.956250260411
    783



```python
#Mean uninsured Charges:
mean_uninsured = np.mean(uninsured.charges)
print('Mean Uninsured Sample:', mean_uninsured)

#Standard Deviation of unInsured Charges: 
std_uninsured = np.std(uninsured.charges)
print('Standard Deviation Uninsured Sample:', std_uninsured)

#Length of Uninsured Samples: 
n_uninsured = len(uninsured)
print(n_uninsured)
```

    Mean Uninsured Sample: 8821.421892306294
    Standard Deviation Uninsured Sample: 6440.699841605233
    555



```python
#Compare numerical results using manual approach and t-test function: 

#1) Manual Approach: Using formulae

std_pooled = np.sqrt((((n_insured-1)*std_insured**2) + ((n_uninsured-1)*std_uninsured**2))/(n_insured + n_uninsured-2))
print('Pooled Standard Deviation of two Samples:', std_pooled)

t = (mean_insured - mean_uninsured)/(std_pooled *(np.sqrt(1/n_insured + 1/n_uninsured)))
print('t-statistics:', t)

#P-Value: 
p = norm.pdf(t)

print('p-value:', p)
```

    Pooled Standard Deviation of two Samples: 11512.282899205744
    t-statistics: 11.901306943555385
    p-value: 6.981270779090461e-32



```python
# Using Function: This is a two-sided test for the null hypothesis that two independent samples have identical average (expected) values.
#Assumption: Both independent sample population variance are equal
ttest_equal_variance=  stats.ttest_ind_from_stats(mean_insured, std_insured, n_insured, mean_uninsured, std_uninsured, n_uninsured, equal_var=True)
print('Result:',ttest_equal_variance)
```

    Result: Ttest_indResult(statistic=11.901306943555387, pvalue=4.090550214373679e-31)


Congratulations! Hopefully you got the exact same numerical results. This shows that you correctly calculated the numbers by hand. Secondly, you used the correct function and saw that it's much easier to use. All you need to do pass your data to it.

__Q:__ In the above calculations, we assumed the sample variances were equal. We may well suspect they are not (we'll explore this in another assignment). The calculation becomes a little more complicated to do by hand in this case, but we now know of a helpful function. Check the documentation for the function to tell it not to assume equal variances and perform the test again.

__A:__ Documentation: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ttest_ind_from_stats.html#r24a95fcea38c-2

Select option equal_var as <b>False


```python
#Asuumption:  Both independent sample population variance are not equal: 

ttest_unequal_variance=  stats.ttest_ind_from_stats(mean_insured, std_insured, n_insured, mean_uninsured, std_uninsured, n_uninsured, equal_var=False)
print('Result:',ttest_unequal_variance)
```

    Result: Ttest_indResult(statistic=13.307332624349796, pvalue=9.974516564429595e-38)


__Q:__ Conceptual question: look through the documentation for statistical test functions in scipy.stats. You'll see the above _t_-test for a sample, but can you see an equivalent one for performing a *z*-test from a sample? Comment on your answer.

__A:__ Documentation for z_test: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.mstats.zscore.html

Use function scipy.stats.zscore to calculate z-score of each value in the sample, standardized by its mean and standard deviation. 

## Learning outcomes

Having completed this project notebook, you now have good hands-on experience:
* using the central limit theorem to help you apply frequentist techniques to answer questions that pertain to very non-normally distributed data from the real world
* performing inference using such data to answer business questions
* forming a hypothesis and framing the null and alternative hypotheses
* testing this using a _t_-test

3d36fb557dde3d8ed6d93aae4ff8ca60f5dfcbc4
ipynb
Jupyter Notebook
Mini_projects/Inferential_Inference/inferential_statistics_1b-Q6.25.ipynb
psanghal/Springboard-Data-Science
47224935d7de51355acedee822b3d27ba820548c
MIT
2019-08-07T17:12:03.000Z
2019-08-07T17:12:03.000Z
Mini_projects/Inferential_Inference/inferential_statistics_1b-Q6.25.ipynb
psanghal/Springboard-Data-Science
47224935d7de51355acedee822b3d27ba820548c
MIT
Mini_projects/Inferential_Inference/inferential_statistics_1b-Q6.25.ipynb
psanghal/Springboard-Data-Science
47224935d7de51355acedee822b3d27ba820548c
MIT
2019-11-13T16:08:32.000Z
2019-11-13T16:08:32.000Z
Qwen/Qwen-72B
1. YES
2. YES