· Test - Training
데이터를 분석하고 예측하는 방법으로 Test - Training - Validation data 방법을 많이 사용한다.
해당 방법을 사용하면 하나의 데이터 집합에서 Training으로 모델을 학습시키면서 해당 학습 방법에 대한 중간 평가를 하는 역할이 Validation data이다. 이 후 최종적으로 나온 모델은 처음 보는 데이터에 대해 잘 적응하는지 알아보기 위해 Test에게 적용하여 평가한다.
테스트 - 트레이닝으로 데이터를 나누는 것은 데이터 분석의 평가 외에도 장점이 하나 더 있는데 과적합(Over-fitting)을 피할 수 있다.
2021.07.01 - [통계/회귀분석 - R 프로그래밍] - 회귀분석의 과적합(Overfitting)
회귀분석의 과적합(Overfitting)
· 과적합(Overfitting) 과적합이란 데이터 분석을 진행함에 있어 모델 학습을 과하게 한 경우를 말한다. 학습 데이터에 대한 분석을 과하게 해서 실제 데이터에 대한 적중률이 떨어져서 오차가 증
bluenoa.tistory.com
- 모든 데이터를 사용
모든 데이터를 이용해서 예측과 분류 모델로 만들어서 훈련시키는 경우
데이터를 다 사용하면 과소적합(under-fitting), 적합(generalized-fitting), 과적합(over-fitting)인지 알 수 없게 된다.
모든 데이터를 사용하면 MSE(Mean Squared Error, 평균 제곱근 편차)가 작아진다. 앞 게시물들에서 MSE가 낮은 결과가 좋다고 했는데, 예외적인 상황에서도 MSE가 낮은 모델이 좋을까?
많은 데이터로 훈련을 시킬 경우 Error는 작아지는 경향이 있으므로 결국 과적합으로 이어질 가능성이 크다.
그렇다면 중간에 과적합으로 넘어가기 전에 적합한 적합식이 있다는 것인데 언제 어디쯤에서 Training을 멈춰야 하는지를 알고 싶은 것이다.
- 훈련 모형(Training)과 검증 모형(Validation)
보통 Training을 60%, Validation을 20%, Test를 20% 정도로 지정해서 분석한다.
트레이닝을 통해 학습시킨 모델은 Error가 점점 낮아질 것이다. 이렇게 학습된 모델을 Validation이 받아오면 과적합으로 빠지기 전의 구간을 계산한다. 그렇기 때문에 Validation은 Training에 비해 Error가 조금 더 높다.
여기서 적합한 회귀 모형이 선택되면 이제 Test에 적용하여 최종 모델을 검증한다.
- 번외
데이터의 크기가 작거나 분류에 문제가 있을 경우
K-fold cross Validation 기법을 이용하면 적절한 데이터의 분할 개수를 정해준다.
Training (80%) 데이터를 k개의 set으로 분류하여 교차하여 검증하는 방법이다.
참고로 데이터를 7 : 3으로 나눠서 검증을 했을 경우에도 과적합이 발생하면 cross validation을 사용하는 것이 좋다.
아니면 처음부터 사용하는 것도 좋은 방법이다.
자세한 내용은 개념 카테고리에서 다룰 예정이다.
· 예제
Petal.Width, Sepal.Width, Sepal.Length에 따른 Petal.Length를 예측한다고 한다면 다음과 같이 작성한다.
data() # 현재 사용 가능한 데이터를 보여준다.
# iris 기본 제공 데이터로 학습 / 검정 모델로 분리하여 검정한다.
head(iris, 10) # 10개 정도의 데이터를 출력해 구성 파악
# Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species
str(iris) # 각 칼럼의 속성을 출력해준다.
cor(iris[,-5]) # 5번째 열인 'Species'를 제외한 상관계수
# train과 test로 분리한다. 대략 7:3 비율
NROW(iris) # 행의 개수 확인 150
set.seed(123) # 난수표에 의한 랜덤 샘플링
samp_dt = sample(1:nrow(iris), nrow(iris) * 0.7, replace = F) # 비복원으로 현재 내에서 70%만 추출한다.
samp_dt; NROW(samp_dt) # 어떤 함수 밖에서 사용할 땐 대문자로 사용하는 것을 추천천, 105개 샘플 데이터
# 학습 집합
train_dt = iris[samp_dt, ] # 학습용 105개 데이터, samp_dt 데이터의 행(105개)과 전체 열
train_dt
# 검증 집합
test_dt = iris[-samp_dt, ] # 105개의 행을 제외한 나머지 데이터와 전체 열 가져오기
test_dt
dim(train_dt); dim(test_dt) # 105행 5열, 45행 5열
# 분석을 위한 학습 모델 생성
model_train = lm(Petal.Length ~ Petal.Width + Sepal.Width + Sepal.Length, data = train_dt)
options(scipen = 999) # 소수점을 생략하지 않는다.
summary(model_train) # 학습 데이터를 이용한 모델은 전반적으로 유의하다고 판단된다.
# 잔차
res = residuals(model_train)
yhat = 1.47429 * train_dt$Petal.Width -0.59086 * train_dt$Sepal.Width + 0.72590 * train_dt$Sepal.Length -0.44761
yhat
# 선형성 분석
library(car)
boxTidwell(Petal.Length ~ Petal.Width + Sepal.Width + Sepal.Length, data = train_dt)
# 독립성
library(lmtest) # dw사용
dwtest(Petal.Length ~ Petal.Width + Sepal.Width + Sepal.Length, data = train_dt)
# DW = 2.249, p-value = 0.8986, 독립이라고 봐도 무방하다.
# 정규성
hist(res) # 어느정도 정규분포의 모양을 띄는 것 같다.
qqplot(yhat, res) # 45도 각도의 일직선으로 우상향하진 않는다.
shapiro.test(res) # W = 0.98346, p-value = 0.2166, 귀무가설 기각 불가 : 정규성을 어느정도 만족한다고 볼 수 있다.
# 등분산성
plot(yhat,res); abline(h=0, col="red") # 등분산성을 만족하는 것 같진 않다.
ncvTest(model_train) # p = 0.017779 : 귀무가설 기각, 등분산성을 만족하지 않는다.
# 데이터 검증
new_data = data.frame(Petal.Width = c(1.2), Sepal.Width = c(3), Sepal.Length = c(4.2))
pred = predict(model_train, newdata = new_data, interval = "confidence") # 신뢰구간 포함, 제외하고 싶으면 "prediction"
pred
- 데이터 구성
iris 데이터의 10개 행만 추출 |
head(iris, 10) Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa 7 4.6 3.4 1.4 0.3 setosa 8 5.0 3.4 1.5 0.2 setosa 9 4.4 2.9 1.4 0.2 setosa 10 4.9 3.1 1.5 0.1 setosa |
str(iris) - 각 데이터의 속성값 'data.frame': 150 obs. of 5 variables: $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ... $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ... $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ... $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ... $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ... |
cor(iris[,-5]) 범주형인 5행을 제외하고 상관계수 Sepal.Length Sepal.Width Petal.Length Petal.Width Sepal.Length 1.0000000 -0.1175698 0.8717538 0.8179411 Sepal.Width -0.1175698 1.0000000 -0.4284401 -0.3661259 Petal.Length 0.8717538 -0.4284401 1.0000000 0.9628654 Petal.Width 0.8179411 -0.3661259 0.9628654 1.0000000 |
- 생성된 모델의 정보
summary(model_train) lm(formula = Petal.Length ~ Petal.Width + Sepal.Width + Sepal.Length, data = train_dt) Residuals: Min 1Q Median 3Q Max -1.02032 -0.16147 -0.01158 0.20749 0.62223 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) -0.44761 0.34433 -1.300 0.197 Petal.Width 1.47429 0.08202 17.974 < 0.0000000000000002 *** Sepal.Width -0.59086 0.08274 -7.141 0.000000000146 *** Sepal.Length 0.72590 0.06700 10.834 < 0.0000000000000002 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 0.3259 on 101 degrees of freedom Multiple R-squared: 0.9682, Adjusted R-squared: 0.9672 F-statistic: 1024 on 3 and 101 DF, p-value: < 0.00000000000000022 |
- 선형성 분석
library(car) boxTidwell(Petal.Length ~ Petal.Width + Sepal.Width + Sepal.Length, data = train_dt) MLE of lambda Score Statistic (z) Pr(>|z|) Petal.Width 0.65743 -4.0341 0.0000548 *** Sepal.Width 3.17307 -1.8113 0.07009 . Sepal.Length 2.77734 2.5392 0.01111 * --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 iterations = 7 |
- 독립성 분석
library(lmtest) # dw사용 dwtest(Petal.Length ~ Petal.Width + Sepal.Width + Sepal.Length, data = train_dt) Durbin-Watson test data: Petal.Length ~ Petal.Width + Sepal.Width + Sepal.Length DW = 2.249, p-value = 0.8986 alternative hypothesis: true autocorrelation is greater than 0 |
- 정규성 분석
shapiro.test(res) # W = 0.98346, p-value = 0.2166, 귀무가설 기각 불가 : 정규성을 어느정도 만족한다고 볼 수 있다. Shapiro-Wilk normality test data: res W = 0.98346, p-value = 0.2166 |
- 등분산성
ncvTest(model_train) # p = 0.017779 : 귀무가설 기각, 등분산성을 만족하지 않는다. Non-constant Variance Score Test Variance formula: ~ fitted.values Chisquare = 5.617835, Df = 1, p = 0.017779 |
- 데이터 검증
new_data = data.frame(Petal.Width = c(1.2), Sepal.Width = c(3), Sepal.Length = c(4.2)) pred = predict(model_train, newdata = new_data, interval = "confidence") # 신뢰구간 포함, 제외하고 싶으면 "prediction" pred fit lwr upr 1 2.597752 2.373298 2.822207 |
'통계 프로그램 > R - Programing' 카테고리의 다른 글
RStudio에서 R버전 업데이트 하기 (0) | 2021.06.17 |
---|---|
R - 자료 생성과 자료의 유형(종류) (0) | 2021.06.17 |
R - 기초 (0) | 2021.06.17 |