---
title: "Simple Linear Regression"
subtitle: "FMB819: R을 이용한 데이터분석"
author: "고려대학교 경영대학 정지웅"
format: 
  revealjs:
    theme: simple
    transition: fade
    transition-speed: fast
    scrollable: true
    chalkboard: true
    slide-number: true
revealjs-plugins:
  - revealjs-text-resizer # Thanks to https://github.com/gadenbuie/revealjs-text-resizer#readme
---

```{r setup, include=FALSE,warning=FALSE,message=FALSE}
options(htmltools.dir.version = FALSE)
knitr::opts_chunk$set(
  message = FALSE,
  warning = FALSE,
  dev = "svg",
  cache = TRUE,
  fig.align = "center",
  comment = "##"
  #fig.width = 11,
  #fig.height = 5
)

library("tidyverse")
# library("repmis")

if (requireNamespace("kableExtra", quietly = TRUE)) {
  library("kableExtra")
}

if (requireNamespace("countdown", quietly = TRUE)) {
  library(countdown)
  # countdown style
  countdown(
    color_border              = "#d90502",
    color_text                = "black",
    color_running_background  = "#d90502",
    color_running_text        = "white",
    color_finished_background = "white",
    color_finished_text       = "#d90502",
    color_finished_border     = "#d90502"
  )
} else {
  countdown <- function(minutes = 0, top = 0, ...) {
    paste0("[Timer: ", minutes, " min]")
  }
}
```

## Today's Agenda

-   ***단순 선형 회귀 모형(Simple Linear Regression Model)*** 및 ***최소제곱법(Ordinary Least Squares, OLS)*** *추정* 소개.

-   실증 분석: 코스피200 지수와 S&P500 지수의 관계

------------------------------------------------------------------------

## 코스피200 지수와 S&P500 지수

-   "S&P500이 움직일 때 코스피200이 얼마나 같이 움직이는가?"

-   이번 예시에서는 웹에서 코스피200/ S&P500 일별 종가를 불러와 수익률을 계산함.

-   실습에서는 두 관계를 함께 봄:

    1)  **당일 관계**: $r^{KOSPI200}_t$ vs $r^{SP500}_t$
    2)  **익일 관계**: $r^{KOSPI200}_{t+1}$ vs $r^{SP500}_t$

------------------------------------------------------------------------

## Task 1 {background-color="#ffebf0"}

`r countdown(minutes = 7, top = "20px", right = "10px", font_size = "0.8em")`

1.  코스피200 및 S&P500 일별 종가 데이터를 불러와 날짜를 기준으로 두 지수를 병합한 뒤, `merged_px` 객체를 생성하시오. 그리고 일별 수익률 변수(`ret_sp500`, `ret_kospi200`, `ret_kospi200_lead`)를 생성하시오. (`inner_join`)

``` r
sp500_px <- read_csv("https://raw.githubusercontent.com/chung-jiwoong/FMB819/refs/heads/main/chapter_slr/data/%5Espx_d.csv")

ks200_px <- read_csv("https://raw.githubusercontent.com/chung-jiwoong/FMB819/refs/heads/main/chapter_slr/data/%5Ekospi_d.csv") 
```

```{r, echo=FALSE, eval=TRUE}
library(dplyr)
library(tidyverse)

sp500_px <- read_csv("https://raw.githubusercontent.com/chung-jiwoong/FMB819/refs/heads/main/chapter_slr/data/%5Espx_d.csv") |>
  transmute(date = as.Date(Date), sp500_close = as.numeric(Close)) |> 
  arrange(date)

ks200_px <- read_csv("https://raw.githubusercontent.com/chung-jiwoong/FMB819/refs/heads/main/chapter_slr/data/%5Ekospi_d.csv") |>
  transmute(date = as.Date(Date), kospi200_close = as.numeric(Close)) |> 
  arrange(date)

merged_px <- inner_join(sp500_px, ks200_px, by = "date") |> 
  mutate(
    ret_sp500 =  10000 * (log(sp500_close) - log(lag(sp500_close))),
    ret_kospi200 =  10000 * (log(kospi200_close) - log(lag(kospi200_close)))
  ) |> 
  mutate(ret_kospi200_lead = lead(ret_kospi200)) |> 
  drop_na()
```

