{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "![title](header.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ANOVA (Analysis Of Variance) lets us test to see if a number of samples have the same mean. It's similar to the independent 2-sample t-test, but doesn't restrict us to just 2 samples. We will look at one-way and two-way ANOVA, and by the end of this guide you should be confident in using these statistical methods in your own work." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## One Way ANOVA" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One way ANOVA can be used when we have data categorised by 1 variable - for example, take the following dataframe of the force applied to a drivers head during a crash in 3 different sizes of cars:" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Compact Large Medium\n", "0 543 600 566\n", "1 555 530 520\n", "2 502 498 580\n", "3 534 460 498\n", "4 611 478 511\n", "5 622 560 560\n" ] } ], "source": [ "import numpy as np\n", "import pandas as pd\n", "\n", "cars = pd.DataFrame({\"Compact\": [543, 555, 502, 534, 611, 622], \"Medium\": [566,520,580,498,511,560], \"Large\": [600,530,498,460,478,560]})\n", "\n", "print(cars)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A simple preliminary technique is to plot the boxplots of the different sets using matplotlib:" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n/wEs38uzkwSEuAAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "plt.boxplot([cars[\"Compact\"], cars[\"Medium\"], cars[\"Large\"]])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It certainly looks like these is some kind of downward trend as the car gets larger - but we need a way of statistically testing if the means are different. ANOVA lets us do this, and works on the assumption that every data point is picked independently from normal distributions with the same variance. Of course - each group can have a different mean (otherwise our data would all be the same), but the variance has to be equal. In ANOVA, the null hypothesis is that all the means are equal, and the alternative hypothesis is they are not." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Scipy has a really nice and easy way to do this: the f_oneway() function:" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "F_onewayResult(statistic=1.1973440463010667, pvalue=0.3292756379801583)\n" ] } ], "source": [ "import scipy.stats as stats\n", "\n", "print(stats.f_oneway(cars[\"Compact\"], cars[\"Medium\"], cars[\"Large\"]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we can see a pvalue of 0.32 gives us no evidence the means are different. If we want more detailed output, we can use the statsmodels library to get more control over what's happening. For this we need to edit our dataframe a little. The melt method for pandas lets us do this really easily:" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Type Force\n", "0 Compact 543\n", "1 Compact 555\n", "2 Compact 502\n", "3 Compact 534\n", "4 Compact 611\n", "5 Compact 622\n", "6 Large 600\n", "7 Large 530\n", "8 Large 498\n", "9 Large 460\n", "10 Large 478\n", "11 Large 560\n", "12 Medium 566\n", "13 Medium 520\n", "14 Medium 580\n", "15 Medium 498\n", "16 Medium 511\n", "17 Medium 560\n" ] } ], "source": [ "cars2 = pd.melt(cars, var_name=\"Type\", value_name=\"Force\")\n", "print(cars2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can use the statsmodels libary to build a model and then perform the analysis:" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " sum_sq df F PR(>F)\n", "C(Type) 4854.777778 2.0 1.197344 0.329276\n", "Residual 30409.666667 15.0 NaN NaN\n" ] } ], "source": [ "import statsmodels.api as sm\n", "from statsmodels.formula.api import ols\n", "\n", "#Fits the data to a model using the formula \"Force ~ C(Type)\" - since Type is categorical we need the C()\n", "model = ols('Force ~ C(Type)', data=cars2).fit() \n", " \n", "anova_table = sm.stats.anova_lm(model, typ=2) #Performs Analysis on this model\n", "print(anova_table)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we can see the test statistic (1.197) and our p-value again (0.329) as well as the sum of squares data. This method doesn't seem useful now, but will be useful when we look at the next section." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Two Way ANOVA" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Two way ANOVA is similar to one way ANOVA in that we're testing data split catagorically for equal means. However this time, our data is sorted into two different types of categories, and what we're testing for is slightly different. The assumptions here are the same as one-way ANOVA, but the groups also must be the same size. We are also testing three null hypothesis at once:\n", "\n", "* The Population Means of the first factor are equal (One-way ANOVA on the first type of category)\n", "* The Population Means of the second factor are equal (One-way ANOVA on the second type of category)\n", "* There is no interaction between the two factors." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we are looking at the length of odontoblasts (cells responsible for tooth growth) in 60 guinea pigs. As this dataset is too large to copy out, we're going to import it. You can download the datafile from the same folder this notebook is in [here](https://www.google.co.uk)" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " len supp dose\n", "0 4.2 VC 0.5\n", "1 11.5 VC 0.5\n", "2 7.3 VC 0.5\n", "3 5.8 VC 0.5\n", "4 6.4 VC 0.5\n" ] } ], "source": [ "teeth = pd.read_csv(\"ToothGrowth.csv\")\n", "print(teeth.head())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The data is split into three columns: our dependent variable - the length of odontoblasts, the form of the suppliment given (OJ is orange juice, VC is ascorbic acid), and the dose of vitamin C they were given. Statsmodels lets us perform a two-way ANOVA test using a similar method to above:" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " sum_sq df F PR(>F)\n", "C(supp) 205.350000 1.0 15.571979 2.311828e-04\n", "C(dose) 2426.434333 2.0 91.999965 4.046291e-18\n", "C(supp):C(dose) 108.319000 2.0 4.106991 2.186027e-02\n", "Residual 712.106000 54.0 NaN NaN\n" ] } ], "source": [ "import statsmodels.api as sm\n", "from statsmodels.formula.api import ols\n", " \n", "model = ols('len ~ C(supp) + C(dose) + C(supp)*C(dose)', data=teeth).fit() #Formula for Two-way ANOVA is C(1) + C(2) + C(1)*C(2)\n", " \n", "anova_table = sm.stats.anova_lm(model, typ=2) #Performs Analysis on this model\n", "print(anova_table)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first line gives us a p-value of 2.3e-04, which gives us strong evidence that the means are not equal when categorised by suppliment (i.e, orange juice gives different results than ascorbic acid).\n", "\n", "The second line gives us a p-value of 4.04e-18, which again gives us strong evidence that the means are not equal when categorised by dose (i.e, different doses give us different growths).\n", "\n", "The third line give us a p-value of 0.02186, which gives us evidence that the two categorical factors are related in some way." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Mini Project" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we have some data detailing the anger scores categorised by gender, and whether or not they are athletes. You can download the datafile from the same folder this notebook is in [here](https://www.google.co.uk). The \"AngerOut\" score is a measurement of verbally or phyiscally expressing anger." ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Gender Sports AngerOut\n", "0 female athlete 18\n", "1 female athlete 14\n", "2 female athlete 13\n", "3 female athlete 17\n", "4 male athlete 16\n" ] } ], "source": [ "angry = pd.read_csv(\"angry_moods.csv\")\n", "print(angry.head())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Can you perform analysis on the data set and conclude if:\n", "\n", "* Men and Women express their anger to a similar degree.\n", "* Athletes and Non-athletes express their anger to a similar degree.\n", "* There is any relationship between whether or not someone is an athelete, their gender, and if they express their anger phyisically or verbally." ] } ], "metadata": { "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.5.2" } }, "nbformat": 4, "nbformat_minor": 2 }