328 lines
10 KiB
Plaintext
328 lines
10 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "0ba6d314",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Imports\n",
|
|
"\n",
|
|
"from IPython.display import display, Markdown\n",
|
|
"from scipy.stats import chi2_contingency\n",
|
|
"from scipy.stats import t as t_test\n",
|
|
"import numpy as np\n",
|
|
"import math\n",
|
|
"t_value = t_test.isf\n",
|
|
"\n",
|
|
"def _display_table(data_array, row_names=None, col_names=None):\n",
|
|
" _row_num = len(data_array)\n",
|
|
" _col_num = len(data_array[0])\n",
|
|
" _rows = []\n",
|
|
" for i in range(_row_num):\n",
|
|
" row = f'| {row_names[i]} |'\n",
|
|
" for j in range(_col_num):\n",
|
|
" row += f' {data_array[i][j]:.1f} |'\n",
|
|
" row += f' {sum(data_array[i]):.0f} |'\n",
|
|
" _rows.append(row)\n",
|
|
" _total_row = '| **Total** |'\n",
|
|
" _col_tots = 0\n",
|
|
" for i in range(_col_num):\n",
|
|
" col_tot = 0\n",
|
|
" for j in range(_row_num):\n",
|
|
" col_tot += data_array[j][i]\n",
|
|
" _col_tots += col_tot\n",
|
|
" _total_row += f' **{col_tot:.0f}** |'\n",
|
|
" _total_row += f' **{_col_tots:.0f}** |'\n",
|
|
" display(Markdown(\n",
|
|
" rf\"\"\"\n",
|
|
"| | {' | '.join(col_names + ['Total'])} |\n",
|
|
"{'|-'*(len(row_names) + 2)} |\n",
|
|
"{'\\n'.join(_rows)}\n",
|
|
"{_total_row}\n",
|
|
"\"\"\"\n",
|
|
"))\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "e0a72880",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Uparret t-test\n",
|
|
"\n",
|
|
"$$\n",
|
|
"SD_{fælles} = \\sqrt{\\frac{(n_1-1)\\cdot SD_1^2 + (n_2-1)\\cdot SD_2^2}{n_1 + n_2 - 2}}\n",
|
|
"$$\n",
|
|
"\n",
|
|
"$$\n",
|
|
"se(\\bar{x}_1 - \\bar{x}_2) = \\sqrt{\\frac{1}{n_1} + \\frac{1}{n_2}} \\cdot SD_{fælles}\n",
|
|
"$$\n",
|
|
"\n",
|
|
"$$\n",
|
|
"t(x) = \\frac{\\bar{x}_1 - \\bar{x}_2}{se(\\bar{x}_1 - {\\bar{x}_2})}\n",
|
|
"$$\n",
|
|
"\n",
|
|
"$$\n",
|
|
"df = n_1 + n_2 - 2\n",
|
|
"$$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 28,
|
|
"id": "7e734740",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/markdown": [
|
|
"\n",
|
|
"Middeldifference: $\\bar{x} = \\bar{x}_1 - \\bar{x}_2 = 1.44 - 1.26 = 0.180$\n",
|
|
"\n",
|
|
"$H_0: \\mu_1 = \\mu_2 \\Rightarrow \\mu_1 - \\mu_2 = 0$\n",
|
|
"\n",
|
|
"Test: uparret t-test med $df = 36 + 36 - 2 = $**70 frihedsgrader**\n",
|
|
"\n",
|
|
"$SD_{fælles} = \\sqrt{ \\frac{ (n_1 - 1)\\cdot SD_1^2 + (n_2-1) \\cdot SD_2^2 }{ n_1 + n_2 - 2 } } = \\sqrt{ \\frac{ (36 - 1)\\cdot 0.25^2 + (36-1) \\cdot 0.32^2 }{ 36 + 36 - 2 } } = 0.2871$\n",
|
|
"\n",
|
|
"$se(\\bar{x_1} - \\bar{x_2}) = \\sqrt{\\frac{1}{n_1} + \\frac{1}{n_2}} \\cdot SD_{fælles} = \\sqrt{\\frac{1}{36} + \\frac{1}{36}} \\cdot 0.2871 = 0.0677$\n",
|
|
"\n",
|
|
"$t(x) = \\frac{\\bar{x_1} - \\bar{x_2}}{se(\\bar{x_1} - \\bar{x_2})} = \\frac{1.44 - 1.26}{0.0677} =$ **2.6596**\n",
|
|
"\n",
|
|
"p-værdi for $|t(x)|$ ved 70 frihedsgrader: **0.0097** $\\lt 0.05$ (fundet ved brug af Python-biblioteket `scipy.stats.t`)\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Markdown object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/markdown": [
|
|
"\n",
|
|
"Da $p$ $\\lt 0.05$, kan nulhypotesen $H_0: \\mu_1 - \\mu_2 = 0$ forkastes. Der er altså statistisk signifikant forskel mellem middelværdierne.\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Markdown object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"middel1 = 1.44\n",
|
|
"n1 = 36\n",
|
|
"sd1 = 0.25\n",
|
|
"\n",
|
|
"middel2 = 1.26\n",
|
|
"n2 = 36\n",
|
|
"sd2 = 0.32\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"###############################\n",
|
|
"dof = n1 + n2 - 2\n",
|
|
"sd_fælles = math.sqrt(((n1-1)*sd1**2 + (n2-1)*sd2**2) / (n1 + n2 - 2))\n",
|
|
"se_fælles = math.sqrt(1/n1 + 1/n2) * sd_fælles\n",
|
|
"t_x = (np.abs(middel1 - middel2))/(se_fælles)\n",
|
|
"p_threshold = 0.05\n",
|
|
"p_værdi = (1 - t_test.cdf(t_x, dof))*2\n",
|
|
"match p_værdi:\n",
|
|
" case p_værdi if p_værdi >= p_threshold:\n",
|
|
" p_text = f'$\\ge {p_threshold}$'\n",
|
|
" case p_værdi if p_værdi < p_threshold/100:\n",
|
|
" p_text = f'$\\ll {p_threshold}$'\n",
|
|
" case _:\n",
|
|
" p_text = f'$\\lt {p_threshold}$'\n",
|
|
"\n",
|
|
"display(Markdown(\n",
|
|
" rf\"\"\"\n",
|
|
"Middeldifference: $\\bar{{x}} = \\bar{{x}}_1 - \\bar{{x}}_2 = {middel1} - {middel2} = {middel1 - middel2:.3f}$\n",
|
|
"\n",
|
|
"$H_0: \\mu_1 = \\mu_2 \\Rightarrow \\mu_1 - \\mu_2 = 0$\n",
|
|
"\n",
|
|
"Test: uparret t-test med $df = {n1} + {n2} - 2 = $**{dof} frihedsgrader**\n",
|
|
"\n",
|
|
"$SD_{{fælles}} = \\sqrt{{ \\frac{{ (n_1 - 1)\\cdot SD_1^2 + (n_2-1) \\cdot SD_2^2 }}{{ n_1 + n_2 - 2 }} }} = \\sqrt{{ \\frac{{ ({n1} - 1)\\cdot {sd1}^2 + ({n2}-1) \\cdot {sd2}^2 }}{{ {n1} + {n2} - 2 }} }} = {sd_fælles:.4f}$\n",
|
|
"\n",
|
|
"$se(\\bar{{x_1}} - \\bar{{x_2}}) = \\sqrt{{\\frac{{1}}{{n_1}} + \\frac{{1}}{{n_2}}}} \\cdot SD_{{fælles}} = \\sqrt{{\\frac{{1}}{{{n1}}} + \\frac{{1}}{{{n2}}}}} \\cdot {sd_fælles:.4f} = {se_fælles:.4f}$\n",
|
|
"\n",
|
|
"$t(x) = \\frac{{\\bar{{x_1}} - \\bar{{x_2}}}}{{se(\\bar{{x_1}} - \\bar{{x_2}})}} = \\frac{{{middel1} - {middel2}}}{{{se_fælles:.4f}}} =$ **{t_x:.4f}**\n",
|
|
"\n",
|
|
"p-værdi for $|t(x)|$ ved {dof} frihedsgrader: **{p_værdi:.4f}** {p_text} (fundet ved brug af Python-biblioteket `scipy.stats.t`)\n",
|
|
"\"\"\"\n",
|
|
"))\n",
|
|
"\n",
|
|
"if p_værdi < p_threshold:\n",
|
|
" display(Markdown(\n",
|
|
" rf\"\"\"\n",
|
|
"Da $p$ {p_text}, kan nulhypotesen $H_0: \\mu_1 - \\mu_2 = 0$ forkastes. Der er altså statistisk signifikant forskel mellem middelværdierne.\n",
|
|
"\"\"\"\n",
|
|
" ))\n",
|
|
"else:\n",
|
|
" display(Markdown(\n",
|
|
" rf\"\"\"\n",
|
|
"Da $p$ {p_text}, kan nulhypotesen $H_0: \\mu_1 - \\mu_2 = 0$ ikke forkastes. Der kan altså ikke siges at være statistisk signifikant forskel mellem middelværdierne.\n",
|
|
"\"\"\"\n",
|
|
" ))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "2ad5beff",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Konfidensintervallet for forskellen på middelværdierne\n",
|
|
"\n",
|
|
"$$\n",
|
|
"95\\% CI(\\mu_1 - \\mu_2) = \\bar{x}_1 - \\bar{x}_2 \\pm t' \\cdot se(\\bar{x}_1 - \\bar{x}_2)\n",
|
|
"$$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 67,
|
|
"id": "c4d47453",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"middel1 = 21.9\n",
|
|
"n1 = 150\n",
|
|
"sd1 = 1.7\n",
|
|
"\n",
|
|
"middel2 = 21.6\n",
|
|
"n2 = 300\n",
|
|
"sd2 = 1.8\n",
|
|
"\n",
|
|
"dof = n1 + n2 - 2\n",
|
|
"sd_fælles = math.sqrt(((n1-1)*sd1**2 + (n2-1)*sd2**2) / (n1 + n2 - 2))\n",
|
|
"se_fælles = math.sqrt(1/n1 + 1/n2) * sd_fælles"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"id": "bdc8cd82",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/markdown": [
|
|
"\n",
|
|
"$\\bar{x}_1 = 1.44$\n",
|
|
"\n",
|
|
"$\\bar{x}_2 = 1.26$\n",
|
|
"\n",
|
|
"Eksakt formel:\n",
|
|
"\n",
|
|
"$SD_{fælles} = \\sqrt{ \\frac{ (n_1 - 1)\\cdot SD_1^2 + (n_2-1) \\cdot SD_2^2 }{ n_1 + n_2 - 2 } } = \\sqrt{ \\frac{ (36 - 1)\\cdot 0.25^2 + (36-1) \\cdot 0.32^2 }{ 36 + 36 - 2 } } = 0.2871$\n",
|
|
"\n",
|
|
"$se(\\bar{x_1} - \\bar{x_2}) = \\sqrt{\\frac{1}{n_1} + \\frac{1}{n_2}} \\cdot SD_{fælles} = \\sqrt{\\frac{1}{36} + \\frac{1}{36}} \\cdot 0.2871 = 0.0677$\n",
|
|
"\n",
|
|
"$95\\% CI(\\mu_1 - \\mu_2) = \\bar{x}_1 - \\bar{x}_2 \\pm t' \\cdot se(\\bar{x}_1 - \\bar{x}_2)$\n",
|
|
"\n",
|
|
"$= 1.44 - 1.26 \\pm 1.994 \\cdot 0.068$\n",
|
|
"\n",
|
|
"$= 0.180 \\pm 0.135 = \\left[0.045\\ ;\\ 0.315\\right]$\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Markdown object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/markdown": [
|
|
"\n",
|
|
"Da $0$ ikke er inkluderet i $95\\%CI$, kan der siges at være signifikant forskel på middelværdierne.\n"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.Markdown object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"####################################\n",
|
|
"t_værdi = t_value(0.025, dof)\n",
|
|
"t_se = t_værdi * se_fælles\n",
|
|
"middel_dif = middel1 - middel2\n",
|
|
"interval_lav = middel_dif - t_se\n",
|
|
"interval_høj = middel_dif + t_se\n",
|
|
"\n",
|
|
"display(Markdown(\n",
|
|
" rf\"\"\"\n",
|
|
"$\\bar{{x}}_1 = {middel1}$\n",
|
|
"\n",
|
|
"$\\bar{{x}}_2 = {middel2}$\n",
|
|
"\n",
|
|
"Eksakt formel:\n",
|
|
"\n",
|
|
"$SD_{{fælles}} = \\sqrt{{ \\frac{{ (n_1 - 1)\\cdot SD_1^2 + (n_2-1) \\cdot SD_2^2 }}{{ n_1 + n_2 - 2 }} }} = \\sqrt{{ \\frac{{ ({n1} - 1)\\cdot {sd1}^2 + ({n2}-1) \\cdot {sd2}^2 }}{{ {n1} + {n2} - 2 }} }} = {sd_fælles:.4f}$\n",
|
|
"\n",
|
|
"$se(\\bar{{x_1}} - \\bar{{x_2}}) = \\sqrt{{\\frac{{1}}{{n_1}} + \\frac{{1}}{{n_2}}}} \\cdot SD_{{fælles}} = \\sqrt{{\\frac{{1}}{{{n1}}} + \\frac{{1}}{{{n2}}}}} \\cdot {sd_fælles:.4f} = {se_fælles:.4f}$\n",
|
|
"\n",
|
|
"$95\\% CI(\\mu_1 - \\mu_2) = \\bar{{x}}_1 - \\bar{{x}}_2 \\pm t' \\cdot se(\\bar{{x}}_1 - \\bar{{x}}_2)$\n",
|
|
"\n",
|
|
"$= {middel1} - {middel2} \\pm {t_værdi:.3f} \\cdot {se_fælles:.3f}$\n",
|
|
"\n",
|
|
"$= {middel_dif:.3f} \\pm {t_se:.3f} = \\left[{middel_dif - t_se:.3f}\\ ;\\ {middel_dif + t_se:.3f}\\right]$\n",
|
|
"\"\"\"\n",
|
|
"))\n",
|
|
"\n",
|
|
"if np.sign(interval_lav) != np.sign(interval_høj):\n",
|
|
" display(Markdown(\n",
|
|
" rf\"\"\"\n",
|
|
"Da $0$ er inkluderet i $95\\%CI$, kan der ikke siges at være signifikant forskel på middelværdierne.\n",
|
|
"\"\"\"\n",
|
|
" ))\n",
|
|
"else:\n",
|
|
" display(Markdown(\n",
|
|
" rf\"\"\"\n",
|
|
"Da $0$ ikke er inkluderet i $95\\%CI$, kan der siges at være signifikant forskel på middelværdierne.\n",
|
|
"\"\"\"\n",
|
|
" ))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "984d104a",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "base",
|
|
"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.13.9"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|