2.  데이터셋 설명:

    -   총 몇 개의 관측치가 있는가?\

    -   데이터셋을 확인하고 어떤 변수가 있는지 확인하시오.

    -   `skimr` 패키지의 `skim` 함수 사용해서 생성한 수익률 변수에 대한 기본적인 요약 통계 확인.\

        **힌트**: `dplyr`의 `select` 사용해서 변수 선택한 후 `%>%`로 `skim()` 적용하면 됨.

```{r, echo=FALSE, eval=FALSE}
if (!requireNamespace("skimr")) {install.packages("skimr")}
library(skimr)
returns_raw <- merged_px %>% select(date, ret_sp500, ret_kospi200, ret_kospi200_lead)
skim(returns_raw)
```

3.  S&P500 수익률(`ret_sp500`)과 코스피200 수익률(`ret_kospi200`, `ret_kospi200_lead`)의 상관관계는?

```{r, echo=FALSE, eval=FALSE}
cor(returns_raw$ret_sp500, returns_raw$ret_kospi200)
cor(returns_raw$ret_sp500, returns_raw$ret_kospi200_lead)
```

------------------------------------------------------------------------

## 코스피200 지수와 S&P500 지수: Scatter plot

::::: columns
::: {.column width="50%"}
```{r, echo=FALSE, fig.height=6}
returns_raw <- merged_px %>% select(date, ret_sp500, ret_kospi200, ret_kospi200_lead)

g_sameday = ggplot(returns_raw, aes(x = ret_sp500, y = ret_kospi200)) + 
    geom_point(size = 2, alpha = 0.5) +
    labs(
      x = "S&P500 return",
      y = "Return",
      title = "KOSPI200 (same day)") +
    theme_bw(base_size = 20)
g_sameday
```
:::

::: {.column width="50%"}
```{r, echo=FALSE,fig.height=6}
g_lead = ggplot(returns_raw, aes(x = ret_sp500, y = ret_kospi200_lead)) + 
    geom_point(size = 2, alpha = 0.5) +
    labs(x = "S&P500 return",
         y = "Return",
         title = "KOSPI200 (next day)") +
    theme_bw(base_size = 20)
g_lead
```
:::
:::::

-   S&P500 수익률을 구간(bin)으로 묶어 평균 관계를 더 명확하게 살펴보자.

------------------------------------------------------------------------

## 코스피200 지수와 S&P500 지수: Binned Scatter Plot

::::: columns
::: {.column width="50%"}
```{r, echo=FALSE, fig.height=6}
library(dplyr)
# Create bins for S&P500 (10bp intervals)
returns_raw <- returns_raw |>
  mutate(ret_sp500_bin = round(ret_sp500 / 10) * 10)

# Compute average returns by S&P500 return bins
returns_bin <- returns_raw |>
  group_by(ret_sp500_bin) |>
  summarise(ret_kospi200_mean = mean(ret_kospi200),
            ret_kospi200_lead_mean = mean(ret_kospi200_lead),
            .groups = "drop") 

g_sameday_bin = ggplot(returns_bin, aes(x = ret_sp500_bin, y = ret_kospi200_mean)) + 
    geom_point(size = 2) +
    labs(
      x = "S&P500 return bin",
      y = "Average return",
      title = "KOSPI200 (same day)") +
    theme_bw(base_size = 20)
g_sameday_bin
```
:::

::: {.column width="50%"}
```{r, echo=FALSE,fig.height=6}
g_lead_bin = ggplot(returns_bin, aes(x = ret_sp500_bin, y = ret_kospi200_lead_mean)) + 
    geom_point(size = 2) +
    labs(
      x = "S&P500 return bin",
      y = "Average return",
      title = "KOSPI200 (next day)") +
    theme_bw(base_size = 20)
g_lead_bin
```
:::
:::::

