{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "tags": [ "hide_input" ] }, "outputs": [], "source": [ "from IPython.core.display import HTML, Markdown, display\n", "\n", "import numpy.random as npr\n", "import numpy as np\n", "import pandas as pd\n", "import seaborn as sns\n", "import matplotlib.pyplot as plt\n", "import scipy.stats as stats\n", "import statsmodels.formula.api as smf\n", "import pingouin as pg\n", "import math\n", "\n", "import ipywidgets as widgets\n", "\n", "# Enable plots inside the Jupyter Notebook\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Differences between means" ] }, { "cell_type": "markdown", "metadata": { "tags": [ "popout" ] }, "source": [ "Authored by *Todd Gureckis and Brenden Lake* with input from *Matt Crump*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 1: Bootstrapping the t-distribution" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Exercise 1
\n", " Create a plot of the sampling distribution of the t statistic for 10,000 random normal samples of size 6 and 500.\n", "
" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'np' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mts\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0m_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# repeat 10000 times\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mr_sample\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrandom\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnormal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0msize\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mXXX\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m#set size size according to instruction\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0msem\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr_sample\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mddof\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msqrt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr_sample\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mt_stat\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mr_sample\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0msem\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mNameError\u001b[0m: name 'np' is not defined" ] } ], "source": [ "ts=[]\n", "for _ in range(10000): # repeat 10000 times\n", " r_sample = np.random.normal(0,1,size=XXX) #set size size according to instruction\n", " sem = np.std(r_sample,ddof=1)/np.sqrt(len(r_sample))\n", " t_stat = np.mean(r_sample)/sem\n", " ts.append(t_stat)\n", " \n", "ts2=[]\n", "for _ in range(10000):\n", " r_sample = np.random.normal(0,1,size=XXX) #set size according to instructions\n", " sem = np.std(r_sample,ddof=1)/np.sqrt(len(r_sample))\n", " t_stat = np.mean(r_sample)/sem\n", " ts2.append(t_stat)\n", " \n", "sns.displot(ts)\n", "plt.xlim([-10,10])\n", "sns.displot(ts2)\n", "plt.xlim([-10,10])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Stop and think
\n", " Do these distibutions look identical? What is different and why?\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Your answer here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 2: Relationship between p and t values" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Exercise 2
\n", " Using the following interactive widget, explore the critical value of t shown for different degrees of freedom (sample sizes) and alpha levels. Report in a cell below the critical value for a t-distribution with 9 degrees of freedom and alpha is 0.05, the critival value for a t-distribution with 50 degrees of freedom and alpha 0.05, and the critical value of a t-distribution with 25 degrees of freedom and alpha = 0.4.\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@widgets.interact(dof=widgets.IntSlider(min=1, max=53, step=1, value=10), alpha=widgets.FloatSlider(min=0,max=0.5, step=0.01, value=0.2))\n", "def plot_t_onsided(dof, alpha):\n", " fix, ax = plt.subplots(1,1,figsize=(10,6))\n", "\n", " x=np.linspace(-3.5,3.5,100)\n", " y=stats.t.pdf(x,df=dof)\n", " t_crit=stats.t.ppf(1.0-alpha, df=dof)\n", " print(t_crit)\n", " ax.plot(x,y)\n", " ax.set_ylabel(\"probability\")\n", " ax.set_xlabel(\"value of t statistic\")\n", " ax.set_title(\"One Sided Test\")\n", " ax.fill_between(x,y,where=x>t_crit,interpolate=True,facecolor='lightblue',alpha=0.2,hatch='/',edgecolor='b')\n", " ax.set_xticks([0, t_crit])\n", " #ax.set_yticklabels([])\n", "\n", "\n", " sns.despine(top=True, right=True, left=True)\n", "\n", " plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Stop and think
\n", " How do the critival values change based on sample size?\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Your answer here " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 3: Computing a one sample t-test by hand" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Exercise 3
\n", " The following cell defines a small dataset as a numpy array. Compute the t-value for this array under the null hypothesis that the true mean is 0.25. You will find the functions np.mean(), np.std(), and np.sqrt() useful. Print the t-value out in a cell by itself. Then use the stats.t.cdf() function to compute the p-value associated with that t using a one sided test. \n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Your answer here\n", "scores=np.array([.5,.56,.76,.8,.9]) # here is your data\n", "# compute the \"effect\" (i.e., difference between the mean of the values and the null hypothesis)\n", "# compute the error (i.e., the standard error of the mean), pay attention to whether you are dividing by n-1 or n\n", "# compute the t-value\n", "# use stats.t.cdf() to compute the area in the tail of the correct t-distribution for a one sided test." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Stop and think
\n", " If you have trouble, try Googling these functions to find information about the arguments!\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 4: Using `pingouin` to do a on sample `ttest()`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Exercise 4
\n", " The following cell shows how to do a one sample t-test from a numpy array. Repeat this for the null hypothesis of 0.25, 0.5, and 0.75. All tests should be one-sided. Write one sentence below each t-test to describe how you would report the test in a paper.\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "scores=np.array([.5,.56,.76,.8,.9])\n", "print(np.mean(scores))\n", "pg.ttest(x=scores, y=0.25, alternative='greater')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise 5: Paired t-test example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### STUDY DESCRIPTION\n", "\n", "Parents often sing to their children and, even as infants, children listen to and look at their parents while they are singing. Research by Mehr, Song, and Spelke (2016) sought to explore the psychological function that music has for parents and infants, by examining the hypothesis that particular melodies convey important social information to infants. Specifically, melodies convey information about social affiliation.\n", "\n", "The authors argue that melodies are shared within social groups. Whereas children growing up in one culture may be exposed to certain songs as infants (e.g., “Rock-a-bye Baby”), children growing up in other cultures (or even other groups within a culture) may be exposed to different songs. Thus, when a novel person (someone who the infant has never seen before) sings a familiar song, it may signal to the infant that this new person is a member of their social group.\n", "\n", "To test this hypothesis, the researchers recruited 32 infants and their parents to complete an experiment. During their first visit to the lab, the parents were taught a new lullaby (one that neither they nor their infants had heard before). The experimenters asked the parents to sing the new lullaby to their child every day for the next 1-2 weeks.\n", "\n", "Following this 1-2 week exposure period, the parents and their infant returned to the lab to complete the experimental portion of the study. Infants were first shown a screen with side-by-side videos of two unfamiliar people, each of whom were silently smiling and looking at the infant.The researchers recorded the looking behavior (or gaze) of the infants during this ‘baseline’ phase. Next, one by one, the two unfamiliar people on the screen sang either the lullaby that the parents learned or a different lullaby (that had the same lyrics and rhythm, but a different melody). Finally, the infants saw the same silent video used at baseline, and the researchers again recorded the looking behavior of the infants during this ‘test’ phase.For more details on the experiment’s methods, please refer to Mehr et al. (2016) Experiment 1." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first thing to do is download the .csv formatted data file, using the link above, or just click [here](http://gureckislab.org/courses/fall19/labincp/data/MehrSongSpelke2016.csv). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# get the baby data frame\n", "baby_df = pd.read_csv('http://gureckislab.org/courses/fall19/labincp/data/MehrSongSpelke2016.csv')\n", "# filter to only have the data from experiment 1\n", "experiment_one_df = baby_df[baby_df['exp1']==1]\n", "experiment_one_df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Baseline phase: Conduct a one sample t-test\n", "\n", "You first want to show that infants' looking behavior did not differ from chance during the baseline trial. The baseline trial was 16 seconds long. During the baseline, infants watched a video of two unfamiliar people, one of the left and one on the right. There was no sound during the baseline. Both of the actors in the video smiled directly at the infant.\n", "\n", "The important question was to determine whether the infant looked more or less to either person. If they showed no preference, the infant should look at both people about 50% of the time. How could we determine whether the infant looked at both people about 50% of the time?\n", "\n", "The `experiment_one_df` data frame has a column called `Baseline_Proportion_Gaze_to_Singer`. All of these values show how the proportion of time that the infant looked to the person who would later sing the familiar song to them. If the average of these proportion is .5 across the infants, then we would have some evidence that the infants were not biased at the beginning of the experiment. However, if the infants on average had a bias toward the singer, then the average proportion of the looking time should be different than .5.\n", "\n", "Using a one-sample t-test, we can test the hypothesis that our sample mean for the `Baseline_Proportion_Gaze_to_Singer` was not different from .5.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " Exercise 6
\n", " The cell below shows how to get the looking time proportions from the baseline phase. Conduct a one-sample t-test using pinguoin to see if this data is different than a null hypothesis of 0.5 (no preference).
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# here is how to get the column\n", "experiment_one_df['Baseline_Proportion_Gaze_to_Singer']\n", "\n", "# Answer goes here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remember how the experiment went. Infants watched silent video recordings of two women (Baseline). Then each person sung a song, one was familiar to the infant (their parents sung the song to them many times), and one was unfamiliar (singing phase). After the singing phase, the infants watched the silent video of the two singers again (test phase). The critical question was whether the infants would look more to the person who sung the familiar song compared to the person who sun the unfamiliar song, which is recorded as `Test_Proportion_Gaze_to_Singer`. If the infants did this, they should look more than 50% of the time to the singer who sang the familiar song. We have the data, we can do another one sample t-test to find out." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", " The cell below shows how to get the looking time proportions from the test phase. First conduct a one sample t-test on this test data compared to a null hypothesis of 0.5. What do you find? Finally, conduct a paired t-test between the baseline and test phase using pinguoin to see if this data is different than a null hypothesis of 0.0 (no difference).\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# here is how to get the column\n", "experiment_one_df['Test_Proportion_Gaze_to_Singer']\n", "\n", "# Answer goes here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Alright. What did we find? You should take a stab at writing down what we found. You can use the same kind of language that I used from the first one sample-test. You should state the mean proportion, the t-value, the dfs, and the p-value. You should be able to answer the question, did the infants look longer at the singer who sang the familiar song? And, did they look longer than would be consist with chance at 50%.\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Answer goes here" ] } ], "metadata": { "celltoolbar": "Tags", "kernel_info": { "name": "python3" }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.9" }, "nteract": { "version": "0.15.0" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 1 }