본문 바로가기
인과관계분석

코스피지수의 회귀분석 with R

by 다빈치스탁 2020. 9. 2.
728x90
반응형

회귀분석이란? 어떠한 사건 (가), (나)의 발생이 서로 연관이 있고(비독립적이며) 상호간의 방향성이 있을 때 변수들의 인과관계를 가정한 수학적 모델링과 측정자료를 통해 계수를 추정, 미래를 예측하는 과정이다. (더 멋진 말이 있을 수 있다. 항상 정답은 아닐 수도 있다는 점 명심.)

 

머신러닝에서도 다루게 될 내용이지만 대부분의 supervised learning 에서는 iid(independent, identical distribute 즉 상호독립적이고 균일한 분포를 확률분포를 가정)를 가정으로 한다. 이와 유사하게 회귀분석에서 몇 가지 가정을 만족할 때 분석을 수행할 수 있다. 

 

회귀분석의 선행조건(가정) : 원래는 측정자료의 검토 및 잔차의 검토 등을 통해 적합성검증을 수행하여야 하나 이번 포스트에서는 이 과정을 생략하고 이미 만족하고 있다고 가정한다.

  • 선형성(종속변수와 독립변수간의 선형관계)
  • 독립성(종속변수, 독립변수, 오차항은 서로 독립)
  • 정규성(종속변수, 오차항은 정규분포를 따른다.)
  • 등분성(오차항의 분산은 동일하다.)

자 이제 코스피지수의 시계열 데이터를 R을 이용한 선형 회귀분석으로 돌려볼텐데 R에서는 주로 "lm"을 중심으로 구성된다. 여기서 가장 중요한 것은 formula를 어떻게 설정할까 하는 것이고 단변량선형회귀에서는 y~x 로 설정해주면 된다.

function (formula, data, subset, weights, na.action, method = "qr", 
    model = TRUE, x = FALSE, y = FALSE, qr = TRUE, singular.ok = TRUE, 
    contrasts = NULL, offset, ...) 
{
    ret.x <- x
    ret.y <- y
    cl <- match.call()
    mf <- match.call(expand.dots = FALSE)
    m <- match(c("formula", "data", "subset", "weights", "na.action", 
        "offset"), names(mf), 0L)
    mf <- mf[c(1L, m)]
    mf$drop.unused.levels <- TRUE
    mf[[1L]] <- quote(stats::model.frame)
    mf <- eval(mf, parent.frame())
    if (method == "model.frame") 
        return(mf)
    else if (method != "qr") 
        warning(gettextf("method = '%s' is not supported. Using 'qr'", 
            method), domain = NA)
    mt <- attr(mf, "terms")
    y <- model.response(mf, "numeric")
    w <- as.vector(model.weights(mf))
    if (!is.null(w) && !is.numeric(w)) 
        stop("'weights' must be a numeric vector")
    offset <- as.vector(model.offset(mf))
    if (!is.null(offset)) {
        if (length(offset) != NROW(y)) 
            stop(gettextf("number of offsets is %d, should equal %d (number of observations)", 
                length(offset), NROW(y)), domain = NA)
    }
    if (is.empty.model(mt)) {
        x <- NULL
        z <- list(coefficients = if (is.matrix(y)) matrix(NA_real_, 
            0, ncol(y)) else numeric(), residuals = y, fitted.values = 0 * 
            y, weights = w, rank = 0L, df.residual = if (!is.null(w)) sum(w != 
            0) else if (is.matrix(y)) nrow(y) else length(y))
        if (!is.null(offset)) {
            z$fitted.values <- offset
            z$residuals <- y - offset
        }
    }
    else {
        x <- model.matrix(mt, mf, contrasts)
        z <- if (is.null(w)) 
            lm.fit(x, y, offset = offset, singular.ok = singular.ok, 
                ...)
        else lm.wfit(x, y, w, offset = offset, singular.ok = singular.ok, 
            ...)
    }
    class(z) <- c(if (is.matrix(y)) "mlm", "lm")
    z$na.action <- attr(mf, "na.action")
    z$offset <- offset
    z$contrasts <- attr(x, "contrasts")
    z$xlevels <- .getXlevels(mt, mf)
    z$call <- cl
    z$terms <- mt
    if (model) 
        z$model <- mf
    if (ret.x) 
        z$x <- x
    if (ret.y) 
        z$y <- y
    if (!qr) 
        z$qr <- NULL
    z
}