------------------------------------------------------------------------

## 코스피200 지수와 S&P500 지수: Regression Line

코스피200 지수와 S&P500 지수의 관계를 시각적으로 요약하는 방법: **산점도를 통과하는 선(Line)**

::::: columns
::: {.column width="50%"}
```{r, echo=FALSE, fig.align='left', fig.height=4, fig.width=7}
g_sameday_bin +
    theme_bw(base_size = 14) +
    geom_hline(yintercept = 0, col = "#d90502")
```
:::

::: {.column width="50%"}
```{r,echo=FALSE, fig.align='left', fig.height=4,fig.width=7}
g_sameday_bin +
  theme_bw(base_size = 14) +
  geom_abline(intercept = -10, slope = 0.8, col = "#d90502")
```
:::
:::::

-   어느 선이 더 나은가? 어떤 기준으로 더 나은가?

------------------------------------------------------------------------

## 단순 선형 회귀 (Simple Linear Regression)

지금까지 분석을 정리하자면

-   두 변수 간의 관계에 관심 있음:

    -   결과변수 (종속변수, dependent variable): *KOSPI200 return* $(y)$

    -   설명변수 (독립변수, independent variable): *S&P500 return* $(x)$

-   각 거래일 $i$에 대해 $x_i$와 $y_i$를 관측할 수 있음. 예, S&P500 수익률과 코스피200 수익률의 *결합 분포(joint distribution)*를 관찰.

-   회귀선은 이 관계를 **선(line)** 하나로 요약하고 있음. 절편 $b_0$와 기울기 $b_1$을 갖는 선의 방정식은 다음과 같음: $$
    \widehat{y}_i = b_0 + b_1 x_i
    $$

-   $\widehat{y}_i$는 *관측값* $i$에서의 예측값(prediction)을 의미함. 즉, 주어진 회귀 직선에 따라 우리가 $y_i$를 어떻게 예측하는지 보여줌.

------------------------------------------------------------------------

## 직선의 방정식

```{r, echo = F, fig.width = 10, fig.height = 5}
b_0 = 32
b_1 = 4.1
space = .5

base_plot <- ggplot() +
    geom_abline(slope = b_1, intercept = b_0) +
    scale_x_continuous(limits = c(-5,10), expand = c(0,0)) +
    scale_y_continuous(limits = c(0,100), expand = c(0,0)) +
    theme_bw(base_size = 16) +
    annotate(geom = "text", x = -4.3, y = 94, label = "y", parse = TRUE, size = 8, hjust = 0) +
    annotate(geom = "text", x = -4.3 + space, y = 94, label = "=", size = 8, hjust = 0) +
    annotate(geom = "text", x = -4.3 + 2*space, y = 94, label = "b[0]", color = "#DE9854", parse = TRUE, size = 8, hjust = 0) +
    annotate(geom = "text", x = -4.3 + 2*space + .6, y = 94, label = "+", size = 8, hjust = 0) +
    annotate(geom = "text", x = -4.3 + 3*space + .6, y = 94, label = "b[1]", parse = TRUE, color = "#d90502", size = 8, hjust = 0) +
    annotate(geom = "text", x = -4.3 + 4*space + .6, y = 94, label = "x", parse = TRUE, size = 8, hjust = 0)
base_plot
```

------------------------------------------------------------------------

## 직선의 방정식

```{r, echo = F, fig.width = 10, fig.height = 5}
plot_b_0 <- base_plot + 
    annotate(geom = "segment", x = 0, xend = 0, y = 0, yend = b_0, arrow = arrow(angle = 12, type = "closed"), color = "#DE9854") +
    annotate(geom = "segment", x = -5, xend = 0, y = b_0, yend = b_0, arrow = arrow(angle = 12, type = "closed", ends = "first"), color = "#DE9854") +
    scale_y_continuous(limits = c(0,100), expand = c(0,0), breaks = c(0,25,b_0,50,75,100), labels = c("0","25","b0","50","75","100"), minor_breaks = seq(0,100,12.5)) +
    theme(axis.text.y = element_text(color = c("grey30", "grey30", "#DE9854", "grey30", "grey30", "grey30")),
          axis.ticks.y = element_line(color = c("grey30", "grey30", "#DE9854", "grey30", "grey30", "grey30")),
          panel.grid.minor = element_line(color = c("grey92", "grey92", "grey92", "grey92", "grey92", "grey92")),
          panel.grid.major.y = element_line(color = c("grey92", "grey92", NA, "grey92", "grey92", "grey92")))
plot_b_0
```

