diff --git a/Chapter_03.ipynb b/Chapter_03.ipynb
new file mode 100644
index 0000000..dd74c60
--- /dev/null
+++ b/Chapter_03.ipynb
@@ -0,0 +1,24284 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "using CSV\n",
+ "using DataFrames\n",
+ "using Plots\n",
+ "using StatsPlots\n",
+ "using GLM\n",
+ "using Statistics"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Load Advertising Data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adsData = CSV.File(\"dataset/Advertising.csv\") |> DataFrame;"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sales = adsData.sales;\n",
+ "tv = adsData.TV;"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Estimating β"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "infer_params (generic function with 1 method)"
+ ]
+ },
+ "execution_count": 25,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "function infer_params(x, y)\n",
+ " x_bar = sum(x) / length(x)\n",
+ " y_bar = sum(y) / length(y)\n",
+ " \n",
+ " xx = x .- x_bar\n",
+ " yy = y .- y_bar\n",
+ " \n",
+ " β_1 = sum(xx .* yy) / sum(xx.^2)\n",
+ " β_0 = y_bar - β_1 * x_bar\n",
+ " \n",
+ " return β_0, β_1\n",
+ "end"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(7.032593549127696, 0.047536640433019736)"
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "β_0, β_1 = infer_params(tv, sales)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2-element Array{Float64,1}:\n",
+ " 6.985056908694676\n",
+ " 21.293585679033615"
+ ]
+ },
+ "execution_count": 27,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "predict(inp, b0, b1) = begin\n",
+ " inp * b1 + b0\n",
+ "end\n",
+ "\n",
+ "line_0 = [-1, 300]\n",
+ "line_1 = [predict(-1, β_0, β_1), predict(300, β_0, β_1)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "\n"
+ ]
+ },
+ "execution_count": 28,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "scatter(tv, sales, xlabel=\"TV\", ylabel=\"Sales\", legend=false, markercolor=\"red\")\n",
+ "plot!(line_0, line_1, lw = 3, lc=\"black\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "RSS (generic function with 1 method)"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "RSS(a_0, a_1) = sum((sales .- (a_0 .+ a_1 .* tv)).^2) "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "\n"
+ ]
+ },
+ "execution_count": 23,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a_0 = range(5, stop=9, length=1000)\n",
+ "a_1 = range(0, stop=0.1, length=1000)\n",
+ "\n",
+ "p1 = contour(a_0, a_1, RSS)\n",
+ "p2 = plot(a_0, a_1, RSS, st=:surface)\n",
+ "plot(p1, p2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 61,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "([-0.22965459204536265, 0.06409744289035421, 7.167620081842205, -5.615007707946638, 1.0419105403052893, 3.2453367517185034, -1.4373952184843661, -4.221901172028013, 3.504776258577725, -1.4630225904716223 … 2.1452537704021815, 0.2580606348005993, -2.6157197910731322, 1.6527414310882453, 7.8775099611928745, 7.99044526539574, 1.1003859871568178, 4.668872437218615, -3.7523671189269816, 2.2269239604320106], [-1.0233342525298452, -0.7210246105370981, 1.7183986185294913, -1.5656950134163132, 0.13301523850683505, 0.5675941113536105, -1.2175711853342026, -1.7409409020923485, -0.028967123381389293, -1.3434669882553454 … 0.24327647304058164, -0.5805186207921258, -1.2571092729199735, -0.40703940477397094, 1.2726148132539379, 1.409872532386462, -0.5405888521821405, 0.7727358656506951, -1.9246552529739276, 0.7535014137437477])"
+ ]
+ },
+ "execution_count": 61,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "Y(X) = 2.0 .+ 3.0 .* X\n",
+ "\n",
+ "function create_sample(n)\n",
+ " X = rand(Float64, n) .* 4.0 .- 2.0\n",
+ " ϵ = randn(Float64, n)\n",
+ " return Y(X) + ϵ, X\n",
+ "end\n",
+ "\n",
+ "y, x = create_sample(100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 62,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2-element Array{Float64,1}:\n",
+ " -3.924093751684773\n",
+ " 8.292403430305832"
+ ]
+ },
+ "execution_count": 62,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "b0, b1 = infer_params(x, y)\n",
+ "line_0 = [-2, 2]\n",
+ "line_1 = [predict(-2, b0, b1), predict(2, b0, b1)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 63,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "\n"
+ ]
+ },
+ "execution_count": 63,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "p1 = scatter(x, y)\n",
+ "p1 = plot!(x, Y(x), lw=2, lc=\"red\")\n",
+ "p1 = plot!(line_0, line_1, legend=false)\n",
+ "\n",
+ "p2 = plot(x, Y(x), lw=2, lc=\"red\")\n",
+ "for i in 1:10\n",
+ " y, x = create_sample(100)\n",
+ " b0, b1 = infer_params(x, y)\n",
+ " line_0 = [-2, 2]\n",
+ " line_1 = [predict(-2, b0, b1), predict(2, b0, b1)]\n",
+ " \n",
+ " p2 = plot!(line_0, line_1)\n",
+ "end\n",
+ "\n",
+ "plot(p1, p2, legend=false)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,LinearAlgebra.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}\n",
+ "\n",
+ "sales ~ 1 + TV\n",
+ "\n",
+ "Coefficients:\n",
+ "─────────────────────────────────────────────────────────────────────────\n",
+ " Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%\n",
+ "─────────────────────────────────────────────────────────────────────────\n",
+ "(Intercept) 7.03259 0.457843 15.36 <1e-34 6.12972 7.93547\n",
+ "TV 0.0475366 0.00269061 17.67 <1e-41 0.0422307 0.0528426\n",
+ "─────────────────────────────────────────────────────────────────────────"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ols = lm(@formula(sales ~ TV), adsData)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3.3 Multiple Linear Regression"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,LinearAlgebra.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}\n",
+ "\n",
+ "sales ~ 1 + radio\n",
+ "\n",
+ "Coefficients:\n",
+ "────────────────────────────────────────────────────────────────────────\n",
+ " Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%\n",
+ "────────────────────────────────────────────────────────────────────────\n",
+ "(Intercept) 9.31164 0.5629 16.54 <1e-38 8.20159 10.4217\n",
+ "radio 0.202496 0.0204113 9.92 <1e-18 0.162244 0.242747\n",
+ "────────────────────────────────────────────────────────────────────────"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ols = lm(@formula(sales ~ radio), adsData)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,LinearAlgebra.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}\n",
+ "\n",
+ "sales ~ 1 + newspaper\n",
+ "\n",
+ "Coefficients:\n",
+ "────────────────────────────────────────────────────────────────────────────\n",
+ " Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%\n",
+ "────────────────────────────────────────────────────────────────────────────\n",
+ "(Intercept) 12.3514 0.62142 19.88 <1e-48 11.126 13.5769\n",
+ "newspaper 0.0546931 0.0165757 3.30 0.0011 0.0220055 0.0873807\n",
+ "────────────────────────────────────────────────────────────────────────────"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ols = lm(@formula(sales ~ newspaper), adsData)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,LinearAlgebra.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}\n",
+ "\n",
+ "sales ~ 1 + TV + radio + newspaper\n",
+ "\n",
+ "Coefficients:\n",
+ "────────────────────────────────────────────────────────────────────────────\n",
+ " Coef. Std. Error t Pr(>|t|) Lower 95% Upper 95%\n",
+ "────────────────────────────────────────────────────────────────────────────\n",
+ "(Intercept) 2.93889 0.311908 9.42 <1e-16 2.32376 3.55402\n",
+ "TV 0.0457646 0.0013949 32.81 <1e-80 0.0430137 0.0485156\n",
+ "radio 0.18853 0.00861123 21.89 <1e-53 0.171547 0.205513\n",
+ "newspaper -0.00103749 0.00587101 -0.18 0.8599 -0.012616 0.010541\n",
+ "────────────────────────────────────────────────────────────────────────────"
+ ]
+ },
+ "execution_count": 9,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "ols = lm(@formula(sales ~ TV + radio + newspaper), adsData)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "4×4 Array{Float64,2}:\n",
+ " 1.0 0.0548087 0.0566479 0.782224\n",
+ " 0.0548087 1.0 0.354104 0.576223\n",
+ " 0.0566479 0.354104 1.0 0.228299\n",
+ " 0.782224 0.576223 0.228299 1.0"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Table 3.5: correlation matrix\n",
+ "cor(Matrix(adsData[:, [\"TV\", \"radio\", \"newspaper\", \"sales\"]]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0.8972106381789521"
+ ]
+ },
+ "execution_count": 23,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "r2(ols)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Sec 3.3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "creditData = CSV.File(\"dataset/Credit.csv\") |> DataFrame;"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/svg+xml": [
+ "\n",
+ "