지난 포스트에서 Smarket 데이터 셋의 주식 가격 상승 여부를 Logistic Regression으로 분류해 보았다.
이번에는 LDA를 이용하려고 하는데, R에서는 MASS 라이브러리의 lda() 함수를 이용하여
모형을 적합시킬 수 있다.
> library(MASS)
> lda.fit = lda(Direction ~ Lag1 + Lag2, data = Smarket.train)
> lda.fit
Call:
lda(Direction ~ Lag1 + Lag2, data = Smarket.train)
Prior probabilities of groups:
Down Up
0.491984 0.508016
Group means:
Lag1 Lag2
Down 0.04279022 0.03389409
Up -0.03954635 -0.03132544
Coefficients of linear discriminants:
LD1
Lag1 -0.6420190
Lag2 -0.5135293
이제 출력 결과들을 살펴보자.
Prior probabilities of groups에 따르면 사전 확률은 0.49, 0.51 이라는 것을 알 수 있다.
그리고 Group means가 같이 제공되는데, 이 값은 LDA에서 의 추정치로 사용되는 값이다.
이를 통해 주가가 상승한 날에는 이전 이틀간의 수익률이 음수일 가능성이 높고,
주가가 하락한 날에는 이전 이틀간의 수익률이 양수일 가능성이 높다는 것을 파악할 수 있다.
Coefficients of linear discriminants에는 선형 판별 함수의 계수를 제공한다. 따라서 선형 판별 함수는 다음과 같다.
predict() 함수는 세 가지 객체가 포함되어 있는데, 첫 번째 객체인 class에는 주가 변동에 대한 예측, 두 번째 객체인 posterior에는 각 관측값이 해당 클래스에 속할 사후확률, 세 번째 객체 x에는 선형 판별 함수에 관측치 를 넣어 계산한 결과가 포함되어 있다.
> lda.pred = predict(lda.fit, newdata = Smarket.2005)
> names(lda.pred)
[1] "class" "posterior" "x"
LDA에서의 적중률은 약 56%로 Logistic Regression과 크게 다르지 않다.
> lda.class = lda.pred$class
> table(lda.class, Direction.2005)
Direction.2005
lda.class Down Up
Down 35 35
Up 76 106
> mean(lda.pred$class == Direction.2005)
[1] 0.5595238
이번에는 QDA를 적용해보자. 마찬가지로 MASS 라이브러리의 qda() 함수를 사용하면 된다.
> qda.fit = qda(Direction ~ Lag1 + Lag2, data = Smarket.train)
> qda.fit
Call:
qda(Direction ~ Lag1 + Lag2, data = Smarket.train)
Prior probabilities of groups:
Down Up
0.491984 0.508016
Group means:
Lag1 Lag2
Down 0.04279022 0.03389409
Up -0.03954635 -0.03132544
LDA와 거의 비슷하지만 출력값에 판별 함수가 포함되지 않는다.
예측의 적중률을 보면 약 60%로, 주식 시장을 정확히 예측하기 어렵다는 점을 고려하면 꽤 높은 값이다.
> qda.pred = predict(qda.fit, newdata = Smarket.2005)
> names(qda.pred)
[1] "class" "posterior"
> mean(qda.pred$class == Direction.2005)
[1] 0.5992063
마지막으로 나이브 베이즈 모델을 적합시켜 보자. e1071 라이브러리의 naiveBayes() 함수를 사용하면 된다.
> nb.fit = naiveBayes(Direction ~ Lag1 + Lag2, data = Smarket.train)
> nb.fit
Naive Bayes Classifier for Discrete Predictors
Call:
naiveBayes.default(x = X, y = Y, laplace = laplace)
A-priori probabilities:
Y
Down Up
0.491984 0.508016
Conditional probabilities:
Lag1
Y [,1] [,2]
Down 0.04279022 1.227446
Up -0.03954635 1.231668
Lag2
Y [,1] [,2]
Down 0.03389409 1.239191
Up -0.03132544 1.220765
출력된 결과를 통해 클래스 별 각 변수의 추정된 평균과 표준편차을 알 수 있는데,
예를 들어 Direction = Down일 때 Lag1의 평균은 0.0428이고 표준편차는 1.23이다.
> nb.pred = predict(nb.fit, newdata = Smarket.2005)
> mean(nb.pred == Direction.2005)
[1] 0.5912698
나이브 베이즈의 클래스 적중률은 약 59%로, QDA보다는 약간 낮지만 LDA보다는 훨씬 더 좋은 성능이다.
여기서 predict() 함수로 각 관측값이 특정 클래스에 속할 확률, 즉 Posterior의 추정치를 생성할 수도 있다.
> nb.preds = predict(nb.fit, Smarket.2005, type = "raw")
> nb.preds[1:5, ]
Down Up
[1,] 0.4873164 0.5126836
[2,] 0.4762492 0.5237508
[3,] 0.4653377 0.5346623
[4,] 0.4748652 0.5251348
[5,] 0.4901890 0.5098110