------------------------------------------------------------------------

## 직선의 방정식

```{r, echo = F, fig.width = 10, fig.height = 5}
plot_b_0 + 
    annotate(geom = "segment", x = 5, xend = 6, y = b_0+5*b_1, yend = b_0+5*b_1, arrow = arrow(angle = 12, type = "closed", length = unit(.4, "cm")), color = "#d90502") +
    annotate(geom = "text", x = 5.5, y = 49, label = "1", size = 5, color = "#d90502") +
    annotate(geom = "segment", x = 6, xend = 6, y = b_0+5*b_1, yend = b_0+6*b_1, arrow = arrow(angle = 12, type = "closed", length = unit(.2, "cm")), color = "#d90502") +
    annotate(geom = "text", x = 6.5, y = (b_0+6*b_1 + b_0+5*b_1)/2, label = "b[1]", parse = TRUE, size = 6, color = "#d90502")
```

------------------------------------------------------------------------

## Simple Linear Regression: 잔차(Residual)

-   만약 모든 데이터가 직선 위에 있다면, $\widehat{y}_i = y_i$.

```{r, echo = FALSE, fig.height = 4,fig.width=7}
x <- runif(50, min  = 0, max = 1)
y <- 1 * x

data <- data.frame(y = y,
                   x = x)

plot_ex <- data %>% ggplot(aes(x = x, y = y)) +
  geom_point() +
  xlim(0, 1) +
  ylim(0, 1) +
  labs(x = "x",
       y = "y") +
  theme_bw(base_size = 14)
plot_ex
```

------------------------------------------------------------------------

## Simple Linear Regression: 잔차(Residual)

-   만약 모든 데이터가 직선 위에 있다면, $\widehat{y}_i = y_i$.

```{r, echo = FALSE, fig.height = 4,fig.width=7}
plot_ex + geom_line(color = "#d90502")
```

------------------------------------------------------------------------

## Simple Linear Regression: 잔차(Residual)

-   만약 모든 데이터가 직선 위에 있다면, $\widehat{y}_i = y_i$.

-   대부분의 경우 *종속변수* $(y)$는 우리가 선택한 *독립변수* $(x)$들에 의해서만 완벽히 설명되지 않음, $\widehat{y}_i \neq y_i$. 실제 값과 예측 값의 차이를 잔차(residual)라 부름. 즉 $y_i - \widehat y_i = e_i$

-   **실제 데이터** $(x_i, y_i)$는 따라서 **예측값 + 잔차**로 표현될 수 있음.

    $$
    y_i = \widehat y_i + e_i = b_0 + b_1 x_i + e_i
    $$

------------------------------------------------------------------------

## Simple Linear Regression: Graphically 1

```{r slr1, echo = FALSE, fig.width = 10, fig.height = 5}
focus_x <- returns_bin$ret_sp500_bin[which.min(abs(returns_bin$ret_sp500_bin - 600))]  # 600에 가장 가까운 ret_sp500_bin 값 선택

plot_1 <- g_sameday_bin +
  theme_bw(base_size = 14)

plot_1
```

------------------------------------------------------------------------

## Simple Linear Regression: Graphically 2

```{r, echo = F, fig.width = 10, fig.height = 5}
plot_2 <- g_sameday_bin +
  theme_bw(base_size = 14) +
  stat_smooth(data = returns_bin, method = "lm", se = FALSE, colour = "#d90502") +
  annotate("text", x = -260, y = 230, label = "hat(y)", parse = TRUE, colour = "#d90502", size = 6)
plot_2
```

