본인의


텀프로젝트 Github은 아래와 같다.

https://github.com/leejaymin/practical_machine_learning


그리고 작성문서는 아래의 파일과 같다.

급하게 작성하느라 문법적 오류가 많은것으로 판단된다.

작성한지 꽤 된 내용이지만 필요한 사람이 있을것 같아서 이곳에 업로드 한다.



practical_machine_learning.html


practical_machine_learning.Rmd


'MOOC > Practical Machine Learning (r programing)' 카테고리의 다른 글

Certification and Comments  (0) 2015.12.04
Week 04: Regularized Regression  (0) 2015.11.24
Week03: Model based prediction  (0) 2015.11.23
Week03: Boosting  (0) 2015.11.23
Week 03: Random Forests  (0) 2015.11.23

Certificate and Comment


수료증을 발급 받았다.

R을 이용한 Machine Learning을 달성하기 위해서 caret package를 주로 활용하는 방법을 배웠다.

아래는 발급받은 수료증이며, 90점 이상으로 Distinction을 받았다.



'MOOC > Practical Machine Learning (r programing)' 카테고리의 다른 글

Term Project  (0) 2016.04.07
Week 04: Regularized Regression  (0) 2015.11.24
Week03: Model based prediction  (0) 2015.11.23
Week03: Boosting  (0) 2015.11.23
Week 03: Random Forests  (0) 2015.11.23

Basic Idea

  1. Fit a regression model
  2. Penalize
    Pros:
  • Can help with the bias / variance trade-off
    Cons:
  • May be computationally demanding on large data sets
  • Does not perform as well as random forests and boosting

The bias is error from erroneous assumptions in the learning algorithm. High bias can cause an algorithm to miss the relevant relations between features and target outputs (underfitting). The variance is error from sensitivity to small fluctuations in the training set. High variance can cause overfitting: modeling the random noise in the training data, rather than the intended outputs.

A motivating example


where $X1$ and $X2$ are nearly perfectly correlated (co-linear). We can approximate this model by:
$$ Y = \beta_0 + \beta_1X_1+\beta_2X_2+\varepsilon $$

$$ Y = \beta_0 + (\beta_1+\beta_2X_1)+\varepsilon $$
These two functions are not exactly same beacuse we choose to leave one of the predictors out but we can avoid overffting.

Y=β0+β1X1+β2X2+ε
Prostate cancer
library(ElemStatLearn); data(prostate)
str(prostate)
## 'data.frame':    97 obs. of  10 variables:
##  $ lcavol : num  -0.58 -0.994 -0.511 -1.204 0.751 ...
##  $ lweight: num  2.77 3.32 2.69 3.28 3.43 ...
##  $ age    : int  50 58 74 58 62 50 64 58 47 63 ...
##  $ lbph   : num  -1.39 -1.39 -1.39 -1.39 -1.39 ...
##  $ svi    : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ lcp    : num  -1.39 -1.39 -1.39 -1.39 -1.39 ...
##  $ gleason: int  6 6 7 6 6 6 6 6 6 6 ...
##  $ pgg45  : int  0 0 20 0 0 0 0 0 0 0 ...
##  $ lpsa   : num  -0.431 -0.163 -0.163 -0.163 0.372 ...
##  $ train  : logi  TRUE TRUE TRUE TRUE TRUE TRUE ...


Model selection approach: split samples

  • No method better when data/computation time permits it
  • Approach
    1. Divide data into training/test/validation
    2. Treat validation as test data, train all competing models on the train data and pick the best one on validation.
    3. To appropriately assess performance on new data apply to test set
    4. You may re-split and reperform steps 1-3
    5. Two common problems
  • Limited data
    • Computational complexity


'MOOC > Practical Machine Learning (r programing)' 카테고리의 다른 글

Term Project  (0) 2016.04.07
Certification and Comments  (0) 2015.12.04
Week03: Model based prediction  (0) 2015.11.23
Week03: Boosting  (0) 2015.11.23
Week 03: Random Forests  (0) 2015.11.23

Basic Idea

Assume the data follow a probabilistic model Use Bayes’ theorem to identify optimal classifiers

Proc:
- Can take advantage of structure of the data
- May be computationally convenient
- Are reasonably accurate on real problems

Cons:
- Make additional assumptions about the data
- When the model is incorrect you may get reduced accruacy

Example: Iris Data

data(iris); library(ggplot2); library(caret)
## Loading required package: lattice
names(iris)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width" 
## [5] "Species"
table(iris$Species)
## 
##     setosa versicolor  virginica 
##         50         50         50

Create training and test sets

inTrain <- createDataPartition(y=iris$Species,
                              p=0.7, list=FALSE)
training <- iris[inTrain,]
testing <- iris[-inTrain,]
dim(training); dim(testing)
## [1] 105   5
## [1] 45  5

Build predictions linear discriminate analysis (lda)

modlda = train(Species ~ .,data=training,method="lda")
## Loading required package: MASS
modnb = train(Species ~ ., data=training,method="nb")
plda = predict(modlda,testing); pnb = predict(modnb,testing)
table(plda,pnb)
##             pnb
## plda         setosa versicolor virginica
##   setosa         15          0         0
##   versicolor      0         17         0
##   virginica       0          1        12

Comparsion of results
see that just one value appears between the two classes appears to be not classified in the same way by the same way two algorithms but overall they perform very similarly.

equalPredictions = (plda==pnb)
qplot(Petal.Width,Sepal.Width,colour=equalPredictions,data=testing)

'MOOC > Practical Machine Learning (r programing)' 카테고리의 다른 글

Certification and Comments  (0) 2015.12.04
Week 04: Regularized Regression  (0) 2015.11.24
Week03: Boosting  (0) 2015.11.23
Week 03: Random Forests  (0) 2015.11.23
Week 03: Bagging  (0) 2015.11.19

Boosting is one of the bset box classifier


Basic Idea
Take lots of (poosibly) weak predictors

Weight them and add them up

Get a stronger predictor

Start with a set of classifiers h1,…,hk


Boosting in R
Boosting can be used with any subset of classifiers One large subclass is gradient boosting R has multiple boosting libraries. Differences include the choice of basic classification functions and combination rules. gbm - boosting with trees. mboost - model based boosting ada - statistical boosting based on additive logistic regression gamBoost for boosting generalized additive models Most of these are available in the caret package


Wage example

library(ISLR); data(Wage); library(ggplot2); library(caret);
## Loading required package: lattice
Wage <- subset(Wage,select=-c(logwage))
inTrain <- createDataPartition(y=Wage$wage,
                              p=0.7, list=FALSE)
training <- Wage[inTrain,]; testing <- Wage[-inTrain,]

#Fit the model
modFit <- train(wage ~., method="gbm",data=training,verbose=FALSE)
## Loading required package: gbm
## Loading required package: survival
## 
## Attaching package: 'survival'
## 
## The following object is masked from 'package:caret':
## 
##     cluster
## 
## Loading required package: splines
## Loading required package: parallel
## Loaded gbm 2.1.1
## Loading required package: plyr
print(modFit)
## Stochastic Gradient Boosting 
## 
## 2102 samples
##   10 predictor
## 
## No pre-processing
## Resampling: Bootstrapped (25 reps) 
## Summary of sample sizes: 2102, 2102, 2102, 2102, 2102, 2102, ... 
## Resampling results across tuning parameters:
## 
##   interaction.depth  n.trees  RMSE      Rsquared   RMSE SD   Rsquared SD
##   1                   50      35.15759  0.3038776  1.530055  0.02487676 
##   1                  100      34.62096  0.3137957  1.439743  0.02232634 
##   1                  150      34.55009  0.3156775  1.394560  0.02166566 
##   2                   50      34.60094  0.3156275  1.455682  0.02485196 
##   2                  100      34.47184  0.3182034  1.374485  0.02300061 
##   2                  150      34.54167  0.3162264  1.387161  0.02253147 
##   3                   50      34.47797  0.3187507  1.440898  0.02512358 
##   3                  100      34.59459  0.3142979  1.374172  0.02372285 
##   3                  150      34.82958  0.3071383  1.363458  0.02276088 
## 
## Tuning parameter 'shrinkage' was held constant at a value of 0.1
## 
## Tuning parameter 'n.minobsinnode' was held constant at a value of 10
## RMSE was used to select the optimal model using  the smallest value.
## The final values used for the model were n.trees = 100,
##  interaction.depth = 2, shrinkage = 0.1 and n.minobsinnode = 10.
qplot(predict(modFit,testing),wage,data=testing)

'MOOC > Practical Machine Learning (r programing)' 카테고리의 다른 글

Week 04: Regularized Regression  (0) 2015.11.24
Week03: Model based prediction  (0) 2015.11.23
Week 03: Random Forests  (0) 2015.11.23
Week 03: Bagging  (0) 2015.11.19
Week 03: Predicting with trees  (1) 2015.11.19

Random Forest

특징
Bootstrap sample
At each split, bootstrap varaibles
Grow multiple trees and vote

Pros:
Accuracy
그래서 Kagger 대회에서 많이 쓰인다고 한다.

Cons:
느린 트레이닝 시간
해석의 어려움
Overfitting
엄청나게 큰 트리를 만든다. 그리고 각각의 트리는 bootstrapping sample에 의존하게 된다.

각각의 트리에서 약간의 서로다름 때문에 약간의 다른 결과를 각각 얻게 된다.

그다음 모든 결과를 평균화 하게 된다. 그렇게 함으로써 각각의 class에대한 확률 값을 얻게 된다.

어떻게 동작하는지 아래의 에제를 통해서 확인해 보자.

Iris data

data(iris); library(ggplot2); library(caret)
## Loading required package: lattice
inTrain <- createDataPartition(y=iris$Species,
                              p=0.7, list=FALSE)
training <- iris[inTrain,]
testing <- iris[-inTrain,]

Random Forest를 수행한다. 예측할 class 값은 species이고 그것을 위해서 사용되는 feature들은 모든 것들이다.

modFit <- train(Species~ .,data=training,method="rf",prox=TRUE)
## Loading required package: randomForest
## randomForest 4.6-12
## Type rfNews() to see new features/changes/bug fixes.
modFit
## Random Forest 
## 
## 105 samples
##   4 predictor
##   3 classes: 'setosa', 'versicolor', 'virginica' 
## 
## No pre-processing
## Resampling: Bootstrapped (25 reps) 
## Summary of sample sizes: 105, 105, 105, 105, 105, 105, ... 
## Resampling results across tuning parameters:
## 
##   mtry  Accuracy   Kappa      Accuracy SD  Kappa SD  
##   2     0.9517675  0.9265018  0.02291581   0.03478529
##   3     0.9528615  0.9280510  0.02219341   0.03404748
##   4     0.9519080  0.9265991  0.02369344   0.03623696
## 
## Accuracy was used to select the optimal model using  the largest value.
## The final value used for the model was mtry = 3.

총 25번의 bootstrap sampling을 한것을 알 수 있다.