작업을 수행하기에 앞서 KOSPI 데이터를 가져와야 하는데 가져오는 방법은 지난번 포스트 (2020/09/01 - [데이터마이닝 with R] - R 데이터 가져오기)를 참고하면 된다. 그보다 더 이전에 증권사 API를 이용한 차트데이터 불러오기도 보지 않은 분들은 그 이전 포스트 2020/08/28 - [증권사 API] - 이베스트증권 차트TR 만들어보기(VBA 활용 - 주식차트편)를 참고하면 상세하게 다 나와 있다.

 

자, 그러면 우리는 이제 코스피 지수의 미래 예측값을 R을 이용해서 구해볼건데 독립변수와 종속변수를 설정한 뒤 아래의 코드와 같이 model을 정의하고 분석하면 회귀계수와 절편이 도출된다. (아래의 코드를 R-studio 혹은 R에 붙여넣고 돌리면 된다. 단, 작업경로는 본인의 환경에 맞게 잘 수정해서 쓰자.)

 

#작업경로를 지정하는 명령어
setwd("C:/Users/Documents/R-code")

#데이터 끌어오기(텍스트형태)
mydatat<-read.table("jisu.txt",
                    header=TRUE, sep="\t", na.strings = "")
mydatat
str(mydatat)

#독립변수
timein<-c(1:499)

#종속변수
kospi<-mydatat$코스피지수

#y:kospi, x:timeinterval
model1<-lm(kospi~timein)
summary(lm(kospi~timein))

#회귀직선을 그린다.
alpha=signif(lm(kospi~timein)$coefficient[1],digits = 3)
beta=signif(lm(kospi~timein)$coefficient[2],digits = 3)
plot(timein,kospi,main="회귀직선")
abline(alpha,beta)
text(200,1600,paste("y=",alpha,"+",beta,"x"))


#nx:new x, 새로운 타임인터벌 생성
nx=data.frame(timein=c(500:600))
pre=predict(model1,nx,interval="prediction")
pre

#예측치를 그려준다.
plot(timein,kospi,main="회귀분석 예측")
matplot(nx$timein,cbind(pre),type="l",col=2,xlab="",ylab="",add=T)
text(450,1774,"low : 1774");text(400,2315,"upper : 2315")

 

위의 코드를 돌려서 나온 결과 회귀직선의 경우 절편은 2150, 그리고 기울기는 -0.18로 분석되었다. 어떤 움직이는 물체에 관한 아주 기초적인 미분방정식이 도출된 셈이다. 물론 정확하지는 않을 수 있지만 아래의 회귀방정식으로 약 100거래일 앞을 예측해보자..

어랏! 예측을 수행했더니 아래와 같이 100거래일 동안 발생할 수 있는 최대 상한폭은 약 2315 포인트, 그리고 만약 폭락이 나와서 빠질 수 있는 하한폭은 1774로 도출되었다. upper bound 와 lower bound는 위 코드에서 지정해주지 않았기 때문에 기본적으로 95%신뢰구간에서 추정된 것이다.(predict 함수의 인자 중 confidence level이라는 값을 0.99로 변경할 수도 있다.) 아래의 예측결과를 직관적으로 표현하자면 향후 100거래일 동안 코스피지수는 95%의 확률로 1774~2315의 구간에 머무를 것이다라고 생각할 수 있다. 

사실 위의 회귀분석에서는 원인변수를 시간의 흐름으로 간주하고 분석을 수행했기 때문에 이와 같은 단순한 선형회귀분석보다는 time series modeling 기법인 arima(자기회귀이동평균모형)와 같은 모형이 더 적합하지만 우선 회귀모형의 기본을 파악하기 위해서 이와 같은 분석을 수행해봤다. 별거 없는 것 같지만 그래도 추후 코스피의 박스권 상단과 하단에 대한 참고자료로 활용하기에는 나쁘지 않은 자료가 될 것이다. 이를 토대로 자동차, 반도체, 음식료 등의 업종 분석은 물론 개별종목에 대해서도 수행할 수 있으니 각자 응용을 해보기 바란다.

 

다음 포스트에서는 각 업종별 지수를 독립변수로 하고 개별주가가 종속변수가 되는 중회귀분석을 수행해보겠다. 

728x90
반응형

'인과관계분석' 카테고리의 다른 글

삼성전자 중회귀분석 with R - 심화편  (0) 2020.09.07
삼성전자의 중회귀분석 with R  (0) 2020.09.02
R 통계분석  (0) 2020.09.01
R 데이터 가져오기  (0) 2020.09.01
R 기초문법을 배워보자  (0) 2020.09.01

댓글