정형, 비정형 데이터의 정의
앞에서 언급 하였듯 데이터마이닝은 거대한 양의 데이터 속에 쉽게 드러나지 않는 통계적 규칙이나 패턴과 같은 유용한 정보를 찾아내는 과정이라 말할 수 있다. 데이터 내에 정보를 찾는 것이 주 목적
iris 자료는 R에서 기본으로 제공하는 붓꽃에 대한 자료
변수
setosa와 versicolor를 분류하는 모형을 만들려고 한다. 이에 따라 필요한 데이터를 추출
data(iris)
data=iris
summary(data)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100 setosa :50
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300 versicolor:50
Median :5.800 Median :3.000 Median :4.350 Median :1.300 virginica :50
Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199
3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500
boxplot(iris[,-5])
기존 자료에 대해 학습한 모형을 바탕으로 새롭게 나타나는 자료에 대하여 정의된 집합에 배정하는 것 모형을 의미한다.
데이터 정재 - 모형 생성 - 모형평가 및 모형비교 순으로 진행
로지스틱 회귀는 분석 대상들이 여러 집단으로 나누어진 경우, 독립 변수의 선형 결합을 이용하여 개별 관측치가 어느 집단에 속하는지 확률을 계산하는 분류 기법이다. 로지스틱이란 odds에 log를 취한 값으로 로지스틱 회귀모형은 아래와 같은 수식으로 나타난다.
\(\ln(\frac{P}{1-P})=a+bX\)
\(odds =\frac{어떤일이\ 일어날\ 확률}{어떤\ 일이\ 일어나지\ 않을\ 확률}\)
로지스틱회귀 모형을 사용하여 setosa와 versicolor를 분류
#데이터 추출
data<-subset(data,Species=="setosa"|Species=="versicolor")
data$Species<-factor(data$Species)
#모형생성
Species_glm<-glm(Species~.,data=data,family=binomial)
# Species_glm<-glm(Species~.,data=data,family=binomial)
# Species_glm<-glm(Species~.-Sepal.Length,data=data,family=binomial)
# Species_glm<-glm(Species~.+I(Sepal.Length^2),data=data,family=binomial)
#모형 요약
summary(Species_glm)
Call:
glm(formula = Species ~ ., family = binomial, data = data)
Deviance Residuals:
Min 1Q Median 3Q Max
-1.681e-05 -2.110e-08 0.000e+00 2.110e-08 2.006e-05
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) 6.556 601950.324 0 1
Sepal.Length -9.879 194223.245 0 1
Sepal.Width -7.418 92924.451 0 1
Petal.Length 19.054 144515.981 0 1
Petal.Width 25.033 216058.936 0 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 1.3863e+02 on 99 degrees of freedom
Residual deviance: 1.3166e-09 on 95 degrees of freedom
AIC: 10
Number of Fisher Scoring iterations: 25
모형의 성능을 평가하기 위해 데이터를 특정비율로 나누어 train 데이터만을 사용하여 모형을 학습시키고 test데이터로 이를 검증하는 방법을 cross validation이라고 한다. cross validation을 통해 모형의 성능을 비교가능 하다.
cross validation에는 holdout cross validation, k-fold cross validation, leave one out cross validation 등이 있다.
data2=data
set.seed(1)
idx=sample(1:nrow(data2),nrow(data2)*0.7)
train=data2[idx,]
test=data2[-idx,]
Species_glm<-glm(Species~.,data=train,family=binomial)
#test데이터를 Species_glm 모형으로 분류
pred=predict(Species_glm,test,type='response')
class=as.factor(round(pred))
levels(class)=c('setosa','versicolor')
table(class,test$Species)
class setosa versicolor
setosa 11 0
versicolor 0 19
위와 같은 표를 정오분류 표라고 한다.
모형 평가 지표
정밀도(Precision) : True라고 분류한 것 중에서 실제 True인 것의 비율 \(\frac{TP}{TP+FP}\)
재현율(Recall) : 실제 True인 것 중에서 모델이 True라고 예측한 것의 비율.민감도(sensitivity)라고 표현하기도 한다. \(\frac{TP}{TP+FN}\)
특이도(Specificity) : 실제 False인 것 중에서 False라고 예측한 것의 비율. \(\frac{TN}{TN+FP}\)
ROC(Receiver Operating Characteristics) : x축은 1-특이도, y축은 민감도를 나타낸 그래프로 이 그래프의 아랫 면적을 AUC(Area Under the ROC Curve)라 한다.
정확도(Accuracy) : 제대로 예측한 것의 비율 \(\frac{TP+TN}{TP+TN+FP+FN}\)
F1 score : 정밀도와 재현율의 조화평균 \(F1\ score = 2 \times \frac{1}{1/재현율+1/정밀도}\)
일반적으로 정확도를 사용해 모형의 성능을 평가하며, 모형이 만일 편향된 예측을 하는 경우 재현율보다 정밀도가 중요해진다. 하지만 정확도는 이를 고려할 수 없다. 이에 자료가 불균형 구조를 띌 때에는 F1 score를 모형평가에 사용한다. 이 경우 정확도를 사용하게되면 편향을 고려할 수 없다.
영역을 나누는 것의 기준은 분류모델을 기준으로 불순도(impurity)/불확실성(uncertainty)이 최소가 될 수 있도록하는 방향으로 진행된다. 순도나 불확실성의 증감을 두고 정보획득(information gain)으로 표현하기도 함.
library(rpart)
data2=iris
set.seed(1)
idx=sample(1:nrow(data2),nrow(data2)*0.7)
train=data2[idx,]
test=data2[-idx,]
Species_tree<-rpart(Species~.,data=train)
pred=predict(Species_tree,test,type='class')
table(pred,test$Species)
pred setosa versicolor virginica
setosa 15 0 0
versicolor 0 13 3
virginica 0 0 14
의사결정트리 시각화
library(rattle)
fancyRpartPlot(Species_tree)
가장 가까운 각 변수의 데이터 점들 간의 거리를 최대로 하는 초평면을 선택해 분류하는 기법
library(e1071)
data2=iris
set.seed(1)
idx=sample(1:nrow(data2),nrow(data2)*0.7)
train=data2[idx,]
test=data2[-idx,]
Species_svm<-svm(Species~.,data=train)
pred=predict(Species_svm,test,type='class')
table(pred,test$Species)
pred setosa versicolor virginica
setosa 15 0 0
versicolor 0 13 2
virginica 0 0 15
베이즈정리를 기반으로 만들어젔으며, 확률적으로 독립이라는 가정을 요구한다. 적은 데이터에 대하여도 우수한 성능을 보여준다.
library(e1071)
data2=iris
set.seed(1)
idx=sample(1:nrow(data2),nrow(data2)*0.7)
train=data2[idx,]
test=data2[-idx,]
Species_nb<-naiveBayes(Species~.,data=train)
pred=predict(Species_nb,test,type='class')
table(pred,test$Species)
pred setosa versicolor virginica
setosa 15 0 0
versicolor 0 13 2
virginica 0 0 15
여러 개의 분류 모형의 결과를 종합하여 분류의 정확도를 높이는 방법
배깅(bootstrap aggregating) : 복원추출을 통해 각각의 모형을 생성하고 그 결과를 종합하는 방법. 부스팅(boosting) : 앞의 모델에서 오분류된 데이터에 대하여 가중치를 주어 표본을 추출하여 모형을 생성하는 작업을 반복하는 방법
트리기반 모델들이므로 control 옵션을 통해 조절 가능하다.
ex)
my.control<-rpart.control(xval=0,cp=0,maxdepth=1)
bagging(Species~.,data=train,control=my.control)
library(adabag)
data2=iris
set.seed(1)
idx=sample(1:nrow(data2),nrow(data2)*0.7)
train=data2[idx,]
test=data2[-idx,]
Species_bagging<-bagging(Species~.,data=train)
importanceplot(Species_bagging,cex.name=0.8,horiz=TRUE)
pred=predict(Species_bagging,test)
table(pred$class,test$Species)
setosa versicolor virginica
setosa 15 0 0
versicolor 0 13 3
virginica 0 0 14
library(adabag)
data2=iris
set.seed(1)
idx=sample(1:nrow(data2),nrow(data2)*0.7)
train=data2[idx,]
test=data2[-idx,]
Species_boosting<-boosting(Species~.,data=train)
importanceplot(Species_boosting,cex.name=0.8,horiz=TRUE)
pred=predict(Species_boosting,test)
table(pred$class,test$Species)
setosa versicolor virginica
setosa 15 0 0
versicolor 0 13 2
virginica 0 0 15
Random forest
randomforest는 의사결정나무의 앙상블 모형으로 다수의 의사결정나무의 분류 중 최고로 많이 분류된 기준을 분류 예측값으로 제시하며, 회귀의 경우 의사결정나무의 예측값의 평균을 예측값으로 사용.
library(randomForest)
data2=iris
set.seed(1)
idx=sample(1:nrow(data2),nrow(data2)*0.7)
train=data2[idx,]
test=data2[-idx,]
Species_rf<-randomForest(Species~.,data=train)
pred=predict(Species_rf,test,type='class')
table(pred,test$Species)
pred setosa versicolor virginica
setosa 15 0 0
versicolor 0 13 2
virginica 0 0 15
hyper parameter
하이퍼파라메터 : 알고리즘을 최적화 하는데 사용되는 모수
하이퍼 파라메터의 튜닝 방법은 다양하나 일반적으로 cross validation을 활용한다. cross validation은
seed=3
set.seed(seed)
idx=sample(1:nrow(iris),nrow(iris)*.5)
train=iris[idx,]
set.seed(seed)
idx2=sample(1:nrow(iris[-idx,]),nrow(iris[-idx,])*.5)
valid=iris[-idx,][idx2,]
test=iris[-idx,][-idx2,]
summary(train)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.400 Min. :2.00 Min. :1.000 Min. :0.100 setosa :27
1st Qu.:5.100 1st Qu.:2.80 1st Qu.:1.600 1st Qu.:0.250 versicolor:25
Median :5.800 Median :3.00 Median :4.100 Median :1.300 virginica :23
Mean :5.873 Mean :3.08 Mean :3.663 Mean :1.136
3rd Qu.:6.400 3rd Qu.:3.40 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.10 Max. :6.900 Max. :2.500
summary(valid)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.200 Min. :1.100 Min. :0.100 setosa :13
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.500 1st Qu.:0.400 versicolor:14
Median :5.700 Median :3.000 Median :4.500 Median :1.300 virginica :10
Mean :5.768 Mean :3.116 Mean :3.659 Mean :1.154
3rd Qu.:6.500 3rd Qu.:3.400 3rd Qu.:5.000 3rd Qu.:1.700
Max. :7.400 Max. :4.400 Max. :6.100 Max. :2.500
rf.model=randomForest(data=train,Species~.)
set.seed(seed)
trf=tuneRF(valid[,1:4],valid[,5])
mtry = 2 OOB error = 8.11%
Searching left ...
mtry = 1 OOB error = 13.51%
-0.6666667 0.05
Searching right ...
mtry = 4 OOB error = 10.81%
-0.3333333 0.05
rf.model=randomForest(data=train,Species~.,mtry=2)
plot(rf.model)
pred=predict(rf.model,test)
table(test$Species,pred)
pred
setosa versicolor virginica
setosa 10 0 0
versicolor 0 11 0
virginica 0 0 17
varImpPlot(rf.model)
학습과 검증방법은 분류모형과 동일하나 평가지표가 수치형이므로 서로 상이하다.
예측모형도 앞에서와 같이 간단하게 생성할 수 있다. 모형 평가에 사용되는 지표는 분류모형과 달리 값이 연속형 수치이므로 다른 지표들을 사용한다. 일반적으로 RMSE와 MAE를 많이 사용한다.
bias-variance trade off
mse는 합을 하기전에 제곱을 하였으므로 실제값과 예측값의 차이가 클수록 값이 mae에 비해 커진다. 따라서 필요에 따라 모형지표를 선택할 필요가 있다. 또한 RMSE나 MAE는 단위에 영향을 받는 반면 MAPE는 단위의 영향을 받지 않는다.
library(spTimer)
seed=3
set.seed(seed)
idx=sample(1:nrow(iris),nrow(iris)*.5)
train=iris[idx,]
set.seed(seed)
idx2=sample(1:nrow(iris[-idx,]),nrow(iris[-idx,])*.5)
valid=iris[-idx,][idx2,]
test=iris[-idx,][-idx2,]
summary(train)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.400 Min. :2.00 Min. :1.000 Min. :0.100 setosa :27
1st Qu.:5.100 1st Qu.:2.80 1st Qu.:1.600 1st Qu.:0.250 versicolor:25
Median :5.800 Median :3.00 Median :4.100 Median :1.300 virginica :23
Mean :5.873 Mean :3.08 Mean :3.663 Mean :1.136
3rd Qu.:6.400 3rd Qu.:3.40 3rd Qu.:5.100 3rd Qu.:1.800
Max. :7.900 Max. :4.10 Max. :6.900 Max. :2.500
summary(valid)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
Min. :4.300 Min. :2.200 Min. :1.100 Min. :0.100 setosa :13
1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.500 1st Qu.:0.400 versicolor:14
Median :5.700 Median :3.000 Median :4.500 Median :1.300 virginica :10
Mean :5.768 Mean :3.116 Mean :3.659 Mean :1.154
3rd Qu.:6.500 3rd Qu.:3.400 3rd Qu.:5.000 3rd Qu.:1.700
Max. :7.400 Max. :4.400 Max. :6.100 Max. :2.500
rf.model=randomForest(data=train,Species~.)
set.seed(seed)
trf=tuneRF(valid[,1:4],valid[,5])
mtry = 2 OOB error = 8.11%
Searching left ...
mtry = 1 OOB error = 13.51%
-0.6666667 0.05
Searching right ...
mtry = 4 OOB error = 10.81%
-0.3333333 0.05
rf.model=randomForest(data=train,Sepal.Length~.,mtry=which.min(trf[,2]))
plot(rf.model)
pred=predict(rf.model,test)
spTimer::spT.validation(test$Sepal.Length,pred)
MSE RMSE MAE MAPE BIAS rBIAS rMSEP
0.1373 0.3705 0.2702 4.7305 0.1172 0.0200 0.2196
varImpPlot(rf.model)