Getting a single tree tree의 모습을 살펴보면 아래와 같다. k=2라고 주면 second tree를 보겠다는 의미이다.

getTree(modFit$finalModel,k=2)
##   left daughter right daughter split var split point status prediction
## 1             2              3         4        0.80      1          0
## 2             0              0         0        0.00     -1          1
## 3             4              5         3        5.05      1          0
## 4             6              7         4        1.75      1          0
## 5             0              0         0        0.00     -1          3
## 6             0              0         0        0.00     -1          2
## 7             8              9         3        4.85      1          0
## 8             0              0         0        0.00     -1          2
## 9             0              0         0        0.00     -1          3

각각의 은 particular split를 의미한다.

Class “centers”

irisP <- classCenter(training[,c(3,4)], training$Species, modFit$finalModel$prox)
irisP <- as.data.frame(irisP); irisP$Species <- rownames(irisP)
p <- qplot(Petal.Width, Petal.Length, col=Species,data=training)
p + geom_point(aes(x=Petal.Width,y=Petal.Length,col=Species),size=5,shape=4,data=irisP)

Predicting nw values we just missed two values with random forest model. Overally, it is highly accurate in the prediction.

pred <- predict(modFit,testing); testing$predRight <- pred==testing$Species
table(pred,testing$Species)
##             
## pred         setosa versicolor virginica
##   setosa         15          0         0
##   versicolor      0         14         2
##   virginica       0          1        13

We can then look and see which of the two that I missed.

qplot(Petal.Width,Petal.Length,colour=predRight,data=testing,main="newdata Predictions")

 After making a model, we should check where our prediction is doing well and where our prediction is doing poorly.

Summary

Random Forests Alogirhtm is top performing method along with bootsting.

They are often dificult to interpret beacuse of these multiple tress that we are ftting but they can be very accurate for a wide range of problems.


'MOOC > Practical Machine Learning (r programing)' 카테고리의 다른 글

Week03: Model based prediction  (0) 2015.11.23
Week03: Boosting  (0) 2015.11.23
Week 03: Bagging  (0) 2015.11.19
Week 03: Predicting with trees  (1) 2015.11.19
Week 02: Predicting with Regression Multiple Covariates  (0) 2015.11.16

Week 03: Bagging


bootstrap aggregating의 short name이다.


어떤 복잡한 모델을 생성할때 여러번 겹쳐서 평균을 낸다면


bias와 variance를 동시에 캡쳐할 수 있다.


기본 아이디어

리샘플해서 모델을 만들고 리프리덱션해서 정확도를 계산해서

그것의 평균을 구하게 된다.

리샘플의 방법은 bootstrapping을 따르는 복원추출을 이용한다.


특징

비슷한 bias를 계속해서 누적하며

하지만 variance를 줄이는 효과가 있다.

이것은 non-linear function을 쓸때 가장 유용하다.



예제: Ozone data

install.packages("ElemStatLearn")
library(ElemStatLearn); data(ozone,package="ElemStatLearn")
ozone <- ozone[order(ozone$ozone),]
head(ozone)
    ozone radiation temperature wind
17      1         8          59  9.7
19      4        25          61  9.7
14      6        78          57 18.4
45      7        48          80 14.3
106     7        49          69 10.3
7       8        19          61 20.1

오존으로 정렬한것이다.

하려고하는것은 temperature를 ozone function으로 예측할려고 하는 것이다.


이제 수작업으로 bagging을 수행해보자.

10 by 155 짜리 matrix를 생성 한다.


10번동안 resampleling을 해서 데이터셋을 만들고

그것으로 smooth curve를 loess 함수를 이용해서 만들고

이것으로 prediction하고

평균을 구하게 된다.

ll <- matrix(NA,nrow=10,ncol=155)
for(i in 1:10){ #10번을 반복 수행함
    ss <- sample(1:dim(ozone)[1],replace=T) #복원 추출을 수행 한다.
    ozone0 <- ozone[ss,]; ozone0 <- ozone0[order(ozone0$ozone),] #데이터를 추출하고 ozone으로 정렬 한다
    loess0 <- loess(temperature ~ ozone,data=ozone0,span=0.2) # loess를 이용해서 예측 모델을 생성 한다.
    ll[i,] <- predict(loess0,newdata=data.frame(ozone=1:155)) 
    # 예측 모델을 이용해서 1~155사이의 오존을 예측한다. 
    #실제 오존은 168번까지 있다. 이것은 순차적이지 않으며, 중간 중가 결측값(NA)도 존재한다.
}

그리고 실제 Ozone과 temperature에 대한 것을 검은색 점으로 표현하고

예측한 값들을 선으로 연결해서 10개를 그리고

그 10개의 예측값을 편균으로해서 빨간색 선으로 그리면 아래와 같은 그래프를 얻을 수 있다.

plot(ozone$ozone,ozone$temperature,pch=19,cex=0.5)
for(i in 1:10){lines(1:155,ll[i,],col="grey",lwd=2)}
lines(1:155,apply(ll,2,mean),col="red",lwd=2)

위와 같이 bias는 높지만 변동은 더 줄어든 것을 볼 수 있다.



정리

bagging은 nonlinear model들에서 많이 사용된다.

tree에서 많이 사용된다. 이것을 확장한 것이 random forests 이다.


기억할것은 bagging이란 결국

데이터를 복원주출로 샘플링 한다음 비선형모델로 생성을 하고

그렇게 생성한 여러개의 모델을 평균화해서 좀더 variance(분산)이적은 부드러운 모델을 생성하는 것이다.

이러한 부드러운 모델은 각각 데이터 셋으로 모델링 했을 때는 나오기 어려운 것들이다. 즉 상대적으로 변동이 적은 그러나 bias는 높은 모델을 생성 하는 것이다. 그것이 bagging 이다.











Week 03: Predicting with Trees


이론적인 내용은 이전 포스트를 참조 한다.


Tree 방식의 Classification의 장단점은 아래와 같다.

Pros:

쉬운 이해

비선형 데이터에 대한 좋은 성능

Cons:

pruning이나 cross-validation을 하지 않으면 over-fitting의 문제가 발생함.

linear regression model같은 것들보다 불확실한 데이터 즉 트레이닝에서 발견되지 않았던 많이 다른 데이터를

추정하기아 어렵다.

결과가가 항상 특정 tree를 구성하는 node 값에의해서 결정되므로 트리에 구조에따라서 결과가 자주 변한다.



예제는 아래와 같다.

2010년 미국 대통령 선거당시 힐러리 클린턴과 버락 오바에 대한 것이다.

각각의 질의에 따라 어떻게 투표 결과가 이뤄 질지에대한 예측을 나타내는 트리이다.



예제: Iris Data


해당 코드는 caret package를 이용하며 해당 package의 party, rpart 방식을 이용해서 tree를 구성한 것이다.

다른 package로는 tree package가 존재 한다.


데이터를 불러온다.

data(iris); library(ggplot2)
names(iris)
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"

각 테이블의 양을 파악한다

table(iris$Species)
    setosa versicolor  virginica 
        50         50         50 

트레이닝 데이터와 테스트 데이터를 분할 한다.

inTrain <- createDataPartition(y=iris$Species,
                               p=0.7, list=FALSE)
training <- iris[inTrain,]
testing <- iris[-inTrain,]
dim(training); dim(testing)
[1] 251   5
[1] 33  5

그래프를 그려서 세개의 분포를 확인해 보자.

qplot(Petal.Width,Sepal.Width,colour=Species,data=training)

아래와 같이 세개의 종들이 나름 극명하게 나뉘는 것을 알 수 있다. 


이제 caret package를 이용해서 모델을 학습해서 수행해 보자.

~,의 의미는 모든 variables를 species를 prediction하기위해서 사용하겠다는 것이다.

library(caret)
modFit <- train(Species ~ .,method="rpart",data=training)
print(modFit$finalModel)
n= 117 
node), split, n, loss, yval, (yprob)
      * denotes terminal node

1) root 117 76 virginica (0.34188034 0.30769231 0.35042735)  
  2) Petal.Length< 2.45 40  0 setosa (1.00000000 0.00000000 0.00000000) *
  3) Petal.Length>=2.45 77 36 virginica (0.00000000 0.46753247 0.53246753)  
    6) Petal.Width< 1.75 40  5 versicolor (0.00000000 0.87500000 0.12500000) *
    7) Petal.Width>=1.75 37  1 virginica (0.00000000 0.02702703 0.97297297) *


모델을 그래프로 표현한다. 좀 더 명확히 보기위해서 rattle package를 이용해서 그린다.

아래의 그림은 일반 plot()이용해서 그린 그래프 이다.

library(rattle)
fancyRpartPlot(modFit$finalModel)
#draw plot using nomal plot
plot(modFit$finalModel, uniform=TRUE, 
     main="Classification Tree")
text(modFit$finalModel, use.n=TRUE, all=TRUE, cex=.8)



fancyRpartPlot으로 그리면 아래와 같다.



normal plot으로 그리면 아래와 같다.


생성된 tree 모델을 이용해서 예측을 수행 한다.

predict(modFit,newdata=testing)
 [1] setosa     setosa     setosa     setosa     setosa    
 [6] setosa     setosa     setosa     setosa     setosa    
[11] versicolor versicolor versicolor versicolor versicolor
[16] versicolor versicolor versicolor versicolor versicolor
[21] versicolor versicolor versicolor versicolor virginica 
[26] virginica  virginica  virginica  virginica  virginica 
[31] virginica  virginica  virginica 
Levels: setosa versicolor virginica



Week 02: Predicting with Regression Multiple Covariates



  • Caret package
  • Data slicing
  • Training options
  • Plotting predictions
  • Basic preprocessing
  • Covariate creation
  • Preprocessing with principal components analysis
  • Predicting with Regression
  • Predicting with Regression Multiple Covariates



Predicting with Regression Multiple Covariates


다루는 내용은 두가지로,

첫 번째는 mutiple covariates를 이용해서 regression model을 생성하는 방법을 다루며,

두 번째는 mutiple covariates들 중에서 무엇을 선택해야하는지를 알아내는 방법이다.



Example: Predicting Wage



# wage data
library(ISLR); library(ggplot2); library(caret);
data(Wage); Wage <- subset(Wage,select=-c(logwage))
summary(Wage)

# get training / test set
inTrain <- createDataPartition(y=Wage$wage,
                               p=0.7, list=FALSE)
training <- Wage[inTrain,]; testing <- Wage[-inTrain,]
dim(training); dim(testing)

# feature plot to know how those are related to each other
featurePlot(x=training[,c("age","education","jobclass")],
            y = training$wage,
            plot="pairs")

# plot age versus wage
qplot(age,wage,data=training)

# to figure out the reason to make outlier
# color point by jobclass, most of point are blue.
qplot(age,wage,colour=jobclass,data=training)

# color education
# also explaine, advanced degree is outlier
qplot(age,wage,colour=education,data=training)

# fit a linear model
modFit<- train(wage ~ age + jobclass + education,
               method = "lm",data=training)
finMod <- modFit$finalModel
print(modFit)

