{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Lab 3-3: Analysis of Variance (ANOVA)\n", "\n", "For this example, we are interested in how different fertilizer treatments have affected plant growth (as measured by plant height).\n", "\n", "Also note, you can find a nice online tutorial on [ANOVA using python here](https://reneshbedre.github.io/blog/anova.html). ANOVA is one of the most commonly used stats tools, so many video and online resources exist. If you find an especially good one, please let me know!" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import scipy.stats as stats\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# load data file (note that we are specifying a separator other than the default comma in read_csv, the symbol for \"tab\" is \"\\t\")\n", "df = pd.read_csv(\"../data/ANOVA_fertilizer_treatment.txt\", sep=\"\\t\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we look at the dataframe we just loaded, we can see that we have one control group (no fertilizer) and three different fertilizer treatments." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ControlF1F2F3
021.032.022.528.0
119.530.526.027.5
222.525.028.031.0
321.527.527.029.5
420.528.026.530.0
521.028.625.229.2
\n", "
" ], "text/plain": [ " Control F1 F2 F3\n", "0 21.0 32.0 22.5 28.0\n", "1 19.5 30.5 26.0 27.5\n", "2 22.5 25.0 28.0 31.0\n", "3 21.5 27.5 27.0 29.5\n", "4 20.5 28.0 26.5 30.0\n", "5 21.0 28.6 25.2 29.2" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can make a boxplot to visualize our data and their distributions." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# Using boxplot, we can start to visually see differences between the treatment groups\n", "df.boxplot(column=['Control', 'F1', 'F2', 'F3'], grid=False)\n", "\n", "# Add labels\n", "plt.xlabel('Fertilizer Treatment')\n", "plt.ylabel('plant height (cm)')\n", "plt.title('Plant Height Measurements\\nFor Each Treatment Group');" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**State our null and alternative hypothesis:**\n", "\n", "$H_0$: All groups have the same central mean\n", "\n", "$H_1$: The means are different from each other\n", "\n", "We want 95% confidence, so choose $\\alpha = 0.05$\n", "\n", "In this case, we perform a one-way (also called one-factor) ANOVA to determine whether our null hypothesis ($H_0$) is true or not. We can use the [scipy.stats.f_oneway()](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.f_oneway.html) function for this. This function will return the F-statistic, and a p-value. **We can reject the null hypothesis if $p < \\alpha$**" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "F-statistic = 27.46\n", "p = 2.711994408537598e-07\n" ] } ], "source": [ "# stats f_oneway functions takes the groups as input and returns an F and P-value\n", "fvalue, pvalue = stats.f_oneway(df['Control'], df['F1'], df['F2'], df['F3'])\n", "\n", "# print the results\n", "print(\"F-statistic = {}\".format( np.round(fvalue,2)))\n", "print(\"p = {}\".format( pvalue ))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Our p-value is smaller than our chosen $\\alpha$, so in this case we can reject the null hypothesis." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "Take a look at the lecture notes to recall how the F-statistic is calculated.\n", "\n", "The p-value for this test is determined by looking up that F-statistic in the [F-distribution](https://en.wikipedia.org/wiki/F-distribution). The p-value is this example much less than 0.05, so we can reject the null. However, if we want to know more, such as which of the groups are actually different from which other groups, we need more information." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "We are going to use functions from the [statsmodels](https://www.statsmodels.org/stable/index.html) python package for the examples below." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import statsmodels.api as sm\n", "from statsmodels.formula.api import ols" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following code will produce an ANOVA table with our results using the [statsmodels.stats.anova.anova_lm()](https://www.statsmodels.org/dev/generated/statsmodels.stats.anova.anova_lm.html) function." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sum_sqdfFPR(>F)
C(treatments)251.4400003.027.4647732.711994e-07
Residual61.03333320.0NaNNaN
\n", "
" ], "text/plain": [ " sum_sq df F PR(>F)\n", "C(treatments) 251.440000 3.0 27.464773 2.711994e-07\n", "Residual 61.033333 20.0 NaN NaN" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# reshape the d dataframe suitable for statsmodels package \n", "df_reshaped = pd.melt(df.reset_index(), id_vars=['index'], value_vars=['Control', 'F1', 'F2', 'F3'])\n", "\n", "# replace column names\n", "df_reshaped.columns = ['index', 'treatments', 'value']\n", "\n", "# Ordinary Least Squares (OLS) model\n", "model = ols('value ~ C(treatments)', data=df_reshaped).fit()\n", "anova_table = sm.stats.anova_lm(model, typ=2)\n", "\n", "# display the results table\n", "anova_table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compare the above to the table we made in class. Both of these python packages are valid ways to solve the basic problem." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "\n", "However, we need to apply Tukey's test to tell which groups are different from which other groups. [Read the documentation for the pairwise_tukeyhsd function here](https://www.statsmodels.org/stable/generated/statsmodels.stats.multicomp.pairwise_tukeyhsd.html)." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from statsmodels.stats.multicomp import pairwise_tukeyhsd" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " Multiple Comparison of Means - Tukey HSD, FWER=0.05 \n", "=====================================================\n", " group1 group2 meandiff p-adj lower upper reject\n", "-----------------------------------------------------\n", "Control F1 7.6 0.0 4.7771 10.4229 True\n", "Control F2 4.8667 0.0006 2.0437 7.6896 True\n", "Control F3 8.2 0.0 5.3771 11.0229 True\n", " F1 F2 -2.7333 0.0599 -5.5563 0.0896 False\n", " F1 F3 0.6 0.9324 -2.2229 3.4229 False\n", " F2 F3 3.3333 0.0171 0.5104 6.1563 True\n", "-----------------------------------------------------\n" ] } ], "source": [ "# perform multiple pairwise comparison (Tukey HSD)\n", "m_comp = pairwise_tukeyhsd(endog=df_reshaped['value'], groups=df_reshaped['treatments'], alpha=0.05)\n", "\n", "# display the results table\n", "print(m_comp)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The \"reject\" column in this table shows us that all of the fertilizer treatments are different from the control (reject=True, we can reject the null hypothesis), and that treatments F2 and F3 are different from each (reject=True) other but not from F1 (reject=False).\n", "\n", "Look at the boxplot graph above again. The boxplots shows the interquartile ranges and plus and minus 1.5 times the interquartile range -- these are related to the 95% confidence range but do not show it exactly. Note that the lower and upper ranges shown in the Tukey table above suggest a real difference if the 95% confidence range does not include 0. (If it includes 0, then there's a greater than 5% chance that there's really no difference at all.)\n", "\n", "This is the extent of what you need to complete the homework problem. I encourage you to read the details about each of these functions, review the lecture notes, or other resources you can find online. Chapter 7 of the [USGS book](https://pubs.usgs.gov/tm/04/a03/tm4a3.pdf) covers in much more detail one-factor ANOVA as well as several more tests for comparing multiple groups of samples." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.10.13" } }, "nbformat": 4, "nbformat_minor": 4 }