------------------------------------------------------------------------

## Simple Linear Regression: Graphically 3

```{r, echo = F, fig.width = 10, fig.height = 5}
kospi_sp500_reg <- lm(ret_kospi200_mean ~ ret_sp500_bin, data = returns_bin)
kospi_sp500_reg <- broom::augment(kospi_sp500_reg)  # 회귀 결과에 예측값과 잔차 추가

g_sameday_bin +
  theme_bw(base_size = 14) +
  stat_smooth(method = "lm", se = FALSE, colour = "#d90502") +
  annotate("text", x = -260, y = 230, label = "hat(y)", parse = TRUE, colour = "#d90502", size = 6) +
  geom_segment(data = kospi_sp500_reg,
               aes(xend = ret_sp500_bin, yend = .fitted), color = "#d90502", size = 0.5)
```

------------------------------------------------------------------------

## Simple Linear Regression: Graphically 4

```{r, echo = F, out.width = "100%", fig.height = 5}
g_sameday_bin +
    theme_bw(base_size = 14) +
  stat_smooth(method = "lm", se = FALSE, colour = "#d90502") +
  annotate("text", x = -260, y = 230, label = "hat(y)", parse = TRUE, colour = "#d90502", size = 6) +
  geom_segment(data = kospi_sp500_reg,
               aes(xend = ret_sp500_bin, yend = .fitted), color = "#d90502", size = 0.5)
```

무엇을 "최소화"하는 직선을 구해야할까?

------------------------------------------------------------------------

## Ordinary Least Squares (OLS) 추정

-   잔차는 +/- 값이 있어 서로 상쇄됨. 따라서 **제곱 잔차(squared residuals)**를 고려 $$\forall i \in [1,N], e_i^2 = (y_i - \widehat y_i)^2 = (y_i - b_0 - b_1 x_i)^2$$

-   $\sum_{i = 1}^N e_1^2 + \dots + e_N^2$ 값이 **최소화하는** $(b_0, b_1)$ 값을 선택.

```{r, echo=FALSE, message=FALSE, warning=FALSE, fig.width=7,fig.height = 4}
g_sameday_bin +
    ylim(-300, 300) +
    xlim(-400, 400) +
    theme_bw(base_size = 14) +
    stat_smooth(method = "lm", se = FALSE, colour = "darkgreen") +
  coord_fixed(ratio = 1)
```

------------------------------------------------------------------------

## Ordinary Least Squares (OLS) 계수 공식

-   **OLS**: *잔차 제곱합(squared residuals)*을 최소화하는 추정 방법.

-   절편 $b_0$와 기울기 $b_1$의 공식, 하나의 독립변수만 있는 경우:

> 기울기 (Slope): $b_1^{OLS} = \frac{cov(x,y)}{var(x)}$

> 절편 (Intercept):$b_0^{OLS} = \bar{y} - b_1\bar{x}$