plot(finMod,1,pch=19,cex=0.5,col="#00000010")
qplot(finMod$fitted,finMod$residuals,colour=race,data=training)
plot(finMod$residuals,pch=19)

# predicted versus truth in test set
pred <- predict(modFit, testing)
qplot(wage,pred,colour=year,data=testing)

# all covariates
modFitAll<- train(wage ~ .,data=training,method="lm")
pred <- predict(modFitAll, testing)
qplot(wage,pred,data=testing)








Week 02: Predicting with Regression


  • Caret package
  • Data slicing
  • Training options
  • Plotting predictions
  • Basic preprocessing
  • Covariate creation
  • Preprocessing with principal components analysis
  • Predicting with Regression
  • Predicting with Regression Multiple Covariates



Predicting with Regression


선형적이면 구현하기 쉽고 이해가 쉽다.

하지만 비선형이면 정확도가 너무 떨어진다.


Example: old faithful eruptions

# ppredicting with regression
library(caret);data(faithful); set.seed(333)
inTrain <- createDataPartition(y=faithful$waiting,
                               p=0.5, list=FALSE)
trainFaith <- faithful[inTrain,]; testFaith <- faithful[-inTrain,]
head(trainFaith)

  eruptions waiting
1     3.600      79
3     3.333      74
5     4.533      85
6     2.883      55
7     4.700      88
8     3.600      85
# showing graph
plot(trainFaith$waiting,trainFaith$eruptions,pch=19,col="blue",xlab="Waiting",ylab="Duration")

데이터가 선형이므로 Linear Regression을 적용하면 좋다.


# making model
lm1 <- lm(eruptions ~ waiting,data=trainFaith)
summary(lm1)
Call:
lm(formula = eruptions ~ waiting, data = trainFaith)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.26990 -0.34789  0.03979  0.36589  1.05020 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.792739   0.227869  -7.867 1.04e-12 ***
waiting      0.073901   0.003148  23.474  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.495 on 135 degrees of freedom
Multiple R-squared:  0.8032,	Adjusted R-squared:  0.8018 
F-statistic:   551 on 1 and 135 DF,  p-value: < 2.2e-16
# model fit
plot(trainFaith$waiting,trainFaith$eruptions,pch=19,col="blue",xlab="Waiting",ylab="Duration")
lines(trainFaith$waiting,lm1$fitted,lwd=3)

만들어진 모델을 확인한다.

그리고 값을 prediction을 해보면 아래와 같다.

# predict a new value
coef(lm1)[1] + coef(lm1)[2]*80
(Intercept) 
   4.119307 
newdata <- data.frame(waiting=80)
predict(lm1,newdata)
       1 
4.119307 

테스트와 트레이이닝에 대해서 각각 그려보면 아래와 같다.

# plot predictions - training and test
par(mfrow=c(1,2))
plot(trainFaith$waiting,trainFaith$eruptions,pch=19,col="blue",xlab="Waiting",ylab="Duration")
lines(trainFaith$waiting,predict(lm1),lwd=3)
plot(testFaith$waiting,testFaith$eruptions,pch=19,col="blue",xlab="Waiting",ylab="Duration")
lines(testFaith$waiting,predict(lm1,newdata=testFaith),lwd=3)

각각의 모델의 에러를 계산해보면 아래와 같다. 계산 방식은 RMSE를 이용하며 트레이닝과 테스트에 대해서 각각 수행 했다.

> # Calculate RMSE on training
> sqrt(sum((lm1$fitted-trainFaith$eruptions)^2))
[1] 5.75186
> # Calculate RMSE on test
> sqrt(sum((predict(lm1,newdata=testFaith)-testFaith$eruptions)^2))
[1] 5.838559


이러한 구현을 caret을 이용해서 할경우 매우 쉽게 할 수 있다.

> #same process with caret
> modFit <- train(eruptions ~ waiting,data=trainFaith,method="lm")
> summary(modFit$finalModel)

Call:
lm(formula = .outcome ~ ., data = dat)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.26990 -0.34789  0.03979  0.36589  1.05020 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.792739   0.227869  -7.867 1.04e-12 ***
waiting      0.073901   0.003148  23.474  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.495 on 135 degrees of freedom
Multiple R-squared:  0.8032,	Adjusted R-squared:  0.8018 
F-statistic:   551 on 1 and 135 DF,  p-value: < 2.2e-16





Week02: Covariate creation, Pre-processing with principal components analysis


  • Caret package
  • Data slicing
  • Training options
  • Plotting predictions
  • Basic preprocessing
  • Covariate creation
  • Preprocessing with principal components analysis
  • Predicting with Regression
  • Predicting with Regression Multiple Covariates


Covariate creation


covariates are sometimes called predictors and features


There are two levels of covariate creation, or feature creation


Level 1: From raw data to covariate

raw data takes the form of an image, text file, or a website.


That kind of information is very hard to build a predictive model around when you haven't summarized the information in some useful way in to either a quantitative or qualitative variable.


e-mail 내용이 아래와 같이 있다고 하자.


그냥 저 이메일을 처리할 수는 없기 때문에 2개의 feature를 끌어 낸다.

captialAve는 당연히 모두 대문자이므로 100% = 1 이다.

particular word frequency를 고려하는데, you가 있을 수 있다. 2이다.

number of dollar 의 경우 8개이다.


Level 2: Transforming tidy covariates

sqaure를 한다.



Level 1, Raw data -> covariates

Depends heavily on application

The balancing act is summarization vs. information loss

Examples:

Text files: frequency of words, frequency of phrases (Google ngrams), frequency of capital letters.

Images: Edges, corners, blobs, ridges (computer vision feature detection))

Webpages: Number and type of images, position of elements, colors, videos (A/B Testing)

People: Height, weight, hair color, sex, country of origin.

The more knowledge of the system you have the better the job you will do.

When in doubt, err on the side of more features

Can be automated, but use caution!


Level 2, Tidy covariates -> new covariates

More necessary for some methods (regression, svms) than for others (classification trees).

Should be done only on the training set

The best approach is through exploratory analysis (plotting/tables)

New covariates should be added to data frames



dummy variable


removing zero covariates


Spline basis

# spline basis
#data
library(ISLR); library(caret); data(Wage);
inTrain <- createDataPartition(y=Wage$wage,
                               p=0.7, list=FALSE)
training <- Wage[inTrain,]; testing <- Wage[-inTrain,]

library(splines)
bsBasis <- bs(training$age,df=3) 
bsBasis
#linear model
lm1 <- lm(wage ~ bsBasis,data=training)
plot(training$age,training$wage,pch=19,cex=0.5)
points(training$age,predict(lm1,newdata=training),col="red",pch=19,cex=0.5)



Notes and further reading

Level 1 feature creation (raw data to covariates)
Science is key. Google "feature extraction for [data type]"
Err on overcreation of features
In some applications (images, voices) automated feature creation is possible/necessary
http://www.cs.nyu.edu/~yann/talks/lecun-ranzato-icml2013.pdf
Level 2 feature creation (covariates to new covariates)
The function preProcess in caret will handle some preprocessing.
Create new covariates if you think they will improve fit
Use exploratory analysis on the training set for creating them
Be careful about overfitting!
preprocessing with caret
If you want to fit spline models, use the gam method in the caret package which allows smoothing of multiple variables.
More on feature creation/data tidying in the Obtaining Data course from the Data Science course 



Pre-processing with principal components analysis (PCA)


quantitative variable이 많이 존재 한다면,

대부분의 variable들이 비슷비슷하고 서로 밀접한 관계가 있다면
모든 variable들을 쓸 때 없이 model 생성에 포함 시킬 필요는 없다.

상관관계(correlation)을 이용해서 연관도가 높은 feature들을 알아내는 방법
# Correlated predictors
library(caret); library(kernlab); data(spam)
inTrain <- createDataPartition(y=spam$type,
                               p=0.75, list=FALSE)
training <- spam[inTrain,]
testing <- spam[-inTrain,]

M <- abs(cor(training[,-58]))
diag(M) <- 0
which(M > 0.8,arr.ind=T)
       row col
num415  34  32
direct  40  32
num857  32  34
direct  40  34
num857  32  40
num415  34  40

cor() 함수를 이용해서 각 feature들 간의 상관 관계를 구하게 된다. -1 <= x <=1 사이의 값을 가지게 된다.
그다음 절대값을 얻게된다.

그렇게해서 높은 correlation을 가지는, 높은 유사도를 서로서로 가지는 feature들의 쌍을 얻어내고 싶은 것이다.
모든 feature들은 자기 자신에 대해서는 1의 correlation을 가지고 있다.
이런것들은 의미가 없으므로,

diag(M) <- 0 으로 설정한다.

그다음 which() 함수를 이용해서 M > 0.8 이사으이 상관관계(correlation)을 가지는 것들에 대해서,
array type의 mattrix로 다가 표시하게 되나.

결과는 num415num857이다.
두개는 phone number이기 때문에 유사하다고 메시지가 나오는 것이다.

이것을 그래프를 그려보면 아래와 같다.
# drawing graph
names(spam)[c(34,32)]
plot(spam[,34],spam[,32])

두개의 correlation은 높았으니 그래프를 그려서 추가로 분석해 본다.

거의 대충형 선에 근접하는것을 알 수 있다.


이것을 통해서 두개의 feature들을 모두 모델에 포함하는 것은 그렇게 좋은 생각이 아니라는것을 알 수 있다.



Basic PCA idea

단하나의 variable이 더 유용할 것이라는 것을 어떻게 알 수 있을까?


We might not need every predictor

A weighted combination of predictors might be better

We should pick this combination to capture the "most information" possible

Benefits

- Reduced number of predictors

- Reduced noise (due to averaging)




plot을 회전 시킨다.
x는 두개의 변수를 더하고
y는 두개의 변수를 뺀다.
# we could rotate the plot
X <- 0.71*training$num415 + 0.71*training$num857
Y <- 0.71*training$num415 - 0.71*training$num857
plot(X,Y)

위와 같은 결과를 얻을 수 있다. X값들은 넓게 퍼져 있다.

하지만 y의 경우 대부분 0에 모여 있는것을 알 수 있다.



2개 이상의 variable에 적용하기 위해서 PCA 함수를 이용하는것이 좋다.

#PCA
smallSpam <- spam[,c(34,32)]
prComp <- prcomp(smallSpam)
plot(prComp$x[,1],prComp$x[,2])




















Week 02: Basic preprocessing


  • Caret package
  • Data slicing
  • Training options
  • Plotting predictions
  • Basic preprocessing
  • Covariate creation
  • Preprocessing with principal components analysis
  • Predicting with Regression
  • Predicting with Regression Multiple Covariates



Basic pre-processing 


어떤 머신러닝 알고리즘을 적용하던지간에 anomaly value를 제거하는 것은 중요하다.

그래프를 그리던지해서 noise 제거하는것은 정확히 해당 데이터로 부터 right signal을 추출해서 모델을 생성하도록 돕기

때문에 정확도 항샹에 큰 영향을 미치게 된다.


아래와 같은 spam 데이터 예제에대해서 일부만 빈도가 높을 수도 있다. 이러면 문제가 발생한다.

library(caret); library(kernlab); data(spam)

inTrain <- createDataPartition(y=spam$type,

                               p=0.75, list=FALSE)

training <- spam[inTrain,]

testing <- spam[-inTrain,]

hist(training$capitalAve,main="",xlab="ave. capital run length")


평균과 표준편차를 계산해 보면 아래와 같다.

> mean(training$capitalAve)

[1] 4.844242

> sd(training$capitalAve)

[1] 27.37255



1.1 standardizing - manual


$$E(X)=m,\quad \sigma (X)=\sigma,\quad Z=\frac { X-m }{ \sigma  }$$라두면, 평균과 표준편차의 성질을 이용하여 아래와 같이 전개 된다.

$$E(Z)=E\left( \frac { X-m }{ \sigma  }  \right) =E=\left( \frac { 1 }{ \sigma  } X-\frac { m }{ \sigma  }  \right) =\frac { 1 }{ \sigma  } E(X)-\frac { m }{ \sigma  } =0$$ 

$$\sigma(Z)=\sigma\left( \frac { X-m }{ \sigma  }  \right) =\sigma=\left( \frac { 1 }{ \sigma  } X-\frac { m }{ \sigma  }  \right) =\frac { 1 }{ \sigma  } \sigma(X)=1$$


이것을 training set에 대해서 표준화(standardizing)을 수행하면 아래와 같은 결과를 얻을 수 있다.

> #Standardizing
> trainCapAve <- training$capitalAve
> trainCapAveS <- (trainCapAve  - mean(trainCapAve))/sd(trainCapAve) 
> mean(trainCapAveS)
[1] -5.008709e-18
> sd(trainCapAveS)
[1] 1


test set에 standardizing을 적용할 때에 test set에 대한 mean과 sd를 적용하는 것이 아닌,

training set에서의 mean과 sd 값을 적용 해야 한다. 

> #standardizing - test set
> testCapAve <- testing$capitalAve
> testCapAveS <- (testCapAve  - mean(trainCapAve))/sd(trainCapAve) 
> mean(testCapAveS)
[1] 0.04085023
> sd(testCapAveS)
[1] 1.131577

당연히 mean과 sd는 0과 1이 아니다. 하지만 그것에 근접한 값이 나오기를 바랄 뿐이다.


1.2 standardizing - using preProcess in caret package


Pre-processing transformation (centering, scaling etc.) can be estimated from the training data and applied to any data set with the same variables.

preObj <- preProcess(training[,-58],method=c("center","scale"))
trainCapAveS <- predict(preObj,training[,-58])$capitalAve
mean(trainCapAveS)
[1] -5.008709e-18
> sd(trainCapAveS)
[1] 1

여기서 58번째 컬럼을 제거하는 이유는 해당 컬럼만 numeric이 아닌 factor type 이기 때문이다.

method=c("center","scale")의 의미는 아래와 같다.

method = "center" subtracts the mean of the predictor's data (again from the data in x) from the predictor values while method = "scale" divides by the standard deviation.


이전과 같이 거의 zero에 가까운 mean과 1의 sd를 얻을 수 있다.


test set의 경우 당연히 training set의 preObj을 사용해서 처리 해야한다.

> testCapAveS <- predict(preObj,testing[,-58])$capitalAve
> mean(testCapAveS)
[1] 0.04085023
> sd(testCapAveS)
[1] 1.131577


1.3 standardizing - preProcess argument

train function에서 argument로써 수행 할 수 있다.

> set.seed(32343)
> modelFit <- train(type ~.,data=training,
+                   preProcess=c("center","scale"),method="glm")
There were 27 warnings (use warnings() to see them)
> modelFit
Generalized Linear Model 

3451 samples
  57 predictor
   2 classes: 'nonspam', 'spam' 

Pre-processing: centered (57), scaled (57) 
Resampling: Bootstrapped (25 reps) 
Summary of sample sizes: 3451, 3451, 3451, 3451, 3451, 3451, ... 
Resampling results

  Accuracy   Kappa     Accuracy SD  Kappa SD 
  0.9201069  0.832212  0.01353308   0.0260575


2. Standardizing - Box-Cox transforms

새로운 standardizing 방법이 있다.

center, scale 방법은 익스트림 값을 제거하는 스타일의 방법이다.


하지만 여기서 소개하는 box-cox 방식은 normal data 처럼 만들어주는 standardizing 방법이다.

# Standardizing box cox transforms
preObj <- preProcess(training[,-58],method=c("BoxCox"))
trainCapAveS <- predict(preObj,training[,-58])$capitalAve
par(mfrow=c(1,2)); hist(trainCapAveS); qqnorm(trainCapAveS)

오른쪽은 이전에 standardizing을 수행하지 않고 histogram을 그린것이다. 보는것과 같이 특정 구간에만 빈도가 몰린것을 알 수 있다. 하지만 box-cox를 적용한다음에는 분포가 고른것을 볼 수 있다. 



 



Q-Q plot을 통해서 해당 standardizing이 얼마만큼 normal distribution과 일치 하는지를 알 수 있다.

변위치(Quantiles) 0에 많은 데이터가 분포하므로 완벽히 45도 기울기의 일직선이 아느므로 완벽하지는 않다. 하지만 거의 유사하다. 



3. Standardizing - Imputing data


missing data를 처리하기 위한 전처리 방법이다. NA(missing data), 결측치가 있을경우 대부분의 통계 함수들이나 prediction algorithm들은 동작 자체를 하지 않는다. 따라서 반드시 처리해줘야하는 것들 중 하나이다.


이때 이러한 missing data를 impute(덮어씌우기)하는 알고리즘들을 배워보자.

k-nearest neighbor's imputation이 쉬운 방법중 하나이다.


코드는 아래와 같다.

#standardizing - imputing data
set.seed(13343)

# Make some values NA
training$capAve <- training$capitalAve
selectNA <- rbinom(dim(training)[1],size=1,prob=0.05)==1
training$capAve[selectNA] <- NA

# Impute and standardize
preObj <- preProcess(training[,-58],method="knnImpute")
capAve <- predict(preObj,training[,-58])$capAve

# Standardize true values
capAveTruth <- training$capitalAve
capAveTruth <- (capAveTruth-mean(capAveTruth))/sd(capAveTruth)

결과는 아래와 같다.

> quantile(capAve - capAveTruth)
           0%           25%           50%           75%          100% 
-3.5036289018 -0.0005761963  0.0006479362  0.0011937179  0.1832545934 
> quantile((capAve - capAveTruth)[selectNA])
           0%           25%           50%           75%          100% 
-3.5036289018 -0.0175633552  0.0009851735  0.0159918619  0.1832545934 
> quantile((capAve - capAveTruth)[!selectNA])
           0%           25%           50%           75%          100% 
-0.8523414202 -0.0004922746  0.0006475486  0.0011696849  0.0016053800 


Notes and future reading

Training and test must be processed in the same way

Test transformations will likely be imperfect

Especially if the test/training sets collected at different times

Careful when transforming factor variables!



더 읽어볼 거리

preprocessing-caret: http://topepo.github.io/caret/preprocess.html




Week 02: Training options, Plotting predictions



  • Caret package
  • Data slicing
  • Training options
  • Plotting predictions
  • Basic peprocessing
  • Covariate creation
  • Preprocessing with principal components analysis
  • Predicting with Regression
  • Predicting with Regression Multiple Covariates


Training options



이전에 트레이닝 옵션을 설정 했었다.

inTrain <- createDataPartition(y=spam$type, 
                               p=0.75, list=FALSE)
training <- spam[inTrain,]
testing <- spam[-inTrain,]
modelFit <- train(type ~., data=training, method="glm")

하지만 많은 training option들이 존재한다.

> args(train.default)

function (x, y, method = "rf", preProcess = NULL, ..., weights = NULL
    metric = ifelse(is.factor(y), "Accuracy", "RMSE"), maximize = ifelse(metric %in% 
        c("RMSE", "logLoss"), FALSE, TRUE), trControl = trainControl(), 
    tuneGrid = NULL, tuneLength = 3) 
NULL

preProcess에 관한 내용.
unbalance한 data sample이 있을경우 weight 값을 조정 할 수도 있다.

metric = ifelse(is.factor(y), "Accuracy""RMSE") 이부분은 categorical data의 경우 해당 데이터를 이용한 모델이
maximized accuracy 일때까지 트레이닝을 수행하고
만약 continuous data의 경우 RMSE가 Maximized 될 때 까지 수행하게 된다.
trainControl도 설정 할 수 있다.

■ Metric options
Continuous outcomes:
  • RMSE = Root mean squared error
  • RSquared = $R^2$ from regression models

Categorical outcomes:
  • Accuracy = Fraction correct
  • Kappa = A measure of concordance

■ trainControl

> args(trainControl)


function (method = "boot", number = ifelse(grepl("cv", method), 
    10, 25), repeats = ifelse(grepl("cv", method), 1, number), 
    p = 0.75, search = "grid", initialWindow = NULL, horizon = 1, 
    fixedWindow = TRUE, verboseIter = FALSE, returnData = TRUE, 
    returnResamp = "final", savePredictions = FALSE, classProbs = FALSE, 
    summaryFunction = defaultSummary, selectionFunction = "best", 
    preProcOptions = list(thresh = 0.95, ICAcomp = 3, k = 5), 
    sampling = NULL, index = NULL, indexOut = NULL, timingSamps = 0, 
    predictionBounds = rep(FALSE, 2), seeds = NA, adaptive = list(min = 5, 
        alpha = 0.05, method = "gls", complete = TRUE), trim = FALSE, 
    allowParallel = TRUE) 
NULL

trainControl resampling

method
- boot = bootstrapping
- boot632 = bootstrapping with adjustment
- cv = cross validation
- repeatedcv = repeated cross validation
- LOOCV = leave one out cross validation

number
- For boot/cross validation
- Number of subsamples to take

repeats
- Number of times to repeate sub-sampling
- If big this can slow things down

Setting the seed
It is often useful to set an overall seed
You can also set a seed for each resmaple
seeding each resample is useful for parallel fits

더 읽어볼 거리




Plotting predictions

머신 러닝 알고리즘을 적용하기 전에 우선적으로 데이터의 특성에 대해서 파악을 해야 한다.

데이터 특성을 파악하기 좋은 방법은 Graph를 그려서 그것을 확인 하는 것이다.