-   잔차 제곱합을 최소화하는 문제를 풀어 유도됨.\
    자세한 수학적 과정은 [\[여기\]](https://www.youtube.com/watch?v=Hi5EJnBHFB4)에서 확인.

------------------------------------------------------------------------

## Ordinary Least Squares (OLS) 해석

> 절편 $(b_0)$: $x = 0$일 때 예측된 $y$ 값 $(\widehat{y})$.

> 기울기 $(b_1)$: $x$가 한 단위 증가할 때, $y$ 값이 *평균적으로* 변하는 정도

-   두 변수 간 *"관련이 있음(associated)"*이라는 표현을 사용함.\
    즉, $b_1$을 $x$의 $y$에 대한 인과적 영향으로 해석하면 안 됨.\
    이를 주장하려면 **특정 조건**이 충족되어야 함.

-   또한 $x$의 단위(unit)에 따라 $b_1$의 해석과 크기(magnitude)가 달라질 수 있음.

-   $x$의 단위가 무엇인지 명확히 해야 함

------------------------------------------------------------------------

## OLS with `R`

-   OLS는 `lm`함수를 사용하여 추정가능

```{r, echo = TRUE, eval = FALSE}
lm(formula = dependent variable ~  independent variable, data = data.frame containing the data)
```

***코스피200 지수와 S&P500 지수***

-   다음과 같은 선형 모형을 OLS로 추정: $\textrm{KOSPI200 return}_i = b_0 + b_1 \textrm{S&P500 return}_i + e_i$

------------------------------------------------------------------------

## Ordinary Least Squares (OLS): Prediction

```{r echo=F, eval = TRUE}
# OLS regression of KOSPI200 return on S&P500 return
kospi_reg <- lm(formula = ret_kospi200_mean ~ ret_sp500_bin, data = returns_bin)
kospi_reg
```

이 결과가 의미하는 것 ($i$ 첨자 생략):

$$
\begin{aligned}
\widehat y &= b_0 + b_1 x \\
\widehat {\text{KOSPI200 return}} &= b_0 + b_1 \cdot \text{S&P500 return}
\end{aligned}
$$

S&P500 수익률이 30bp일 때 예상되는 코스피200 수익률은?

$$
\begin{aligned}
\widehat {\text{KOSPI200 return}} &= b_0 + b_1 \cdot 30
\end{aligned}
$$

------------------------------------------------------------------------

## Task 2 {background-color="#ffebf0"}

`r countdown(minutes = 5, top = "20px", right = "10px", font_size = "0.8em")`

1.  익일 코스피200 평균 수익률(`ret_kospi200_lead`)을 S&P500 수익률에 대해 회귀분석 수행. 회귀 계수(coefficients)를 해석하시오.

```{r, echo=F, eval=F}
kospi_reg <- lm(ret_kospi200_lead ~ ret_sp500, data = merged_px)
summary(kospi_reg)
```

2.  이 회귀분석에서 OLS 계수 $b_0$ 및 $b_1$을 직접 계산 (공식 이용).\
    ***힌트***: `cov`, `var`, `mean` 함수 사용.

```{r, echo=F, eval=F}
b_1 <- cov(merged_px$ret_sp500, merged_px$ret_kospi200_lead) / var(merged_px$ret_sp500)
b_0 <- mean(merged_px$ret_kospi200_lead) - b_1 * mean(merged_px$ret_sp500)
b_0
b_1
```

3.  S&P500 수익률이 0bp일 때, 예측된 익일 코스피200 수익률은 얼마인가?

```{r, echo=F, eval=F}
b_0 + b_1 * 0
```

4.  S&P500 수익률이 30bp일 때, 예측된 익일 코스피200 수익률은 얼마인가?

```{r, echo=F, eval=F}
b_0 + b_1 * 30
```

------------------------------------------------------------------------

## 예측값과 잔차의 성질

::::: columns
::: {.column width="50%"}
-   $\widehat{y}_i$의 평균은 $\bar{y}$와 같음 $$\begin{align} \frac{1}{N} \sum_{i=1}^N \widehat{y}_i &= \frac{1}{N} \sum_{i=1}^N b_0 + b_1 x_i \\ &= b_0 + b_1  \bar{x}  = \bar{y} \end{align}$$

-   잔차의 평균(또는 합)은 0. $$\begin{align} \frac{1}{N} \sum_{i=1}^N e_i &= \frac{1}{N} \sum_{i=1}^N (y_i - \widehat y_i) \\ &= \bar{y} - \frac{1}{N} \sum_{i=1}^N \widehat{y}_i \\\ &= 0 \end{align}$$
:::

::: {.column width="50%"}
-   설명 변수(regressor)와 잔차는 정의상 서로 상관이 없음.

    $$Cov(x_i, e_i) = 0$$

-   예측값과 잔차는 상관이 없음.

    $$\begin{align} Cov(\widehat y_i, e_i) &= Cov(b_0 + b_1x_i, e_i) \\ &= b_1Cov(x_i,e_i) \\ &= 0 \end{align}$$

    이는 $Cov(a + bx, y) = bCov(x,y)$라는 성질 때문.
:::
:::::

------------------------------------------------------------------------

## 선형성 가정: 데이터 시각화의 중요성

-   **공분산(covariance)**, **상관계수(correlation)**, 그리고 **단순 OLS 회귀**는 두 변수 간 **선형 관계(linear relationships)**만 측정한다는 점을 기억해야 함.

-   서로 *완전히 동일한* 상관계수 및 회귀선을 갖는 두 개의 데이터셋이 *완전히 다르게* 보일 수도 있음.

------------------------------------------------------------------------

## 선형성 가정: Anscombe의 예제

-   Francis Anscombe (1973)는 통계적으로 *완전히 동일한* 네 개의 데이터셋을 만들었음. 하지만 **시각적으로 보면 완전히 다름!**

```{r, echo=FALSE, fig.height=4}
##-- now some "magic" to do the 4 regressions in a loop:
ff <- y ~ x
mods <- setNames(as.list(1:4), paste0("lm", 1:4))
covs = data.frame(dataset = 1:4, cov = 0.0)
for(i in 1:4) {
  ff[2:3] <- lapply(paste0(c("y","x"), i), as.name)
  mods[[i]] <- lmi <- lm(ff, data = anscombe)
  covs[i,"cov"] = eval(parse(text = paste0("cov(anscombe$x",i,",anscombe$y",i,")")))
  covs[i,"var(y)"] = eval(parse(text = paste0("var(anscombe$y",i,")")))
  covs[i,"var(x)"] = eval(parse(text = paste0("var(anscombe$x",i,")")))
}

op <- par(mfrow = c(2, 2), mar = 0.1+c(4,4,1,1), oma =  c(0, 0, 0, 0))
for(i in 1:4) {
  ff[2:3] <- lapply(paste0(c("y","x"), i), as.name)
  plot(ff, data = anscombe, col = "black", pch = 21, bg = "#d90502", cex = 1.2,
       xlim = c(3, 19), ylim = c(3, 13),main=paste("dataset",i))
  abline(mods[[i]], col = "#DE9854")
}
par(op)
```

```{r,echo = FALSE}
ch = knitr::kable(round(covs,3))
if (requireNamespace("kableExtra", quietly = TRUE)) {
  ch %>% kableExtra::kable_styling(bootstrap_options = "striped", font_size = 20)
} else {
  ch
}
```

------------------------------------------------------------------------

## 데이터에서 비선형 관계?

::::: columns
::: {.column width="50%"}
-   회귀 분석에서 비선형 관계를 반영할 수 있음.

-   *고차항(higher order term)*을 추가하면 됨.\
    $$
      y_i = b_0 + b_1 x_i + b_2 x_i^2 + e_i
      $$

-   이는 **다중 회귀(multiple regression)**의 한 형태임.
:::

::: {.column width="50%"}
-   예를 들어, 아래 데이터에 다중 회귀 모델을 적용할 수 있음:

```{r non-line-cars-ols2, echo=FALSE, fig.height=6}
data(mtcars)
mtcars %>% ggplot(aes(x = hp, y = mpg)) +
    geom_point() +
    stat_smooth(method='lm', formula = y~poly(x,2), se = FALSE, aes(colour="Nonlinear")) +
    stat_smooth(method='lm', se = FALSE, aes(colour="Linear")) +
    scale_colour_manual(name="legend", values=c("darkgreen", "#d90502")) +
    labs(x = "x",
         y = "y",
         title = "Nonlinear relationship between x and y") +
    theme_bw(base_size = 20) +
    theme(legend.position="top") +
    theme(legend.title = element_blank())
```
:::
:::::

------------------------------------------------------------------------

## 분산 분석 (Analysis of Variance)

-   다음 관계를 기억할 것: $$
    y_i = \widehat{y}_i + e_i
    $$

-   이를 기반으로 **다음과 같은 분산 분해(variance decomposition)**를 얻음: $$\begin{align} 
    Var(y) &= Var(\widehat{y} + e)\\
    &= Var(\widehat{y}) + Var(e) + 2 Cov(\widehat{y},e)\\
    &= Var(\widehat{y}) + Var(e)
    \end{align}$$

-   총 변동 (SST) = 모델이 설명한 변동 (SSE) + 설명되지 않은 변동 (SSR)

-   왜냐하면:

    -   $Var(x+y) = Var(x) + Var(y) + 2Cov(x,y)$
    -   $Cov(\hat{y},e) = 0$

------------------------------------------------------------------------

## 적합도 평가 (Goodness of Fit)

-   $R^2$ 값은 **모델이 데이터를 얼마나 잘 설명하는지(fit)** 측정하는 지표.

$$
R^2 = \frac{\text{variance explained}}{\text{total variance}} = \frac{SSE}{SST} = 1 - \frac{SSR}{SST}\in[0,1]
$$

-   $R^2$ 값이 **1에 가까울수록**, 모델의 **설명력**이 ***높음.***

-   $R^2$ 값이 **0에 가까울수록**, 모델의 **설명력**이 ***낮음***.

-   예를 들어, $R^2 = 0.5$이면, $x$의 변화가 $y$의 변화 중 50%를 설명함.

-   낮은 $R^2$ 값이 무조건 모델이 쓸모없다는 뜻은 아님! **예측(predictive power)**보다는 **인과적 메커니즘(causal mechanisms)**에 더 초점을 맞추는 경우.

-   $R^2$ 값은 **인과 관계(causal relationship)를 나타내는 지표가 아님!** 회귀 모델에서 높은 $R^2$ 값이 있다고 해서, $x$가 $y$를 인과적으로 설명한다고 볼 수 없음!

------------------------------------------------------------------------

## Task 3 {background-color="#ffebf0"}

`r countdown(minutes = 10, top = "20px", right = "10px", font_size = "0.8em")`

1.  코스피200 수익률을 S&P500 수익률에 대해 회귀(regress)하고 결과를 `kospi_reg` 객체에 저장.

```{r, echo=F, eval=F}
kospi_reg <- lm(ret_kospi200 ~ ret_sp500, data = merged_px)
summary(kospi_reg)
```

2.  `summary(kospi_reg)`를 실행하여 **(다중)** $R^2$ 값을 확인함. 이 값의 의미를 해석할 것.

3.  코스피200 수익률을 S&P500 수익률 간 **상관계수(correlation)**를 제곱하여 계산. 참고: 이 값은 **단일 설명변수**를 가진 회귀에서 $R^2$와 상관계수 간의 관계를 보여줌.

```{r, echo=F, eval=F}
cor(merged_px$ret_sp500, merged_px$ret_kospi200)^2
```

4.  1번과 2번을 익일 코스피200 수익률에 대해 반복.\
    당일 코스피200 수익률과 익일 코스피200 수익률 중 어떤 결과가 S&P500 수익률 변화로 더 많이 설명되는지 비교하시오.

```{r, echo=F, eval=F}
kospi_reg <- lm(ret_kospi200_lead ~ ret_sp500, data = merged_px)
summary(kospi_reg)
```

5.  (Optional) `broom` 패키지를 설치 및 로드한 후, `augment(kospi_reg)`를 새로운 객체에 저장.\
    `ret_kospi200_lead`의 분산(SST)과 예측값의 분산(SSE)을 사용하여 $R^2$ 값을 직접 계산하시오. (이전 슬라이드의 공식을 참고할 것.)

    -   `broom` 패키지의 `augment()` 함수는 회귀 결과에 예측값과 잔차를 추가하는 데 사용됨.\

    ```{r, echo=F, eval=F}
    if (!requireNamespace("broom")) {install.packages("broom")}
    library(broom)
    kospi_reg_aug <- augment(kospi_reg) # 회귀 결과에 예측값과 잔차 추가
    SST <- var(merged_px$ret_kospi200_lead) * (nrow(merged_px) - 1)
    SSE <- var(kospi_reg_aug$.fitted) * (nrow(kospi_reg_aug) - 1)
    R_squared <- SSE / SST
    R_squared
    ```

# THE END!