사용할 데이터는 임금에 대한 데이터를 사용 한다.
predicting wages
library(ISLR); library(ggplot2); library(caret);
data(Wage)
summary(Wage)
데이터 결과는 아래와 같다.
      year           age               sex                    maritl    
 Min.   :2003   Min.   :18.00   1. Male  :3000   1. Never Married: 648  
 1st Qu.:2004   1st Qu.:33.75   2. Female:   0   2. Married      :2074  
 Median :2006   Median :42.00                    3. Widowed      :  19  
 Mean   :2006   Mean   :42.41                    4. Divorced     : 204  
 3rd Qu.:2008   3rd Qu.:51.00                    5. Separated    :  55  
 Max.   :2009   Max.   :80.00                                           
                                                                        
       race                   education                     region    
 1. White:2480   1. < HS Grad      :268   2. Middle Atlantic   :3000  
 2. Black: 293   2. HS Grad        :971   1. New England       :   0  
 3. Asian: 190   3. Some College   :650   3. East North Central:   0  
 4. Other:  37   4. College Grad   :685   4. West North Central:   0  
                 5. Advanced Degree:426   5. South Atlantic    :   0  
                                          6. East South Central:   0  
                                          (Other)              :   0  
           jobclass               health      health_ins      logwage     
 1. Industrial :1544   1. <=Good     : 858   1. Yes:2083   Min.   :3.000  
 2. Information:1456   2. >=Very Good:2142   2. No : 917   1st Qu.:4.447  
                                                           Median :4.653  
                                                           Mean   :4.654  
                                                           3rd Qu.:4.857  
                                                           Max.   :5.763  
                                                                          
      wage       
 Min.   : 20.09  
 1st Qu.: 85.38  
 Median :104.92  
 Mean   :111.70  
 3rd Qu.:128.68  
 Max.   :318.34  

위의 것을 그래프로 그려보자.

featurePlot()은 caret package에 있는 것이다.

Wrapper for Lattice Plotting of Predictor Variables

#drawing Feautre plot
featurePlot(x = training[,c("age","education","jobclass")],
            y = training$wage,
            plot="pairs")

재미있는 그래프 이다. wage에 대해서 즉 y값에 대해서 age, education, jobclass와의 관계를 한눈에 볼 수 있다.

다소 복잡해 보이지만 찬찬히 보면 한눈에 들어오는것을 알 수 있다.









Week 02: Caret package, data slicing


  • Caret package
  • Data slicing
  • Training options
  • Plotting predictions
  • Basic peprocessing
  • Covariate creation
  • Preprocessing with principal components analysis
  • Predicting with Regression
  • Predicting with Regression Multiple Covariates


caret package


해당 페키지는 R에서 Machine Learning을 수행하도록 도와주는 많은 package들 중의 하나이다.

하지만 여타 package들과 다르게 간편하고 강력하다는 장점이 있다.




■ caret의 기능들


1) 프리프로세싱 (데이터 클린)

2) 데이터 분할

createDataPartition

createResample

createTimeSlices

3) 트레이닝과 테스트 함수

train

predict

4) 생성한 모델들간의 비교

confusionMatrix



caret에서 지원하는 Machine Learning Algorithms

  • Linear discriminant analysis 

  • Regression

  • Naive Bayes

  • Support vector machines

  • Classificiation and Regression tree

  • Random forests
  • Boosting
  • etc.


왜 caret 인가? 수많은 machine learning 구현 package들 중에서


caret이 설정해서 사용하기 제일 편하다.

아래의 표처럼 각각의 페키지들은 서로다른 알고리즘을 사용할 때 마다 설정을 재각각 다르게 해줘야 한다.




다시보는 SPAM 예제


Data Splitting 

library(caret)

library(kernlab)

data(spam)


inTrain <- createDataPartition(y=spam$type, 

                               p=0.75, list=FALSE)

training <- spam[inTrain,]

testing <- spam[-inTrain,]

dim(training)


[1] 3451   58


Fit a model

train 함수를 이용해서 machine learning을 수행한다.

prediction할 것은 type이고

tilde (~)와 dot(.) 은 모든 data frame에 있는 데이터들은 prediction을 위해서 사용된다는 것을 의미한다.

그리고 어떤 데이터셋을 트레이닝을 위해서 사용할지 알려준다.

data=training

마지막으로 어떤 method를 사용할지를 알려준다.

method="glm"


set.seed(32343)

modelFit <- train(type ~., data=training, method="glm")

modelFit


생성된 모델 정보는 아래와 같다.

> modelFit

Generalized Linear Model 


3451 samples

  57 predictor

   2 classes: 'nonspam', 'spam' 


No pre-processing

Resampling: Bootstrapped (25 reps) 

Summary of sample sizes: 3451, 3451, 3451, 3451, 3451, 3451, ... 

Resampling results


  Accuracy  Kappa      Accuracy SD  Kappa SD  

  0.918051  0.8278053  0.01416705   0.02778765


모델의 계수(coeeficients)들을 확인하면 아래와 같다.

> modelFit$finalModel


Call:  NULL


Coefficients:

      (Intercept)               make            address                all              num3d                our  

       -1.490e+00         -4.477e-01         -1.493e-01          5.160e-02          1.746e+00          4.210e-01  

             over             remove           internet              order               mail            receive  

        1.504e+00          2.466e+00          5.677e-01          4.802e-01          1.196e-01         -3.559e-01  

             will             people             report          addresses               free           business  

       -6.004e-02         -2.322e-01          1.732e-01          5.614e-01          1.164e+00          1.200e+00  

            email                you             credit               your               font             num000  

        4.194e-02          8.780e-02          2.307e+00          2.697e-01          2.301e-01          2.094e+00  

            money                 hp                hpl             george             num650                lab  

        3.204e-01         -2.117e+00         -1.391e+00         -1.031e+01          3.958e-01         -2.554e+00  

             labs             telnet             num857               data             num415              num85  

       -1.399e-01         -1.854e-01          2.073e-01         -6.540e-01          8.005e-01         -2.510e+00  

       technology            num1999              parts                 pm             direct                 cs  

        1.340e+00          6.107e-02          1.001e+00         -1.107e+00         -4.080e-01         -4.010e+01  

          meeting           original            project                 re                edu              table  

       -3.290e+00         -1.187e+00         -2.507e+00         -8.582e-01         -1.383e+00         -3.183e+00  

       conference      charSemicolon   charRoundbracket  charSquarebracket    charExclamation         charDollar  

       -5.973e+00         -1.367e+00         -1.341e-01         -4.585e-01          2.613e-01          4.264e+00  

         charHash         capitalAve        capitalLong       capitalTotal  

        2.430e+00         -2.119e-02          1.297e-02          7.873e-04  


Degrees of Freedom: 3450 Total (i.e. Null);  3393 Residual

Null Deviance:    4628 

Residual Deviance: 1351 AIC: 1467


모델을 이용해서 prediction할 수 있다.

predict() 함수를 이용하는데, 이때 통일된 인자를 넘겨 주게된다. 이러한 통일성이 caret의 장점이다.

인자로는 생성된 model과 prediction에 사용될 데이터 set을 넘겨 준다.


# predict 

predictions <- predict(modelFit, newdata=testing)

predictions 


모델의 평가는 confusion matrix을 이용해서 한다.

# evaluating models

confusionMatrix (predictions, testing$type)


많은 statistical information들이 자동으로 계산 되는것을 볼 수 있다.

Confusion Matrix and Statistics


          Reference

Prediction nonspam spam

   nonspam     646   45

   spam         51  408

                                         

               Accuracy : 0.9165         

                 95% CI : (0.899, 0.9319) # confidence interval for the accuracy

    No Information Rate : 0.6061         

    P-Value [Acc > NIR] : <2e-16         

                                         

                  Kappa : 0.8256         

 Mcnemar's Test P-Value : 0.6098         

                                         

            Sensitivity : 0.9268         

            Specificity : 0.9007         

         Pos Pred Value : 0.9349         

         Neg Pred Value : 0.8889         

             Prevalence : 0.6061         

         Detection Rate : 0.5617         

   Detection Prevalence : 0.6009         

      Balanced Accuracy : 0.9137         

                                         

       'Positive' Class : nonspam        


추가적인 참고 자료들


공식 사이트: http://topepo.github.io/caret/index.html

튜토리얼 자료1: http://www.edii.uclm.es/~useR-2013/Tutorials/kuhn/user_caret_2up.pdf

튜토리얼 자료2: https://cran.r-project.org/web/packages/caret/vignettes/caret.pdf

caret 논문 (journal of statistical software): file:///C:/Users/justin/Downloads/v28i05.pdf




Data Slicing


data slicing에 대한 이야기 이다.

뭘하던 간에 데이터 슬라이싱 부터 수행 해야 한다.


caret에서 지원하는 Data Splitting function들은 아래와 같다.

createDataPartition(y, 

                    times = 1,

                    p = 0.5,

                    list = TRUE,

                    groups = min(5, length(y)))

createResample(y, times = 10, list = TRUE)

createFolds(y, k = 10, list = TRUE, returnTrain = FALSE)

createMultiFolds(y, k = 10, times = 5)

createTimeSlices(y, initialWindow, horizon = 1, 

            fixedWindow = TRUE, skip = 0)

각각에 대해서 알아보자.




■ createDataPartition

아래의 createDataPartion() 함수를 이용해서 데이터를 분할 하게 된다.

y 변수에 분할할 데이터를 입력하고

p에서 몇 %를 분할 할지를 설정한다.

그럼 최종적으로 inTrain에는 index 값이 저장 되어 진다.


# --- 2-1 caret package ---

library(caret); library(kernlab); data(spam)

inTrain <- createDataPartition(y=spam$type, 

                               p=0.75, list=FALSE)

training <- spam[inTrain,]

testing <- spam[-inTrain,]

dim(training)



■ createFolds

cross validation방법중 k-folds 방법으로 data와 training set을 분할 하는 방법을 소개한다.

y는 결과값을 저장하고 있는 vector 이다.

k는 folds할 숫자를 나타낸다.

list = TRUE로 설정할 경우 결과를 list로 저장 하게 된다.

returnTrain = TRUE로 설정할 경우 folds의 결과를 training을 위해서 사용할지 여부를 결정 한다.


library(caret); library(kernlab); data(spam)

set.seed(32323)

folds<-createFolds(y=spam$type, k=10, list=TRUE, returnTrain = TRUE)

sapply(folds, length)


생성된 10-folds의 데이터 길이를 각각 확인하면 아래와 같다.

Fold01 Fold02 Fold03 Fold04 Fold05 Fold06 Fold07 Fold08 Fold09 Fold10 

  4141   4140   4141   4142   4140   4142   4141   4141   4140   4141 

각각의 fold의 데이터 길이는 유사한것을 알 수 있다.


각 fold가 포함하는 데이터를 10개씩만 확인해보면 아래와 같다.

> folds[[1]][1:10]

 [1]  1  2  3  4  5  6  7  8  9 10

> folds[[2]][1:10]

 [1]  1  3  4  5  6  7  8  9 10 11

> folds[[3]][1:10]

 [1]  1  2  3  4  5  6  7  8  9 10

> folds[[10]][1:10]

 [1]  1  2  3  4  5  6  7  8  9 10


test set을 생성하는 방법은 아래와 같다.

> # for test set

> set.seed(32323)

> folds <- createFolds(y=spam$type, k=10, list=TRUE, returnTrain = FALSE)

> sapply(folds, length)



Fold01 Fold02 Fold03 Fold04 Fold05 Fold06 Fold07 Fold08 Fold09 Fold10 

   460    461    460    459    461    459    460    460    461    460 



> folds[[1]][1:10]

 [1] 24 27 32 40 41 43 55 58 63 68

> folds[[2]][1:10]

 [1]   2  21  25  54  64  71  87 105 107 108


■ createResample

완전히 full cross validation하는 것이 아니라 resampling 또는 bootstrapping을 하고 싶을 때가 있다.


설정방법은 아래와 같다.

y는 이전과 같이 결과 데이터를 저장하고 있는 vector 이다.

time은 얼마만큼 resampling을 할지를 저장해 준다.

list, vector, matrix 원하는 type을 설정해 준다.


> # resampling for traning set

> set.seed(32323)

> folds <- createResample(y=spam$type, times=10, list=TRUE)

> sapply(folds, length)


Resample01 Resample02 Resample03 Resample04 Resample05 Resample06 

      4601       4601       4601       4601       4601       4601 

Resample07 Resample08 Resample09 Resample10 

      4601       4601       4601       4601 


결과를 확인해보면 k-folds 방법과 다르게 중복 데이터가 존재하는 것을 알 수 있다.

> folds[[1]][1:10] 


[1]  1  2  3  3  3  5  5  7  8 12



■ createTimeSlice


시계열 데이터를 slicing 할 필요가 있을 수도 있다.

기상예보를 예측하려고 할때를 말한다.


아래와 같이 time series 데이터의 경우 

window 크기를 20으로 설정한다음 그것으로 다음 10개를 예측 하는 식으로 동작하게 된다.

이렇게 순차적으로 데이터를 분할하게 된다.


즉, (트레이닝 20개, 테스트 10)이 조합이 반복적으로 수행 된다.

> # Time Slices for traning and test set

> set.seed(32323)

> time <- 1:1000

> folds <- createTimeSlices(y=time, initialWindow = 20, horizon = 10)

> names(folds)


[1] "train" "test" 


> folds$train[[1]]


[1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20


> folds$test[[1]]


[1] 21 22 23 24 25 26 27 28 29 30

















Week 01: Receiver Operating Characteristic, Cross validation


  • Prediction motivation
  • What is prediction?
  • Relative importance of steps
  • In sample and out of sample errors
  • Prediction study design
  • Types of errors
  • Receiver Operating Characteristic
  • Cross validation
  • What data should you use ?



ROC curves


Receiver Operating Characteristic Curves (ROC curves)


prediction algorithm의 좋은 정도를 측정하는 좋은 measure 이다.


Why a curve ?


In binary classification you are predicting one of two categories

Alive / Dead

Click on add / don't click


But your prediction are often quantitative

Probability of being alive

Prediction on a scale from 1 to 10


The cutoff you choose gives different results

   

같은 모델이라도 0.7 부터 alive로 설정한지 그 이하로 설정 할지에 따라서 결과가 달라지게 된다.



ROC curves


상세한내용 Wekipedia


사람들은 ROC curve를 이용하는데


X축은 1 - specificity 

다른 말로, P(FP)와 같다.

정리하면 아래와 같다.

$$1\quad -\quad specificity\quad =\quad 1\quad -\quad \frac { TN }{ (FP+TN) } \\ =>\quad \frac { FP }{ FP+TN } \quad =\quad Probability\quad of\quad FP\quad =\quad P(FP)$$



Y축은 sensitivity

다른말로 P(TP)와 같다.

정리하면 아래와 같다.

$$Sensitivity\quad =\quad \frac { TP }{ TP+FN } \quad =\quad P(TP)$$



이제 해당 그래프로 무엇을 하냐면

어떠한 curve를 하나 생성하고 curve를 구성하는 각각의 점들은 모두 하나의 cut off가 된다.

어떤 특별한 cut off에서 그 지점에서의 P(FP)와 P(TP)를 구할 수 있게 된다.


이러한 curve를 통해서 해당 Algorithm이 좋은 안 좋은지를 평가 할 수 있다.

즉 각각의 cutoff로 구성된 어떠한 curve를 생성해서 해당 알고리즘의 goodness를 평가 할 수 있다.

X축은 1 - Specificity 이므로 값이 커질 수록 specificity가 작아지는 것이다.

Y축은 Sensitivity 이므로 값이 클 수록 좋다.


x축 0.2는 specificity가 0.8이므로 매우 좋은것이다. 하지만 그것을 따라 위로 가보면 빨간색 알고리즘 (NetChop)에 대해서 0.4가 약간 넘는 Sensitivity를 가지는 것을 알 수 있다. 이것은 그다지 높은 수치가 아니다.


따라서 이 X와 Y축 둘 사이에는 trade-off 관계가 존재하는 것을 알 수 있다.




Area under the curve (AUC)


AUC = 0.5 라는 것은 random guessing과 다를바 없으므로 매우 안좋은 성능을 나타낸다.

0.5 보다 낮다는 것은 동전 던지기 (flip a coin) 보다 더 안좋다는 것이기 때문에 심각하다고 할 수 있다.


AUC = 1 라는 것은 perfect classifier


일반적으로 AUC가 0.8 이상이라면 좋다고 생각한다.





Cross validation


아래와 같은 목적으로 자주 사용되는 도구이다.

detecting relevant features for building model

estimating their parameters when doing machine Learning



Key idea

트레이닝 데이터 셋에대한 Accuracy에 대해서는 언제나 낙관적이다. 그다지 유효하지 않다.

왜냐하면 항상 best model이 선택 되어 지기 때문이다.


더 나은 평가 방법은 independent set (test set accuracy)를 이용해서 평가 하는 것이다.


하지만 test set을 언제나 사용 할 수 있는 것은 아니다. 즉 모델을 만들고 있을때나 데이터가 너무 작아서 test set을 설정하지 못할 때이다. test set은 반드시 단 한번만 적용 해야 한다.


결국 training set과 test set의 경계는 모호해지며 따라서 training set으로 independent set을 만들어서 평가하는 방법을

고안한 것이 cross validation 이다.


각각의 다른 방식의 cross validation을 알아보자.


Random sub-sampling

랜덤하게 데이터를 training과 testing으로 구분해서 수행 한다.



K-fold


K 번 나눠서 수행 한다.

그리고 각각의 결과를 평균화하여 최종적인 결과로 사용 한다.




Leave one out


하나를 빼고 하나를 넣고 이렇게 순차적으로 반복해서 수행 한다.



고려사항 (Considerations)


time series 데이터들은 "chunk"단위로 수행 해야 한다.


k-fold cross validation을 위해서는

k가 너무 크면 bias는 값이 작아진다. 하지만 variance는 커진다.

k가 너무 작다면 bias는 값이 커진다. 하지만 variance는 작아진다.


LOOCV는 좀 더 높은 variance를 K-fold CV에 비해서 가지게 된다. 

왜냐하면, Training set들이 LOOCV의 경우 좀더 overlap 되기 때문이다.

Random sampling must be done without replacement


Random sampling with replacement is the bootstrap

Underestimates of the error

Can be corrected, but it is complicated (0.632 Bootstrap)


If you cross-validate to pick predictors estimate you must estimate error on independent data.











Week 01: Prediction study design, Types of errors


  • Prediction motivation
  • What is prediction?
  • Relative importance of steps
  • In sample and out of sample errors
  • Prediction study design
  • Types of errors
  • Receiver Operating Characteristic
  • Cross validation
  • What data should you use ?


Prediction study design


만약 validation set이 없다면 반드시 test set으로는 단 한번만 평가해라.

그렇지 않고 여러번 test해서 그중 최적의 model을 선택하게 된다면 training set이랑 다르지 않게 된다.


■ Avoid small sample sizes

왜 test data set이 커야하는지에 대한 이야기 이다.


만약 Diseased 와 healthy를 구분하는 문제가 있다고 하자.

이것의 알고리즘이 

$$\left( \frac { 1 }{ 2 }  \right) ^{ sampleSize }$$

를 따른다고 하자.


그냥 랜덤으로 돌아가는 알고리즘이다.


1번의 수행으로 100%의 정확도를 달성할 확률은 50%이다.

하지만 10번의 test 셋에대해서 100%를 달성할 확률은 0.10% 이다.


이러한 사실을 통해서 왜 test 사이즈가 커야하는지를 알 수 있다.


■ Rule of thumb for prediction study design


large sample size가 주어졌다면

60%를 training 

20%를 test

20%를 validation


Medium sample size가 주어졌다면

60% training

40% testing


If you have a small sample size

Do cross validation

Report caveat of small sample size




Types of errors



■ Basic terms

prediction하는 것이 무엇이냐에 따라 Positive와 Negative의 정의는 달라진다.

여기서는 아픈 사람을 찾아내는 것을 목표로 한다고 가정 한다.


Positive = identified 

Negative = rejected


TP = correctly identified 

FP = incorrectly identified 

TN = correctly rejected

FN = incorrectly rejected


Medical testing example:

TP = Sick people correctly diagnosed as sick

FP = Healthy people correctly identified as healthy

TN = Healthy people correctly identified as healthy

FN = Sick people incorrectly identified as healthy




■ Key quantities




Sensitivity (recall) -> Pr ( positive test | disease ) 

-> 예측되어지는 확률인데, 주어진 진짜 Disease인 것들에 대해서 예측되어진 Disease를 나타내는 확률이다.

recall만 무조건 높다고 좋을 수 없는 이유는, 비록 재현율은 100%가 나올지 모르지만, 정확도가 매우 낮을 수도 있다.

무작정 많은 환자들을 검출하겠다고 막무가내로 모두다 아픈 환자로 취급 할 수는 없다.

Specificity -> Pr ( negative test | no disease )

Positive Predictive Value (precision) -> Pr ( disease | positive test )

-> 환자라고 예측한것들 중에서 실제로 환자인 것을 의미한다.

precision만 높으면 안되는 이유는 다음과 같다.

무작정 정확도만 높이자고 정말 아픈사람만 환자로 취급한다면 그래서 대다수의 잠재적인 환자들은 무시한다면 당장 정확도는 높일 수 있지만, 많은 FN를 발생 시키므로 전체 실제 환자를 재현하는것에는 실패했다고 할 수 있다.

Negative Predictive Value -> Pr ( no disease | negative test )

Accuracy -> Pr ( correct outcome )

-> Positive와 Negative가 모두 동등하게 중요할 때 사용 되는 measure 이다.


Sensitivity (recall) -> TP / (TP + FN)

Specificity -> TN / (FP + TN)

Positive Predictive Value (precision) -> TP / (TP + FP)

Negative Predictive Value -> TN / (FN + TN)

Accuracy -> (TP + TN) / (TP + FP + NF + TN)



좀더 실제적인 예를 보면 아래와 같다.


  • 유병률 0.1%인 일반적인 환자 분포와

  • 유병률 10%인 high risk sub-population 분포가 있다고 하자.


두 분포에 대해서 모두 sensitivity와 specificity가 99%인 좋은 모델이 있다고 하자.

즉, 환자에 대해서도 99%로 prediction하며

일반 사람들에 대해서도 99%로 prediction하는 알고리즘 인것이다.

Accuracy (정확도)는 당연히 99% 이다. 하지만 한쪽 Class가 유난히 작은 분포를 가지고, 이것의 발견이 중요한 상황에서는 Accuracy는 의미가 없다. 즉 유병률이 0.1%인 집단에서는 대부분 환자가 아니므로 정확도가 해당 모델의 유용성을 평가할 수 있는 지표로 올바르지 않다.


아래의 질문을 통해서 각각의 Evaluation Measure 특성을 파악해 보자.


- Sensitivity와 Specificity만 보면 안되는 이유?

유병률 0,1%인 집단 (General population as fractions)



유병률 10%인 집단 (At risk sub-population as fraction)


위와 같이 precision (positive predictive rate)이 0.1% 유병률인 집단에 대해서는 9%로 급격히 안좋아 지는것을 알 수 있다.

따라서 샘플의 특성에 대해서 다른 고려를 해야한다.

그리고 이렇기 때문에 recall과 precision을 동시에 고려해서 evaluation 해야 한다.


하지만 그래도 10만명 검사할것을 1098명으로 줄였기 때문에 의미 있다고 할 수 있다. 비록 precision이 매우 낮자다고 할 지라도 말이다.


- Accuracy만 보면 안되는 이유?

Accuracy의 정의 (TP + TN) / (TP + FP + NF + TN)에 의해서

만약 아래와 같이 유병률이 0.1%라고 하면 대부분에 대해서 TN이므로 Accuracy가 의미가 없다.


- Precision만 보면 안되는 이유?

실제 예측한것들 중에서 TP의 비율을 보는 P(TP)이므로 고의적으로 TP를 축소 할 수도 있다.

적게 예측하여 정확도를 올림.


- Recall (Sensitivity) 만 보면 안되는 이유?

Recall의 정의는$\frac {TP}{(TP+FN)}$ 이다.


아래와 같은 결과를 얻었다고 하면,

 

Actual

Prediction

 

         +

-

+

10000

50000

-

100

39900


Recall 10000 / 10100 *100 = 99%

이지만 precision16%이다.

, 일부러 많이 Positive로 예측해서 최대한 Recall을 올릴 수도 있다.




■ 연속 데이터를 위한 방법


간단하게 얼마만큼 참값과 유사한지를 알아내기위해서 두가지 간단한 기법을 사용할 수 있다.

연속 데이터 일 때 사용 한다.


Mean Squared Error (MSE)

$$\frac { 1 }{ n } \sum _{ i=1 }^{ n }{{(Prediction_i-Truth_i)}^{2}} $$

예측값과 참값간의 차이를 구한다음 제곱해서 모두 더한다음 전체 샘플 숫자로 나눈다.

샘플 데이터의 스케일을 모른다면 해당 수치의 해석이 난해하다.

그냥 단수히 값만으로는 어느정도 수준으로 모델이 정확한지 알아내기 어렵다.


Root Mean Squared Error (RMSE)

좀더 연속데이터를 위한 일반적인 수치값은 아래와 같다.

$$\sqrt { \frac { 1 }{ n } \sum _{ i=1 }^{ n }{ { (Prediction_{ i }-Truth_{ i }) }^{ 2 } } }$$



■ Common error measures


Mean squared error (or root mean squared error)

연속형 데이터 일때 사용 한다.

outlier에 민감하다는 특성을 가지고 있다.


Median absolute deviation

연속형 데이터 일때 사용 한다.

outlier에 대해서 다소 MSE보다는 덜 민감하다는 특성이 있다. 


Sensitivity (recall)

실제 positive들 중에서 얼마만큼 놓쳤는지를 알고 싶을 때 사용 한다. 


Specificity

실제 negative를 얼마만큼 놓쳤는지를 알고 싶을 때 사용 한다.


Accuracy

False Positive들과 False Negative들의 가중치가 같을때 사용 된다.


Concordance

One example is kappa





Week 01: Relative importance of steps, In sample and out of sample errors



  • Prediction motivation
  • What is prediction?
  • Relative importance of steps
  • In sample and out of sample errors
  • Prediction study design
  • Types of errors
  • Receiver Operating Characteristic
  • Cross validation
  • What data should you use ?


Relative importance of steps


Question

간결하고 단단하게 질문을 만들어야한다.


Input data

Garbage in  = Garbage out


Features

좋은 feature들의 요소

압축형 데이터

관련 정보들의 유지

해당 응용의 전문가의 지식에 기반해서 만든다.


일반적인 실수

자동으로 features들이 선택 되어지는 경향. 따라서 해석을 집중해서 하지 않는 경우이다.

Black Box Machine learning Algorithm(ex., ANN, SVM)의 경우 매우 유용하지만 이러한 해석의 어려움을 내포하고 있다.

필요 없다고 무조건 버리는 행동



블랙박스가 유용한 경우

Youtube Video에서 고양이 이미지를 알려주지 않고 분류하는 연구

Building High-level Features Using Large Scale Unsupervised Learning, Standford, Andrew Y. Ng.



semi supervised learning 

deep learning


YouTube video에서 feature들을 자동으로 discovering 한 다음

그것을 prediction 알고리즘에 사용 했다.

여기서 사람의 개입은 존재 하지 않는다.

이것이 그런데도 잘 동작하는 이유는 다음과 같다.


predictor는 기본적으로 video 이미지가 나오면 그것이 cat인지 아닌지를 구분하게 된다.

이것은 unsupervised learning을 이용해서 자동으로 수집된 a bunch of features들에 기반해서 이뤄 진다.

좋은 feature들은 위 그림에서 오른쪽과 같이 고양이 얼굴일 것이다. 이러한 feature들을 자동으로 잘 수집해줘야 한다.



Algorithm


Machine Learning을 한다고 하면, 우리는 항상 연구된 많은 알고리즘중 어떤 알고리즘을 선택하는지가

Prediction Model의 정확도를 결정하는 중요한 요소라고 생각 한다.


하지만 생각보다는 Algorithm 종류가 미치는 정확도의 영향은 크지 않다는것이 사실이다.

그내용을 다뤄 본다.


linear discriminant analysis은 그다지 복잡하지 않은 기본적인 알고리즘 이다.

또한 그들은 각각의 Data set에 맞춰서 absolute best prediction algorithm을 적용 했다.

그렇게 했을 때의 prediction error를 보여주게 된다.

http://arxiv.org/pdf/math/0606441.pdf


best algorithm을 선택해서 수행한 것의 prediction error는 항상 단순히 Linear discriminant analysis를 수행 했을 때보다 낮게 된다. 이것은 당연한 사실 이다. 중요한 것은 그 차이가 크다지 크지 않다는 점이다.


Issues to consider

  • Interpretable

  • Simple

  • Accurate

  • Fast (to train and test)

  • Scalable


Prediction is about accuracy tradeoffs

  • interpretability versus accuracy

  • Speed versus accuracy

  • Simplicity versus accuracy

  • Scalability versus accuracy



Interpretability matters


Interpretability는 중요한 요소 이므로 If then else 스타일의 decision tree가 많이 쓰이는 이유이다.


Google Flu에서도 실제 사람들의 Keyword를 If than else로 확인하면 이해하기 쉬우므로 모델 재조정이 쉽게 된다.

decision tree가 단순하지만 때로는 정확도 보다는 interpretability가 더 중요할 때도 많다. 모델 이해가 어렵다면 지금 당장이야 정확도가 높을지 몰라도 Google Flu의 사례처럼 반년만 지나도 유지 보수 없이는 엉망이 되어 버릴 수 있다. 



Scalability matters


매년 100만 달러를 걸고 original Netflix 보다 좋은 알고리즘을 개발하는 경진 대회를 연다.

하지만 Netflix는 그러한 우승 알고리즘을 구현해서 제품에 반영하고 있지는 않다.

이유는 통상의 우승 알고리즘들은 복잡한 machine learning을 여러개 섞어서 사용하기 떄문에 데이터 처리 시간이 오래걸리며 그것을 Netflix와 같은 거대 data 셋에 적용하기엔 노력이 많이 필요하기 떄문이다.


따라서 Netflix는 약간 정확도를 잃더라도 현재의 방법을 고수하고 있는 것이다.

이번 사례에서도 알 수 있듯이 Accuracy가 언제나 항상 중요한 것은 아니다.






 

In sample and out of sample error


In sample error: 같은 data set이지만 알고리즘이 noise를 처리하는 방식에 따라서 매번 약간식은 차이가 생기는 것을 말한다.

다른 이름으로 re-substitution error 라고 한다.


Out of sample error: 새로운 데이터 셋에 대해서 발생 하는 에러이다. 이것은 generalization error라고도 불리운다.

결국, 해당 알고리즘을 트레이닝 데이터 셋을 벗어나서 일반적으로 적용했을 때 발생하는 에러를 말한다.


이것에대해서는 신중히 다뤄 줘야 한다.

In sample error < out of sample error 이다.

왜냐하면, 항상 트레닝이닝 데이터에 대해서 over-fitting 되는 경향이 있기 때문이다.

너무 트레닝이닝 데이터 셋에 대해서 맞추기 보다는 어느정도 noise를 감수하는것이 오히려 generalization을 했을 때 robust를 보장 할 수도 있다.


간단한 예제는 아래와 같다.

library(kernlab)
data(spam)
#smae data reproduced by using same seed
set.seed(333)
# randomly choose 10 data from entire data.
smallSpam <- spam[sample(dim(spam)[1],size=10),]
spamLabel <- (smallSpam$type=="spam")*1+1
plot(smallSpam$capitalAve,col=spamLabel)


스팸 데이터 10개를 추출해서 대문자 분포를 확인해 보면, spam은 빨간색 점들인데 대문자 비중이 높은것을 알 수 있다.

이것을 토대로 아래와 같은 일반적인 모델을 생성 할 수 있다.


capitalAve > 2.7 = "spam"

capitalAve > 2.40 = "nonspam"


여기에 추가로 정확도 100%를 위해서 

index 7과 index 10을 각각 ham과 spam으로 구분하기 위해서


capitalAve between 2.40 and 2.45 = "spam"

captialAve between 2.45 and 2.7 = "nonspam"


아래와 같이 rule model을 만들어서 수행해보면 training data set에 대해서 100%의 정확도를 가지는 것을 알 수 있다.

# perfect rule for traning data
rule1 <- function(x){
    # handle to missing value (NA)
    prediction <- rep(NA,length(x))
    prediction[x > 2.7] <- "spam"
    prediction[x < 2.40] <- "nonspam"
    prediction[(x >= 2.40 & x <= 2.45)] <- "spam"
    prediction[(x > 2.45 & x <= 2.70)] <- "nonspam"
    return(prediction)
}
table(rule1(smallSpam$capitalAve),smallSpam$type)
          nonspam spam
  nonspam       4    0
  spam          0    5


일반적인 룰에 대해서만 고려해서 수행하면, 아래와 같이 1개의 오류를 범하게 된다.

# general rule, considering noise for robust.
rule2 <- function(x){
    prediction <- rep(NA,length(x))
    prediction[x>2.8] <- "spam"
    prediction[x<=2.8] <- "nonspam"
    return(prediction)
}
table(rule2(smallSpam$capitalAve),smallSpam$type)
          nonspam spam
  nonspam       5    1
  spam          0    4


하지만 위 과정을 10개의 트레이닝 데이터 셋이 아닌 전체 데이터 셋인 4601개에 대해서 적용하면 아래와 같은 반대의 결과를 얻는다.

> # apply two models to a whole bunch of data set (4601)
> table(rule1(spam$capitalAve),spam$type)
         
          nonspam spam
  nonspam    2141  588
  spam        647 1225
> table(rule2(spam$capitalAve),spam$type)
         
          nonspam spam
  nonspam    2224  642
  spam        564 1171


행이 prediction이고 열이 actual data 이다.

rule1의 error 숫자는 647 + 588 = 1235 이고

rule2의 error 숫자는 564 + 642 = 1206 이다.

오류 숫자가 트레이닝 데이터에 대해서 더 완벽했던 rule1이 많은 데이터에 적용했을 때는 오류가 더 큰 것을 알 수 있다.


정확히 예측한 것들에 대한 합을 구해보면 아래와 같다.

> sum(rule1(spam$capitalAve)==spam$type)
[1] 3366
> sum(rule2(spam$capitalAve)==spam$type)
[1] 3395


왜 그럼 간단한 규칙이 복잡한 규칙보다 일반적으로 많은 데이터에 대해서 적용했을 때 더 정확도가 높은지를 알아보자.

우리는 이러한 현상을 Overfitting이라고 부른다.


■ Overfitting


데이터 셋은 크게 2가지 파트로 구성된다

Signal

Noise 

문제는 Signal만을 캡쳐해서 모델을 만들어야는데 Signal과 Noise를 분명히 구분하기 어렵기 때문에

너무 모델을 해당 트레이닝 데이터에 대해서만 정확하게 만들면 Noise도 모델에 반영되는 문제가 발생한다.


Machine learning의 목적은 signal을 발견해서 모델을 만들고 최대한 측정과 데이터 수집에서 발생한 noise는 무시하는 것이다.







Week 01: Prediction motivation, What is prediction?


첫 번째 week의 수업 이슈들은 아래와 같다.

  • Prediction motivation
  • What is prediction?
  • Relative importance of steps
  • In and out of sample errors
  • Prediction study design
  • Types of errors
  • Receiver Operating Characteristic
  • Cross validation
  • What data should you use ?


Prediction motivation


Who predicts?

  • Local governments -> pension payments
  • Google -> whether you will click on an ad
  • Amazon -> what movies you will watch
  • Insurance companies -> what your risk of death is
  • Johns Hopkins -> who will succeed in their programs


Machine Learning 성공 사례


Chris Volinsky

Netflix Awards 1 Million Netflix Prize & Announce 2nd 1 Million Challenge

비디오 대여 회사 넷플릭스에 주최한 대회에서 우승 




Identify patients who will be admitted to a hospital within the next year using historical claims data. (Enter by 06:59:59 UTC Oct 4 2012)

Healthcare를 예측하는 completion에서 우승 함으로써 돈을 벌 수도 있다.




Data science는 어떤 하나의 sport로 활용 될 수 있다. 재미를 위해서

Kaggle에서 주최한 대회이다.




더 나은 medical decision을 위해서도 활용 될 수 있다.

oncotype DX 같은 prognostic gene을 구분하는 signature를 발견하는 것에 사용 한다.

즉, 여성이 breast cancer에 얼마나 취약한지, 발병 했다면 얼마동안 살 수 있는지를 예측 할 수 있다.

Bioinformatic 분야를 말한다.





Advanced Study를 위한 자료들


The elements of statistical learning (Standford, California), It can be accessed as free PDF.

caret package: 다양한 prediction model을 제공하며 여러 문제들을 해결 할 수 있게 해준다.

Machine Learning Course in coursera

이곳에서 더 자세한 수학적 수식의 의미를 다루며 또한 더 cutting edge algorithm을 기술 한다.




What is prediction ?



아래는 Machine learning을 도식화한 그림이다.

우리는 항상 prediction을 위해서 Function F에 대해서만 항상 학습한다.

하지만 모든 Machine Learning 에서 쓰이는 중요한 부분은 바로 Probability와 Sampling 부분이다.

데이터를 모으고 어떻게 가공하고 어떤 Feature들을 모델로 넣을지 결정하는 문제는 반드시 거쳐야하는 중요한 초기 단계이며

이것은 모델을 성능을 결정짓는 매우 중요한 작업이다.


이러한 좋은 예가 Google Flu 프로젝트이다.

사람들이 사용하는 검색키워드를 통해서 감기가 어느지역에서 퍼질것인지를 예측 하는 것이다.

샌디에고에서 만약 cough라는 단어가 급증됬다면 조만간 그쪽지역에 flu가 창궐할 수도 있다.


하지만 문제는 해당 알고리즘이 막 개발 되었을 때는 잘 동작했지만, 사람들의 검색 패턴은 실시간으로 변화하기 때문에

만년만 지나도 해당 알고리즘의 정확도는 매우 떨어진 다는 것이다.

Dataset을 선정하고 그것을 가공하는것이 알고리즘에 비견할 만큼 중요하는 것을 알 수 있는 사례이다.




■ Components of a predictor


question -> input data -> features -> algorithm -> parameters -> evaluation


question

무엇을 기계학습 하던간에 잘 정의된 질문으로 부터 시작 된다.

어떤것을 예측하려 하는지 그래서 어떤 데이터를 이요할 건지에 대한 문제이다.


input data

그런 prediction을 위해서 가장 최선의 데이터 셋을 확보 해야한다.

이러한 데이터 확보는 그냥 알 수 있는게 아니다.

여러번 시도해봐야 어떤 데이터가 최선이었는지 알 수 있다.


features

유용한 feature들을 정의 할 수 있어야 한다.

input data들 중에서 실제로 의미 있는 데이터의 집합을 의미한다.


algorithm

machine learning algorithm을 적용한다.

Random Forest

Decision Trees


parameters

최종적으로 모델을 얻게된다.

이러한 모델의 파라메터값을 이용해서 데이터가 들어 왔을 때 어떠한 결과를 예측 할 수 있게 된다.


evaluation

예측한 결과를 평가하는 단계이다.



스팸 예제를 통해서 위 과정을 이해해 보겠다.

스팸 예제에 대해서 좀 더 Advanced된 내용을 보고싶으면, Naive Bayes로 구현했던 이전 POST를 참조하자.

이곳에서는 매우 간단하게 다룬다.



1) Question

start with a general question

Can I automatically detect emails that are SPAM that are not ?

Make it concrete 

Can I use quantitative characteristics of the emails to classify them as SPAM/HAM ?


2) Input data

kernlab package에 보면 데이터가 있다. 


3) features


일단 이러한 이메일 input data가 있다고 생각해보자. 그리고 이것은 a whole bunch of email 이다.


Dear Jeff,

Can you send me your address so I can send you the invitation?

Thanks,

Ben


Frequency of you = 2/17 = 0.118

위와 같이 모든 단어들의 빈도를 구해서 이것을 feature들의 characteristic으로 사용 할 수 있다.

> library(kernlab)
> data(spam)
> head(spam)
  make address  all num3d  our over remove internet order mail receive will people report addresses free business
1 0.00    0.64 0.64     0 0.32 0.00   0.00     0.00  0.00 0.00    0.00 0.64   0.00   0.00      0.00 0.32     0.00
2 0.21    0.28 0.50     0 0.14 0.28   0.21     0.07  0.00 0.94    0.21 0.79   0.65   0.21      0.14 0.14     0.07
3 0.06    0.00 0.71     0 1.23 0.19   0.19     0.12  0.64 0.25    0.38 0.45   0.12   0.00      1.75 0.06     0.06
4 0.00    0.00 0.00     0 0.63 0.00   0.31     0.63  0.31 0.63    0.31 0.31   0.31   0.00      0.00 0.31     0.00
5 0.00    0.00 0.00     0 0.63 0.00   0.31     0.63  0.31 0.63    0.31 0.31   0.31   0.00      0.00 0.31     0.00
6 0.00    0.00 0.00     0 1.85 0.00   0.00     1.85  0.00 0.00    0.00 0.00   0.00   0.00      0.00 0.00     0.00
  email  you credit your font num000 money hp hpl george num650 lab labs telnet num857 data num415 num85 technology
1  1.29 1.93   0.00 0.96    0   0.00  0.00  0   0      0      0   0    0      0      0    0      0     0          0
2  0.28 3.47   0.00 1.59    0   0.43  0.43  0   0      0      0   0    0      0      0    0      0     0          0
3  1.03 1.36   0.32 0.51    0   1.16  0.06  0   0      0      0   0    0      0      0    0      0     0          0
4  0.00 3.18   0.00 0.31    0   0.00  0.00  0   0      0      0   0    0      0      0    0      0     0          0
5  0.00 3.18   0.00 0.31    0   0.00  0.00  0   0      0      0   0    0      0      0    0      0     0          0
6  0.00 0.00   0.00 0.00    0   0.00  0.00  0   0      0      0   0    0      0      0    0      0     0          0


1-6개의 메시지에 대한 각각의 단어에 대한 빈도를 보여준다.

money의 경우 빈도가 높다면 해당 message는 spam일 확률이 크다.


좀더 분석해보면

아래의 그래프와 같이 SAPM의 경우 your에 대해서 빈도가 고루고루 넓게 사용 되는 것을 알 수 있다.

반면에 HAM은 your를 사용하지 않거나 1~2개 정도 사용한다.

plot(density(spam$your[spam$type=="nonspam"]),col="blue",main="",xlab="Frequency of 'your'")
lines(density(spam$your[spam$type=="spam"]),col="red")


4) our algorithm

Find a value C.

Frequency of "your" > C predict "spam"

abline(v=0.5,col="black")

5) Parameter

0.5 를 기준으로 잡았고 그것 보다 크면 SAPM이 되고 그것 보다 작으면 HAM 이 된다.

이렇게 0.5로 정한 이유는 the large spike of blue HAM Message가 우리가 설정한 0.5 보다 밑에 있기 때문이다.


6) Evaluation

prediction을 수행해서 정확도를 검정 한다.

> prediction <- ifelse(spam$your > 0.5, "spam","nonspam")
> table(prediction,spam$type)/length(spam$type)
          
prediction   nonspam      spam
   nonspam 0.4590306 0.1017170
   spam    0.1469246 0.2923278

정확도는 TP + TN 이므로


0.459 + 0.292 = 0.751이 Accuracy가 된다.

매우 간단하게 했는데도 생각보다 정확도가 높은 것을 알 수 있다.








+ Recent posts