Data Science를 위한 Python package 꾸러미들


설치방법은 크게 두가지이다.

Ubuntu packages

  • Ipython: 인터렉트 python kernel
  • numpy: 수치배열 연산
  • Scipy: 과학 공학 계산에 필요한 툴박스
  • Matplotlib: 매트랩 스타일의 plot 생성
  • pands: R과 같은 statistical package (통계)
  • sympy: 심볼릭연산. 즉 도함수를 쉽게 그릴 수 있다.
  • scikit-learn: machine learning package 이다. (deep learning은 아직없음 tensorflow 설치법 참조)
sudo apt-get install ipython 
sudo apt-get install python-numpy 
sudo apt-get install python-scipy 
sudo apt-get install python-matplotlib 
sudo apt-get install python-pandas 
sudo apt-get install python-sympy 

pip를 이용한 설치 (python 2.7)

pip의 장점은 virtualenv를 사용할 수 있다는 것이다.
apt-get의 경우 system-wide로 영향을 미치게 된다.

Prerequisite:

sudo apt-get install build-essential gfortran libatlas-base-dev python-pip python-dev
sudo pip install --upgrade pip
sudo pip install numpy
sudo pip install scipy
sudo pip install matplotlib 
sudo pip install pandas 
sudo pip install sympy 
sudo pip install -U scikit-learn


Week 01: Parameter Learning


해당 수업에서는 첫 번째 Machine Learning 알고리즘이면서, 빈번하게 사용되는 gradient descent 알고리즘을 학습 한다.

Gradient Descent Algorithm

Cost Fuction이 다음과 같이 있다고 가정하다.

J(θ0,θ1)


당연히 이러한 Cost Fucntion의 값이 최소가 되는 θ0와 θ1을 우리는 찾고 싶을 것이다.

minθ0,θ1J(θ0,θ1)

최적화된 Cost Function을 찾는 방법을 Gradient Descent 알고리즘이라 한다.

  • Start with some θ0,θ1
  • Keep Changing θ0,θ1 to reduce J(θ0,θ1) untile we hopfully end up at a minimum

아래와같이 최소 지역을 찾을 수고 있고,

아래와 같이 약간 옆으로 시작할경우 local minimum 문제에 빠질 수도 있다.

수식으로 Gradient descent algorithm을 표현하면 아래와 같다.
구현상의 중요점은 θ0,θ1두 개가 모두 한번에 업데이트 되어야 한다는 것이다.
그리고 temp를 이용해서 저장하고 그것을 반영해야한다.

Gradient Descent Algorithm Intuition

좀 더 직관적으로 쉽게 이해해보자.
일단 단하나의 변수 θ1만 존재하는 Cost Function을 생각해보자. 아래와 같이 간단히 구할 수 있다.

추가로 learning rate에 따라서 최적화가 될 수도 있고 안될 수도 있다.

아래는 간단한 Quize이다.

이렇게 local minimum에서 빠져 나오지 못하는것은
자체적으로 점점 더 값이 작아지기 때문이다.
알파 값을 고저이켜도 결국 minimum 값에 converge 하게 된다.

이러한 gradient descent algorithm을 이용해서 어떠한 cost function도 최적화 할 수 있다.
단 local minimum의 문제는 여전히 존재 한다.

Gradient Descent for Linear Regression

실제 cost function인 linear regression에서의 measn sqaured error 를 생각해보자.
당연히 θ0,θ1으로 두개의 변수를 가지고 있다.
각각에 대해서 partial derivative (편미분)하면 아래와 같다.

실제 partialderivative (편미분)을 통해서 optimal 함수를 구하는 것은 알아냈다.
이제는 좀 더 실제적으로 local fucntion을 구하는것을 알아보자.

bow shape을 따른다 Linear regression의 cost function의 경우에는

아래와같은 모양을 convex fucntion이라고 하고 이것을 bow-shaped 이라고 인포멀리 부른다.
이러한 convex fucntion은 local minimum이 존재하지 않고, 오로지 global minimum만이 존재한다.

따라서 linear regression의 cost function은 convex이기 때문에 local minimum문제 없이 언제나 global minimum에 도달하게 된다.

좀 더 포멀하게 cost function을 최적화 하는 것을 생각해보자.
θ0=900,θ1=0.1의 값을 생각해보자.
이때 hypothesis function h(x) = -0.1x+900

그리고 이것을 반복하면 최종적으로 global minimum에 도달하게 된다.

그리고 이렇게 전체 Traning set을 가지고 gradient descent하는 것을 Batch Gradient Descent라 한다.

Quize

Week 01: Model And Cost Function


Cost Function - Intuition 1

Cost Function - Intuition 2

또하나의 예제를 생각해보자.


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

2015의 스마트 기기들 (gadgets)


2015년에 핫 이슈 gadets들을 다뤄 본다.
단, CNN 기사들중에서 내가 관심 있는 것들만 추렸다.
원기사에서는 36개를 언급한다.

Google EKG smartwatch (no price yet)

Google's experimental watch can help doctors remotely monitor patients' health. The connected wristband can take a person's electrocardiogram (or EKG) and assess environmental stressors, including light and noise levels.


Microsoft HoloLens, $3,000

Microsoft has developed goggles that offer an augmented -- or "mixed" -- reality experience. Unlike Facebook's Oculus Rift, which completely blocks out the outside world to fully immerse the wearer in another reality, HoloLens keeps one foot (and both eyes) firmly planted in the real world. The lenses of the goggles are transparent, your view of the space around you only selectively blocked by digital images that can mingle with real objects. It's currently only available for software developers.




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 이다.











Ensemble method: Bagging (bootstrap aggregating)


일반적인 ensemble 방법의 하나가 bootstrap aggregating인 Bagging 방법이다.

Leo Breiman에 의해서 1994년에 만들어 졌다.


bagging은 오리지널 트레이닝 셋으로 부터 bootstrap 샘플링 방법을 이용해서 여러개의 트레이닝 데이터를 생성하는 방법이다.

이렇게 생성된 데이터 셋은 하나의 모델을 생성하기 위해서 사용 된다.


상대적으로 Ensemble 기법들 중에서는 Bagging은 단순한 방법에 속하지만 꽤 잘 동작 한다.

특히 Decision Tree 알고리즘의 경우 약간의 입력 데이터의 변화에도 급격히 다른 결과값을 이끌어 내므로

Bagging으로 이것을 보완 할 수 있다.



ipred package는 bagged decision tree를 구현한 것이다.


'AI > Machine Learning with R' 카테고리의 다른 글

Caret의 이해  (0) 2016.03.06
Cross Validation  (0) 2016.02.26
Bootstrapping  (0) 2015.11.19
Principal Component Analysis (PCA)  (0) 2015.11.18
Evaluating Model Performance with R  (2) 2015.11.12

Bootstrapping


resubstitution error는 한글로 재치환오류라고 하며 트레이닝 셋에서 훈련된 모델에서의 에러를 말한다.

다른 용어로는 In sample error라고도 한다.

당연히 수치는 긍정적으로 평가된다. 왜냐하면 같은 데이터로 훈련하고 테스트 하기 때문이다.



Bootstrap sampling

큰 데이터 셋을 추정하기 위해서 임의로 여러번 샘플링을 하는것을 말한다.

When this principle is applied to machine learning model performance, it implies the creation of several randomly-selected training and test datasets, which are then used to estimate performance statistics.

The results from the various random datasets are then averaged to obtain a final estimate of future performance.


어떤 점이 그럼 k-fold Cross Validation이랑 다른 것일까?

이 방법은 생성한 각각의 구획들이 단 한번만 나타나게 된다.


하지만 bootstrap의 방법은 복원 추출을 하기 때문에 여러번 나올 수 있다.

증명에 의하면 초기 데이터 셋의 수인 N이 엄청 크다면, bootstrap으로는 63.2%를 커버한다는 증명이 있다.


결국 36.8%는 트레이닝 셋이다.


original data의 size가 N 레코드라고 하자. 이때 bootstrap으로 샘플링을 수행하면 N번 수행하면 당연히 N개의 레코드가 있고

이러한 N개의 레코드는 원래 original data size인 N개 중 63.2%를 포함한다고 한다.


N번의 bootstrap sampling에서 단일 record가 선택 되어질 확률은 아래와 같다.

$$1-(1-\frac{1}{N})^{N}$$

이것은 asymptotically approaches $1-e^{-1}=0.632$에 근접한다.

이렇게 bootstrap sampling으로 포함되지 않은 것들은 test set으로 자동으로 포함된다.


이에반에 10-fold cv를 할경우 90%가 결국 트레이닝이 된다.


N이 충분히 크다면 bootstrap은 더 낮은 representative를 보인다.


당연히 63.2%의 트레이닝 셋을 가지고 테스트 하기 때문에 더 큰 트레이닝셋을 가지고 만든 모델보다 더 낮은 정확도를 가지게 된다.


최종적인 error rate의 계산식은 아래와 같다.

$$ error = 0.632 \times error_{test} + 0.368 \times error_{train}$$


cross validation 보다 더 좋은 bootstap의 장점은 더 작은 dataset에서 잘 동작하는 특성이 있다는 것이다.

또한 bootstrap sampling은 모델 정확도 향상의 효과가 있을 수도 있다




주어진 데이터로 부터 복원 표본을 구하는 작업을 여러 번 반복해 원하는 값을 추정 하는 것이다.


예를 들어 보면,

평균의 신뢰 구간을 구하는 경우를 생각해보자.


평균의 신뢰 구간은 평균이 속할 범위를 95% 신뢰도로 찾는 것이다.

부트스트래핑은 데이터로 부터 표본을 복원 추출로 구하고 이들의 평균을 기록하는 일을 반복한다.


이렇게 구한 평균들을 나열한 뒤 가장 작은 값으로 부터 2.5% 가장 큰 값으로 부터 97.5% 지점의 평균 두 개를 구한다.

그러면 두 평균 사이의 구간이 평균 95% 신뢰 구간이 된다.


실제 코드로 구현해 보자.

평균 30, 표준편차 3인 정규 분포로부터 1,000개의 난수를 만들고 이 난수로부터 역으로 평균을 추정해보자.

x <- rnorm(1000, mean=30, sd=3)
t.test(x)
	One Sample t-test
data:  x
t = 308, df = 999, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 29.72329 30.10447
sample estimates:
mean of x 
 29.91388 

t검정 결과 평균의 신뢰 구간이 (29.78891, 30.16317)로 구해졌다. 

library(foreach)
bootmean <- foreach(i=1:10000, .combine=c) %do% {
    return(mean(x[sample(1:NROW(x), replace=TRUE)]))
}

이제는 부트스트래핑으로 복원 추출을 통해 샘플을 구하고 평균을 구하는 작업을 10,000회 반복해보자.

평균의 신뢰구간은 이 평균들의 하위 2.5%, 상위 97.5%에 속하는 값의 구간이다.

bootmean <- sort(bootmean)
bootmean[c(10000*0.025, 10000*0.975)]
[1] 29.72578 30.10531

t검정과 유사한 값이 부트스트랩핑으로도 구해진것을 알 수 있다.


부트스트래핑을 사용한 모델의 정확도 평가도 마찬가지로 수행된다.

데이터의 일부를 트레이닝 데이터로, 일부를 테스트 데이터로 복원 추출을 통해서 구한다.

그리고 이를 수회 반복하여 정확도를 추정한다. 이것이 trainControl()에서 method="boot"가 하는 일이다.



.







'AI > Machine Learning with R' 카테고리의 다른 글

Cross Validation  (0) 2016.02.26
Ensemble method: Bagging (bootstrap aggregating)  (0) 2015.11.19
Principal Component Analysis (PCA)  (0) 2015.11.18
Evaluating Model Performance with R  (2) 2015.11.12
Naive Bayes with Caret package (R)  (0) 2015.11.12

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 08: Dimensionality Reduction


Dimensionality Reduction을 수행 할경우 아래와 같은 장점이 존재 한다.

데이터 압축의 효과 발생 -> 낮은 메모리 사용 디스크 공간 활용 증대 -> 속도 향상

따라서 중요하 전처리 과정중 하나이다.




Dimensonlaity Reduction의 실체


두 개의 차원의 데이터가 cminches로 나뉘어서 있다고 하자. 

높은 중복성을 가지는 데이터이다.

이것을 파란색 선으로 그어보면 새로운 일차원 데이터 구조로 만들 수 있음을 알수 있다.

2D를 1D로 바꾼 것이 된다.


또 다른 예제는 아래와 같다.

헬기 조종사의 적성을 평가할때 skill과 enjoying 두개의 요소가 있다고 하자. 두개의 관계도 대칭적이므로 일차원으로 표현 할 수 있다.

결국 아래와 같은 데이터 압축의 효과가 나타난다.


3D to 2D의 경우도 아래와 같다.


데이터 표현의 경우 아래와 같다. 50개의 차원을 2개의 차원으로 줄인 것이다.



D50 -> D2를 함으로써 데이터를 그래프로 표현 할 수 있게 되었다.






Principal Component Analysis (PCA)


블루 라인이 projection error 이다.

이것은 sum of squares of these little blue line segments is minimized로 구해진다.

즉 최소제곱법 합으로 구해진다.


PCA는 이러한 최소화된 project 방법을 찾는 알고리즘이다.

mean normalization at feature scaling 


마젠타 라인에서의 블루라인은 길기때문에 PCA를 이용해서 최적의 선을 찾아내는 것이 중요하다.



formulation으로 표현해보자.


2차원에서 1차원으로 줄일때의 필요한 방향 벡터 $u^{(1)}$를 찾는것이 중요하다.

아래와 같이 해당 벡터는 -일수도 있고 +일 수도 있다. 단위 벡터를 찾기만 하면 되지 방향은 중요하지 않다.



n차원을 k 차원으로 줄일려면 k개의 벡터를 찾는것이 된다. $u^{(1)}, u^{(2)},...,u^{(k)}$와 같이이다.


3차원 2차원 예제로 본다면 아래와 같이 k-vector들에 걸쳐 있는 linear subspace를 찾을 수 있게 된다.



PCA는 뭔가 Linear regression을 의미하는것 같지만 그것과 동일 하지는 않다.

겉으로는 비슷해 보일 지언정 정말로 다른 알고리즘이다.


선형회귀분석의 경우 블루라인의 제곱합을 최대한 작게 하는것이다.

sum of squared errors (SSE)가 가장 작아야 한다.

블루라인은 Vertical 라인이다.


하지만 PCA의 경우 vertical이 아니다.

아래의 그래프와 같이 포인트 X와 read line에 대해서 orthogonal (직교)한 최단거리를 의미하게 된다.


linear regression에서는 y를 predict 하기 위해서 x를 사용하는 것이 된다.


PCA에서는 distinguished y, special variable y 따위는 존재하지 않는다. 

즉 $x_1, x_2, ... , x_n$까지 모두 같은 동일한 것으로 다루게 된다.


아래의 예제처럼 $x_1, x_2, x_3$의 세개의 features가 존재하는 분포가 있다고 하자.

3차원 분포를 2차원으로 줄이기 위해서는 $u^{(1)}, u^{(2)}$ 두개의 방향 벡터를 찾아야 한다.

이때 $x_1, x_2, x_3$ 세개의 feature들은 모두 같은 수준이지 특별히 y가 없다.




아래의 문제를 풀면

$u^{(1)}$는 $[\frac{-1/\sqrt{2}}{1/\sqrt{2}}]$의 값을 가진다.






Principal Component Analysis (PCA)


주성분 분석은 데이터에 많은 변수가 있을 때 변수의 수를 줄이는 차원 감소(Dimensionality Reduction)기법 중 하나다.

PCA는 변수들을 주성분(Principal Component)이라 부르는 선형적인 상관관계가 없는 다른 변수들로 재표현한다.


무슨말인가 하면,


선형적인 관계가 있는 두 변수가 아래와 같이 있다고 가정해보자.

A = 2c+3

B= 3c

이다.

이때 Y = f(A,B)라는 어떤 모델이 있다고 하자.

이럴때 실제로 A,B 둘 사이에는 C라는 변수에 의한 선형적 관계가 있는데 둘 다 이용해서 Y를 예측하는 모델을 생성할 필요가 있을까?

이와 같을 때는 f(A,B)로 Y를 예측하기 보다는 그냥 f(C)로 Y를 예측하는것이 더 좋다.


Principal component들은 원 데이터의 분산(퍼짐 정도)을 최대한 보존하는 방법으로 구한다.

좀 더 자세한 내용은 아래의 이전 포스트를 참조하자.

practical machine learning (johns hopkins)

machine learning (standford)



R을 이용해서 실제로 적용해 보기 [R프로그래밍 실습서]


pincomp() 함수 또는 preComp()를 이용한다.


pincomp: 주성분 분석을 수행 한다.

x, # 행렬 또는 데이터 프레임

cor=FASLE # cor=FALSE면 공분산 행렬, TRUE면 상관 행렬을 사용한 주성분 분석을 한다.


아래와 같이 1:10을 저장한 x

약간의 noise를 추가한 y. 즉 x + noise = y 이다.

마지막으로 z는 x + y 에 noise를 추가한 것이다.

x <- 1:10

y <- x + runif(10, min=-.5, max=.5)

z <- x + y + runif(10, min=-10, max=.10)

data frame으로 내용을 출력해보면 아래와 같다.

> (data <- data.frame(x,y,z))

    x         y          z

1   1  1.413629 -0.5826325

2   2  2.021631 -0.9343342

3   3  3.045810 -3.1059315

4   4  3.857941  6.3310046

5   5  5.418124  0.4202864

6   6  6.306387  6.6968121

7   7  7.488154 13.1231456

8   8  8.148416 12.0075606

9   9  9.260750 10.7979732

10 10 10.086332 16.6841931


# do PCA using data

pr <- princomp(data)

summary(pr)


Importance of components:

                          Comp.1    Comp.2       Comp.3

Standard deviation     7.5667362 1.5335677 0.1356764036

Proportion of Variance 0.9602481 0.0394432 0.0003087272

Cumulative Proportion  0.9602481 0.9996913 1.0000000000


위 데이터들은 주성분들이 원 데이터의 분산 중 얼마만큼을 설명해 주는지를 알 수 있다.

Proportion of Variance 행을 보면 첫 번째 주성분은 데이터의 분산 중 92.86%를 설명해 주며,

두 번째 주성분은 데이터의 분산 중 7.1%를 설명함을 알 수 있다.

세 번째 주성분은 가장작은 0.03%의 분산을 설명 한다.

마지막 행의 Cumulative Proportion은 Proportion of Variance의 누적 값이다.


결국 원 데이터의 분산은 첫 번째와 두 번째 주성분에 의해 99.97%가 포함됨을 알 수 있다.

이들 두 주성분상의 좌표는 scores를 보고 구하면 된다.


결국 x,y,z의 데이터 분포는 그냥 2개의 차원으로 축소가 된것이다. 아래와 같은 좌표값을 가지게 된다.

> pr$scores[,1:2]

           Comp.1      Comp.2

 [1,]   8.9555327  1.91623469

 [2,]   8.6788410  0.76263371

 [3,]   9.8173286 -1.57583908

 [4,]   1.0457826  2.13444485

 [5,]   5.2072178 -2.44130849

 [6,]  -0.8729855 -0.38916205

 [7,]  -7.1881748  1.55801181

 [8,]  -6.8265993 -0.01728680

 [9,]  -6.5475880 -1.91981691

[10,] -12.2693552 -0.02791173



알츠하이머(Alzheimer)를 이용한 예제 [Practical Machine Learning HW-2]


데이터를 불러온다.

set.seed(3433)

library(AppliedPredictiveModeling)

data(AlzheimerDisease)

adData = data.frame(diagnosis, predictors)

inTrain = createDataPartition(adData$diagnosis, p = 3/4)[[1]]

training = adData[inTrain, ]

testing = adData[-inTrain, ]


위 데이터 셋에서 "IL"로 시작하는 트레이닝 셋 variables(변수)들에 대해서만 PCA를 수행한다.

preProcess()를 이용하며, PCA 수행결과 80%의 variance(분산)를 capture할 수 있는 변수들의 갯수를 결정해 보자.


먼저 grep과 정규표현으로 해당 열 데이터를 수집한다.

IL_str <- grep("^IL", colnames(training), value = TRUE)


아래와 같이 caret package의 preProcess()를 이용해서 pca를 수행한다. 임계값은 80%이다.

preProc <- preProcess(training[, IL_str], method = "pca", thresh = 0.8)


실행 결과 총 12개의 IL 변수중 7개만으로 원래 데이터 분포의 80%수준의 분산을 설명 할 수 있음을 알 수 있다.

preProc$rotation

                      PC1           PC2           PC3          PC4         PC5          PC6         PC7

IL_11         -0.06529786  0.5555956867  0.2031317937 -0.050389599  0.73512798 -0.102014559  0.20984151

IL_13          0.27529157  0.3559427297 -0.0399010765  0.265076920 -0.25796332 -0.068927711  0.58942516

IL_16          0.42079000  0.0007224953  0.0832211446 -0.082097273  0.04435883 -0.007094672 -0.06581741

IL_17E        -0.01126118  0.5635958176  0.3744707126  0.302512329 -0.38918707  0.221149380 -0.46462692

IL_1alpha      0.25078195 -0.0687043488 -0.3008366900  0.330945942  0.16992452  0.742391473  0.12787035

IL_3           0.42026485 -0.0703352892 -0.1049647272 -0.065352774  0.02352819 -0.165587911 -0.09006656

IL_4           0.33302031  0.0688495706 -0.1395450144  0.165631691 -0.14268797 -0.297421293  0.19661173

IL_5           0.38706503 -0.0039619980  0.0005616126 -0.224448981  0.08426042  0.153835977 -0.16425757

IL_6           0.05398185 -0.4248425653  0.6090821756  0.417591202 -0.00165066 -0.166089521  0.21895103

IL_6_Receptor  0.21218980  0.1005338329  0.2920341087 -0.659953479 -0.29654048  0.138000448  0.22657846

IL_7           0.32948731  0.0806070090 -0.1966471906  0.165544952  0.11373532 -0.405698338 -0.42065832

IL_8           0.29329723 -0.1883039842  0.4405255221  0.002811187  0.28608600  0.184321013 -0.14833779



이전과 같이 princomp를 수행하면 아래와 같다.

summary(princomp(training[, IL_str]))

                          Comp.1    Comp.2    Comp.3     Comp.4    Comp.5     Comp.6     Comp.7     Comp.8     Comp.9    Comp.10      Comp.11
Standard deviation     1.4947237 1.2328654 1.1784414 0.62482551 0.5437811 0.40042942 0.36239787 0.30216932 0.25401803 0.25223488 0.0286080996
Proportion of Variance 0.3523411 0.2397026 0.2190067 0.06156856 0.0466326 0.02528678 0.02071156 0.01439933 0.01017585 0.01003348 0.0001290683
Cumulative Proportion  0.3523411 0.5920437 0.8110505 0.87261902 0.9192516 0.94453840 0.96524995 0.97964928 0.98982513 0.99985861 0.9999876814
                            Comp.12
Standard deviation     8.838105e-03
Proportion of Variance 1.231856e-05
Cumulative Proportion  1.000000e+00



PCA가 정확도에 미치는 영향을 glm 모델을 만들어서 알아보자 [Practical Machine Learning HW-2]



set.seed(3433)

library(AppliedPredictiveModeling)

data(AlzheimerDisease)

adData = data.frame(diagnosis, predictors)

inTrain = createDataPartition(adData$diagnosis, p = 3/4)[[1]]

training = adData[inTrain, ]

testing = adData[-inTrain, ]


set.seed(3433)

## grep the predictors starting with 'IL'

IL_str <- grep("^IL", colnames(training), value = TRUE)

## make a subset of these predictors

predictors_IL <- predictors[, IL_str]

df <- data.frame(diagnosis, predictors_IL)

inTrain = createDataPartition(df$diagnosis, p = 3/4)[[1]]

training = df[inTrain, ]

testing = df[-inTrain, ]



PCA를 적용하지 않은 glm 모델

## train the data using the first method

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

predictions <- predict(modelFit, newdata = testing)

## get the confustion matrix for the first method

C1 <- confusionMatrix(predictions, testing$diagnosis)

print(C1)


Confusion Matrix and Statistics


          Reference

Prediction Impaired Control

  Impaired        2       9

  Control        20      51

                                         

               Accuracy : 0.6463         

                 95% CI : (0.533, 0.7488)

    No Information Rate : 0.7317         

    P-Value [Acc > NIR] : 0.96637        

                                         

                  Kappa : -0.0702        

 Mcnemar's Test P-Value : 0.06332        

                                         

            Sensitivity : 0.09091        

            Specificity : 0.85000        

         Pos Pred Value : 0.18182        

         Neg Pred Value : 0.71831        

             Prevalence : 0.26829        

         Detection Rate : 0.02439        

   Detection Prevalence : 0.13415        

      Balanced Accuracy : 0.47045        

                                         

       'Positive' Class : Impaired 


PCA를 적용해서 수행한 결과이다.

# prediction with PCA

A1 <- C1$overall[1]


## do similar steps with the caret package

modelFit <- train(training$diagnosis ~ ., method = "glm", preProcess = "pca", 

                  data = training, trControl = trainControl(preProcOptions = list(thresh = 0.8)))

C2 <- confusionMatrix(testing$diagnosis, predict(modelFit, testing))

print(C2)


Confusion Matrix and Statistics


          Reference

Prediction Impaired Control

  Impaired        3      19

  Control         4      56

                                          

               Accuracy : 0.7195          

                 95% CI : (0.6094, 0.8132)

    No Information Rate : 0.9146          

    P-Value [Acc > NIR] : 1.000000        

                                          

                  Kappa : 0.0889          

 Mcnemar's Test P-Value : 0.003509        

                                          

            Sensitivity : 0.42857         

            Specificity : 0.74667         

         Pos Pred Value : 0.13636         

         Neg Pred Value : 0.93333         

             Prevalence : 0.08537         

         Detection Rate : 0.03659         

   Detection Prevalence : 0.26829         

      Balanced Accuracy : 0.58762         

                                          

       'Positive' Class : Impaired      


적용전 0.65

적용후 0.72


결국 dimentionality reduction이 정확도 향상에도 기여한다는 것을 알 수 있다.





TensorFlow 개발환경 ( Eclipse + PyDev, Pycharm, Jupyter)



TensorFlow 설치법과 PyDev 설치법은 이전에 다뤘다.

원할한 개발을 위해서 PyDev에 TensorFlow를 연결하는것을 다룬다.


우선 필자는 TensorFlow를 Virtualenv에다가 설치 했다. VirtualEnv를 설치하는 이유는 아래와 같다.

Here's the short version: pip lets you install packages (Python libraries). Usually, you do not want to install packages globally, for the entire system, because they may conflict with each other. Instead, you want each Python project you create to have its own isolated ecosystem. Virtualenv provides this isolation. Virtualenvwrapper makes virtualenv nicer to use.


Even if you're not worried about conflicts, virtualenv can help you make sure your demo still works years from now (especially important if you care about reproducible research). The fact is that libraries aren't always perfectly backward-compatible or bug-free. You may upgrade a package and find that it breaks your project. The more time passes since you last ran a piece of code, the more likely it is to be broken. Using a virtualenv to freeze the dependencies is a safeguard against this problem.



PyDev의 VirtualEnv 설정 연결


PyDev와 TensorFlow 그리고 virtualenv가 모두 설치되었어야 한다.


Eclipse 메뉴에서

Preferences -> PyDev > Interpreters > Python 메뉴에서

New를 눌러서 Browse를 통해서 설정한 virtualenvs를 등록해준다.

<venv-name>/bin/python


등록할때 모든 종속 라이브러릴 같이 등록해준다. 팝업이 나오면 다 선택된 상태로 등록하면 된다.






프로젝트 생성 및 "Hellow Tensor"실행


아래와 같이 프로젝트를 생성 할 때 interpreter를 생성한 virtualenv용 python 환경으로 잘 선택해 줘야 한다.



그다음 Hello tensorflow 코드를 실행하면 정상적으로 실행 되는것을 알 수 있다.

'''
Created on Nov 17, 2015

@author: root
'''
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print sess.run(hello)

a = tf.constant(10)
b = tf.constant(32)
print sess.run(a+b)





IntelliJ 기반의 Pycharm


설치방법: 이전포스트


실행 모습



아래와 같이 Tensorflow가 있는 virtualenv를 interpreter로 설정을 해주어야 한다.





웹기반 Jupyter로 실행하기


설치방법: 이전포스트




'AI > TensorFlow, PyTorch, Keras, Scikit' 카테고리의 다른 글

Softmax Function  (0) 2016.04.19
Neural Networks in XOR problem  (0) 2016.04.18
Logistic Regression  (0) 2016.04.17
Linear regression with TensorFlow  (0) 2016.04.17
TensorFlow 설치 및 예제 실행 (uBuntu)  (2) 2015.11.17

TensorFlow 설치 및 예제 실행 (uBuntu)


2015.11.9일에 공개된 오픈프로젝트 TensorFlow는 Google에서 공개한 DeepLearning을 위한 2세대 system이다.

TensorFlow의 내용은 이전 Post를 참조 한다.

이 시스템의 설치와 실행을 다룬다.



Python VirtualEnv에 기반한 설치 방법


필자가 사용하는 Desktop PC의 환경은 아래와 같다.


설치환경

uBuntu 14.04 64bit (LTS)

VMware based

python 2.7 (설치법 참조)


필자는 VirtualEnv-based Installation을 수행한다(VirtualEnv 설치).

VirtualEnv 환경을 python 자체가 지원하므로 고립된 수행 환경을 생성할 수 있는 이점이 있다. 문제 발생시에도 모든 사람이 같은 상황이므로 해결방법을 그대로 적용할 수 있는 장점이 있다.

#Next, set up a new virtualenv environment. To set it up in the directory ~/tensorflow, run:
$ virtualenv --system-site-packages ~/tensorflow
$ cd ~/tensorflow

tensorflow는 이제 가상환경이 저장되는 디렉터리가 된다.

--system-site-packages 옵션의 의미는 가상환경에게 global site-package의 접근 권한을 허용 하는 것이다.

아래의 경로에 해당 가상환경에만 적용되는 site-package들이 저장되어 있다.

~/tensorflow/lib/python2.7/site-packages

아래의 경로에는 해당 가상환경에서 사용 할 수 있는 python의 종류이다.

~/tensorflow/lib/


virtualenv를 활성화 시킨다.

$ source (설치경로)/bin/activate  # If using bash
source ./tensorflow/bin/activate #나의 경우 

비활성화는 deactivate라고 치면된다.


만약 csh 쉘을 쓴다면 아래의 명령어이다.

$ source bin/activate.csh  # If using csh

최종적으로 아래처럼 프롬프트 창의 이름 앞에 (tensorflow)가 들어가는 것을 볼 수 있다.

(tensorflow)root@jemin-virtual-machine:

실행된 virtualenv의 환경에서 TensorFlow를 설치한다.

설치 종류는 CPU-only version과 GPU-enabled version이 있으므로 자신이 원하는것을 선택하자.

필자는 일단 CUDA sdk를 설치하지 않았으므로 CPU-only를 설치했다.

# For CPU-only version
$ pip install https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.5.0-cp27-none-linux_x86_64.whl

# For GPU-enabled version (only install this version if you have the CUDA sdk installed)
$ pip install https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow-0.5.0-cp27-none-linux_x86_64.whl

이렇게까지 하면 tensorFlow는 설치가 된것이다.

이제 간단한 예제를 실행해보자.


Hello, TensorFlow

Hello, TensorFlow
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> hello = tf.constant("Hello, TensorFlow!")
>>> sess = tf.Session()
I tensorflow/core/common_runtime/local_device.cc:25] Local device intra op parallelism threads: 8
I tensorflow/core/common_runtime/local_session.cc:45] Local session inter op parallelism threads: 8
>>> print sess.run(hello)
Hello, TensorFlow!
>>> a = tf.constant(10)
>>> b = tf.constant(32)
>>> print sess.run(a+b)
42
(tensorflow)root@jemin-virtual-machine:~/tensorflow# 
위와 같이 실행되면, 정상적으로 설치가 된것이다.


삼차원 데이터를 100개 생성하고 그것에 딱 맞는 초평면을 생성하는 예제이다.
# Make 100 phony data points in NumPy.
x_data = np.float32(np.random.rand(2, 100)) # Random input
y_data = np.dot([0.100, 0.200], x_data) + 0.300

# Construct a linear model.
b = tf.Variable(tf.zeros([1]))
W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0))
y = tf.matmul(W, x_data) + b

# Minimize the squared errors.
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)

# For initializing the variables.
init = tf.initialize_all_variables()

# Launch the graph
sess = tf.Session()
sess.run(init)

# Fit the plane.
for step in xrange(0, 201):
    sess.run(train)
    if step % 20 == 0:
        print step, sess.run(W), sess.run(b)

# Learns best fit is W: [[0.100  0.200]], b: [0.300]
I tensorflow/core/common_runtime/local_device.cc:25] Local device intra op parallelism threads: 8
I tensorflow/core/common_runtime/local_session.cc:45] Local session inter op parallelism threads: 8
Hello, TensorFlow!
42
0 [[ 0.3138563   0.52770293]] [-0.0221094]
20 [[ 0.17014106  0.30057704]] [ 0.20599112]
40 [[ 0.12187628  0.23032692]] [ 0.27126268]
60 [[ 0.10676718  0.20918694]] [ 0.29121917]
80 [[ 0.10208294  0.2027912 ]] [ 0.29731771]
100 [[ 0.10063919  0.20084961]] [ 0.29918078]
120 [[ 0.10019579  0.20025893]] [ 0.29974979]
140 [[ 0.1000599   0.20007896]] [ 0.2999236]
160 [[ 0.10001831  0.2000241 ]] [ 0.29997668]
180 [[ 0.1000056   0.20000736]] [ 0.29999286]
200 [[ 0.1000017   0.20000222]] [ 0.29999784]

위와 같이 점차 반복수행 하면서, best fit인 0.1, 0.2, 0.3에 근접하는 것을 알 수 있다.



신경망 모델링 실행

이제 TensorFlow를 이용해서 이제 DeepLearning 예제를 실행해 보자.

실행할 예제는 신경망 모델링에 관한것이다.


일단 gitHub에서 TensorFlow 소스코드를 복제(clone)해와야 한다.

tensorflow)root@jemin-virtual-machine: git clone https://github.com/tensorflow/tensorflow.git

정상적으로 다운이 완료 되면, 예제를 실행 해보자.

이 예제는 "LeNet -5 - like convolutional MNIST model"이라고 한다.

(tensorflow)$ cd tensorflow/models/image/mnist
(tensorflow)$ python convolutional.py



실행결과

Initialized!
Epoch 0.00
Minibatch loss: 12.054, learning rate: 0.010000
Minibatch error: 90.6%
Validation error: 84.6%
Epoch 0.12
Minibatch loss: 3.285, learning rate: 0.010000
Minibatch error: 6.2%
Validation error: 7.0%
Epoch 0.23
Minibatch loss: 3.473, learning rate: 0.010000
Minibatch error: 10.9%
Validation error: 3.7%
Epoch 0.35
Minibatch loss: 3.221, learning rate: 0.010000
Minibatch error: 4.7%
Validation error: 3.2%
Epoch 0.47
Minibatch loss: 3.193, learning rate: 0.010000
Minibatch error: 4.7%
Validation error: 2.7%
Epoch 0.58
Minibatch loss: 3.301, learning rate: 0.010000
Minibatch error: 9.4%
Validation error: 2.5%
Epoch 0.70
Minibatch loss: 3.203, learning rate: 0.010000
Minibatch error: 6.2%
Validation error: 2.8%
Epoch 0.81
Minibatch loss: 3.022, learning rate: 0.010000
Minibatch error: 4.7%
Validation error: 2.6%
Epoch 0.93
Minibatch loss: 3.131, learning rate: 0.010000
Minibatch error: 6.2%
Validation error: 2.1%
Epoch 1.05
Minibatch loss: 2.954, learning rate: 0.009500
Minibatch error: 3.1%
Validation error: 1.6%
Epoch 1.16
Minibatch loss: 2.854, learning rate: 0.009500
Minibatch error: 0.0%
Validation error: 1.8%
Epoch 1.28
Minibatch loss: 2.825, learning rate: 0.009500
Minibatch error: 1.6%
Validation error: 1.4%
Epoch 1.40
Minibatch loss: 2.938, learning rate: 0.009500
Minibatch error: 7.8%
Validation error: 1.5%
Epoch 1.51
Minibatch loss: 2.767, learning rate: 0.009500
Minibatch error: 0.0%
Validation error: 1.9%
Epoch 1.63
Minibatch loss: 2.771, learning rate: 0.009500
Minibatch error: 3.1%
Validation error: 1.4%
Epoch 1.75
Minibatch loss: 2.844, learning rate: 0.009500
Minibatch error: 4.7%
Validation error: 1.2%
Epoch 1.86
Minibatch loss: 2.694, learning rate: 0.009500
Minibatch error: 0.0%
Validation error: 1.3%
Epoch 1.98
Minibatch loss: 2.650, learning rate: 0.009500
Minibatch error: 0.0%
Validation error: 1.5%
Epoch 2.09
Minibatch loss: 2.667, learning rate: 0.009025
Minibatch error: 1.6%
Validation error: 1.4%
Epoch 2.21
Minibatch loss: 2.658, learning rate: 0.009025
Minibatch error: 1.6%
Validation error: 1.2%
Epoch 2.33
Minibatch loss: 2.640, learning rate: 0.009025
Minibatch error: 3.1%
Validation error: 1.2%
Epoch 2.44
Minibatch loss: 2.579, learning rate: 0.009025
Minibatch error: 1.6%
Validation error: 1.1%
Epoch 2.56
Minibatch loss: 2.568, learning rate: 0.009025
Minibatch error: 0.0%
Validation error: 1.2%
Epoch 2.68
Minibatch loss: 2.554, learning rate: 0.009025
Minibatch error: 1.6%
Validation error: 1.1%
Epoch 2.79
Minibatch loss: 2.503, learning rate: 0.009025
Minibatch error: 0.0%
Validation error: 1.2%
Epoch 2.91
Minibatch loss: 2.487, learning rate: 0.009025
Minibatch error: 0.0%
Validation error: 1.2%
Epoch 3.03
Minibatch loss: 2.463, learning rate: 0.008574
Minibatch error: 1.6%
Validation error: 1.2%
Epoch 3.14
Minibatch loss: 2.458, learning rate: 0.008574
Minibatch error: 1.6%
Validation error: 1.1%
Epoch 3.26
Minibatch loss: 2.410, learning rate: 0.008574
Minibatch error: 0.0%
Validation error: 1.4%
Epoch 3.37
Minibatch loss: 2.496, learning rate: 0.008574
Minibatch error: 3.1%
Validation error: 1.3%
Epoch 3.49
Minibatch loss: 2.399, learning rate: 0.008574
Minibatch error: 1.6%
Validation error: 1.1%
Epoch 3.61
Minibatch loss: 2.377, learning rate: 0.008574
Minibatch error: 0.0%
Validation error: 1.1%
Epoch 3.72
Minibatch loss: 2.333, learning rate: 0.008574
Minibatch error: 0.0%
Validation error: 1.1%
Epoch 3.84
Minibatch loss: 2.312, learning rate: 0.008574
Minibatch error: 0.0%
Validation error: 1.2%
Epoch 3.96
Minibatch loss: 2.300, learning rate: 0.008574
Minibatch error: 1.6%
Validation error: 1.1%
Epoch 4.07
Minibatch loss: 2.276, learning rate: 0.008145
Minibatch error: 0.0%
Validation error: 1.1%
Epoch 4.19
Minibatch loss: 2.250, learning rate: 0.008145
Minibatch error: 0.0%
Validation error: 1.0%
Epoch 4.31
Minibatch loss: 2.233, learning rate: 0.008145
Minibatch error: 0.0%
Validation error: 1.0%
Epoch 4.42
Minibatch loss: 2.217, learning rate: 0.008145
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 4.54
Minibatch loss: 2.324, learning rate: 0.008145
Minibatch error: 3.1%
Validation error: 1.0%
Epoch 4.65
Minibatch loss: 2.212, learning rate: 0.008145
Minibatch error: 0.0%
Validation error: 1.0%
Epoch 4.77
Minibatch loss: 2.174, learning rate: 0.008145
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 4.89
Minibatch loss: 2.211, learning rate: 0.008145
Minibatch error: 1.6%
Validation error: 1.0%
Epoch 5.00
Minibatch loss: 2.193, learning rate: 0.007738
Minibatch error: 1.6%
Validation error: 1.0%
Epoch 5.12
Minibatch loss: 2.148, learning rate: 0.007738
Minibatch error: 3.1%
Validation error: 1.0%
Epoch 5.24
Minibatch loss: 2.153, learning rate: 0.007738
Minibatch error: 3.1%
Validation error: 1.0%
Epoch 5.35
Minibatch loss: 2.111, learning rate: 0.007738
Minibatch error: 1.6%
Validation error: 0.9%
Epoch 5.47
Minibatch loss: 2.084, learning rate: 0.007738
Minibatch error: 1.6%
Validation error: 0.8%
Epoch 5.59
Minibatch loss: 2.054, learning rate: 0.007738
Minibatch error: 0.0%
Validation error: 1.0%
Epoch 5.70
Minibatch loss: 2.043, learning rate: 0.007738
Minibatch error: 0.0%
Validation error: 1.0%
Epoch 5.82
Minibatch loss: 2.134, learning rate: 0.007738
Minibatch error: 3.1%
Validation error: 1.0%
Epoch 5.93
Minibatch loss: 2.006, learning rate: 0.007738
Minibatch error: 0.0%
Validation error: 1.0%
Epoch 6.05
Minibatch loss: 2.048, learning rate: 0.007351
Minibatch error: 3.1%
Validation error: 0.9%
Epoch 6.17
Minibatch loss: 1.988, learning rate: 0.007351
Minibatch error: 0.0%
Validation error: 1.1%
Epoch 6.28
Minibatch loss: 1.957, learning rate: 0.007351
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 6.40
Minibatch loss: 1.971, learning rate: 0.007351
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 6.52
Minibatch loss: 1.927, learning rate: 0.007351
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 6.63
Minibatch loss: 1.912, learning rate: 0.007351
Minibatch error: 0.0%
Validation error: 1.0%
Epoch 6.75
Minibatch loss: 1.901, learning rate: 0.007351
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 6.87
Minibatch loss: 1.886, learning rate: 0.007351
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 6.98
Minibatch loss: 1.894, learning rate: 0.007351
Minibatch error: 1.6%
Validation error: 1.0%
Epoch 7.10
Minibatch loss: 1.859, learning rate: 0.006983
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 7.21
Minibatch loss: 1.844, learning rate: 0.006983
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 7.33
Minibatch loss: 1.836, learning rate: 0.006983
Minibatch error: 0.0%
Validation error: 1.0%
Epoch 7.45
Minibatch loss: 1.887, learning rate: 0.006983
Minibatch error: 3.1%
Validation error: 0.9%
Epoch 7.56
Minibatch loss: 1.808, learning rate: 0.006983
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 7.68
Minibatch loss: 1.822, learning rate: 0.006983
Minibatch error: 1.6%
Validation error: 0.9%
Epoch 7.80
Minibatch loss: 1.782, learning rate: 0.006983
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 7.91
Minibatch loss: 1.772, learning rate: 0.006983
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 8.03
Minibatch loss: 1.761, learning rate: 0.006634
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 8.15
Minibatch loss: 1.773, learning rate: 0.006634
Minibatch error: 1.6%
Validation error: 0.9%
Epoch 8.26
Minibatch loss: 1.742, learning rate: 0.006634
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 8.38
Minibatch loss: 1.744, learning rate: 0.006634
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 8.49
Minibatch loss: 1.719, learning rate: 0.006634
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 8.61
Minibatch loss: 1.700, learning rate: 0.006634
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 8.73
Minibatch loss: 1.700, learning rate: 0.006634
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 8.84
Minibatch loss: 1.801, learning rate: 0.006634
Minibatch error: 1.6%
Validation error: 0.8%
Epoch 8.96
Minibatch loss: 1.666, learning rate: 0.006634
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 9.08
Minibatch loss: 1.666, learning rate: 0.006302
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 9.19
Minibatch loss: 1.649, learning rate: 0.006302
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 9.31
Minibatch loss: 1.676, learning rate: 0.006302
Minibatch error: 1.6%
Validation error: 0.8%
Epoch 9.43
Minibatch loss: 1.626, learning rate: 0.006302
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 9.54
Minibatch loss: 1.621, learning rate: 0.006302
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 9.66
Minibatch loss: 1.606, learning rate: 0.006302
Minibatch error: 0.0%
Validation error: 0.8%
Epoch 9.77
Minibatch loss: 1.596, learning rate: 0.006302
Minibatch error: 0.0%
Validation error: 0.9%
Epoch 9.89
Minibatch loss: 1.602, learning rate: 0.006302
Minibatch error: 0.0%
Validation error: 0.9%
Test error: 0.8%

실행 시간은 아래와 같다.

- MNIST -

real 26m26.382s

user 77m58.714s

sys 19m21.539s


가상화 환경에서 CPU만 가지고 처리해서 오래걸린것 같다.

그래도 i7 4세대 프로세서, ram 24gb, ssd pro 256gb에서 실행한것인데, 대략 Android 5.0 컴파일 시간의 반 정도의 시간이 걸린것 같다.








Python 설치법, 환경설정, IDE 설정


python 설치방법 -기본



Python 2.7 버전 설치

sudo apt-get install python


수동 설치 (비추천)

#download using the following command:
cd ~/Downloads/
wget https://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz

#Extract and go to the directory:
tar -xvf Python-2.7.9.tgz
cd Python-2.7.9

#Now, install using the command you just tried:
./configure
make
sudo make install


우분투에서 python3을 default로 잡지 않은 이유는 다음과 같다.

1) 우분투는 python 2.x의 스크립트를 많이 이용하고 있다.

2) python 2와 python3은 서로를 완전히 보완하지 못한다. 버전간의 충돌이 있다.

3) python 2.7은 지속적으로 bugfix가 되며, 2020년까지는 지원을 해준다고 한다.

4) 대부분의 python script는 명시적으로 #!/usr/bin.env python 이라고만 명시하는데, 만약 /usr/bin/python을 python3으로 변경 한다면, #/usr/bin/env python2라고 명시한 스크립트를 제외하고는 python2에서만 동작하는 스크립트가 문제가 생기게 된다.




python 설치방법 - Virtualenv 




Python VirtuaEnv


Virtualenv is a tool to reate isolated Python environment
만약 서로다른 version app이 서로다른 version의 python library를 사용하다면 그것은 하나의 컴퓨터 환경에서는 지원해 주기 어렵게 된다.
``/usr/lib/python2.7/site-packages``
라이브러리만 업데이트할경우 떄떄로 응용프로그램이 망가진다.
때때로 global “site-packages”에다가 package를 설치하고 싶지 않을 수도 있다.
모든 경우에 대해서 virtualenv는 도움을 줄 수 있다. 이것은 어떠한 독립적인 하나의 installation environment를 생성 한다.

좀 더 장점에대해서 알고싶으면 blog를 참조하자.

설치방법
# On Linux:
$ sudo apt-get install python-pip python-dev python-virtualenv
#활성화 방법
source (설치경로)/bin/activate #일반적인 경우
source ./tensorflow/bin/activate #나의 경우
#비활성화 방법
deactivate


IDE 설정 - PyDev (Eclipse)


필자는 PyDev를 사용한다.

하지만 다른 IDE가 궁금하다면 10 Best Python IDE for Developers를 읽어보자.


필자가 PyDev를 선택한 이유는 간단하다. Eclipse 기반의 Plugin으로써 Eclipse의 개발 경험을 그대로 활용할 수 있기 때문이다.

그리고 commercial IDE는 사용하고 싶지 않기 때문이다.


설치방법

Help -> Install New Software -> Add

Name: Pydev and Pydev Extensions

Location: http://pydev.org/updates







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




Google의 오픈소스 머신러닝 시스템, TensorFlow


2015.11.9일 구글이 자시들의 Machine Learning Platform TensorFlow를 공개 했다.




공식 사이트: http://tensorflow.org/

GitHub: https://github.com/tensorflow/tensorflow

ResearchBlog: http://googleresearch.blogspot.kr/


이것은 구글이 2011년부터 내부에서 사용해오던 DeepLearning Infrastructure인 "DistBelief"의 후속 버전이다.


DistBelief는 지금까지 음성인식, 지메일 스팸 방지, 유튜브 동영상 썸네일 제작, 유트부 영상에서 고양이 인식 등의 딥러닝을 적용한 구글의 서비스와 연구에 사용된 것이다.


이번에 공개된 TensorFlow는 이러한 DistBelief의 성능과 사용편의성을 개선한 2세대 머신 러닝 시스템이라고 할 수 있다.




GoogleResearch - TensorFlow, Google's latest machine learning system, open sourced for everyone.


작성자: Jeff Dean (Senior Google Fellow) and Rajat Monga (Technical Lead)


2011년 부터 사용된 DistBelief 구글의 DeepLearning 플랫폼은 Find "cat", speech recognition, Google Photos, Large Scale Visual Recognition Challegne in 2014, and automated image captioning 그리고 DeepDread 에서 성공적인 결과를 보였다.


하지만, DistBelief는 너무나 Google의 내부 구조와 결집되어 있기 때문에 그동안 공개하기가 어려웠다.


2015.11.9일 구글은 마침내 2세대 머신러닝 시스템인 TensorFlow를 공개한다. 이것은 그동안의 단점을 모두 보완 했으며, flexible, portable, easy to use, and completely open source이다.

또한 구글의 Technical report에 따르면 TensorFlow는 특정 BanchMark에 대해서 2배 가량 DistBreief보다 빠르다고 한다.


이제 non-learning tool과 learning too로 양분화 대며, 모든 non-learning tool들은 점차 대체될 것이다.

바야흐로 새로운 시대가 열렸다.



TensorFlow의 특징


일단은 구글이 사용하는 버전과 다르게 단일 컴퓨터에서 다중 GPU를 지원하여 동작하는것 같다.

Jeff Dean의 말에 따르면 이것은 기존의 Deep Learning library인 Torch, Caffe, Theano의 장점을 가져온 것이라고 한다.

즉, Torch와 Theano 처럼 research idea를 구현하기 쉽고 Caffe처럼 실제 product에 구현하기 쉽게 만든것이 Tensorflow이라는 것이다.


참고문헌: http://www.wired.com/2015/11/google-open-sources-its-artificial-intelligence-engine/





'Computer Science > IT Issue' 카테고리의 다른 글

광선검(lightsaber)는 어떻게 만들 것인가?  (0) 2015.12.13
2015의 스마트 기기들 (gadgets)  (0) 2015.11.26
No, you can't have it all  (0) 2015.10.23
Sensing Emotions (Affective Computing)  (0) 2015.10.22
Google Alphabet  (0) 2015.08.12

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

















Evaluating Model Performance with R


이론적인 부분은 아래의 이전 포스트를 확인한다.




Confusion Matrix


가장 쉽게 생성할 수 있는 방법은 table()을 이용 하는 것이다.

vec1 <- factor(c("ham","ham","spam","ham"))
vec2 <- factor(c("spam","ham","spam","ham"))
> table(vec1,vec2)
      vec2
vec1   ham spam
  ham    2    1
  spam   0    1


좀더 상세한 결과를 원한다면, gmodels package의 CrossTable() function을 사용하자.

default로써 CrossTable() output으로써 proportion값을 포함하고 있다.

> class(sms_test_pred)
[1] "factor"
> class(sms_raw_test$type)
[1] "factor"
> CrossTable(sms_test_pred, sms_raw_test$type)

 
   Cell Contents
|-------------------------|
|                       N |
| Chi-square contribution |
|           N / Row Total |
|           N / Col Total |
|         N / Table Total |
|-------------------------|

 
Total Observations in Table:  1390 

 
              | sms_raw_test$type 
sms_test_pred |       ham |      spam | Row Total | 
--------------|-----------|-----------|-----------|
          ham |      1202 |        31 |      1233 | 
              |    16.109 |   106.250 |           | 
              |     0.975 |     0.025 |     0.887 | 
              |     0.996 |     0.169 |           | 
              |     0.865 |     0.022 |           | 
--------------|-----------|-----------|-----------|
         spam |         5 |       152 |       157 | 
              |   126.514 |   834.437 |           | 
              |     0.032 |     0.968 |     0.113 | 
              |     0.004 |     0.831 |           | 
              |     0.004 |     0.109 |           | 
--------------|-----------|-----------|-----------|
 Column Total |      1207 |       183 |      1390 | 
              |     0.868 |     0.132 |           | 
--------------|-----------|-----------|-----------|

위 데이터를 가지고 직접 precision, recall, accuracy, error rate 등을 계산 하면 된다.





Beyond accuracy, other measures of performance


자동 계산을 위해서는 또 다른 package인 caret을 사용 한다.

해당 package는 classificationregression training에 대한 정보를 담고 있으며, Max Kuhn에 의해서 만들어 졌다.


preparing, training, evaluating, and visualizing machine learning models and data 등을 지원 한다.


Journal of statistical software에 "Building predictive models in R using the caret package."을 보면 상세한 내용을 알 수 있다.


아래와 같이 사용하며, 단지 positive label이 무엇인지만 정의해 주면 된다. 

> library(caret)
필요한 패키지를 로딩중입니다: lattice
필요한 패키지를 로딩중입니다: ggplot2
> confusionMatrix(sms_test_pred, sms_raw_test$type, positive = "spam")
Confusion Matrix and Statistics

          Reference
Prediction  ham spam
      ham  1202   31
      spam    5  152
                                          
               Accuracy : 0.9741          
                 95% CI : (0.9643, 0.9818)
    No Information Rate : 0.8683          
    P-Value [Acc > NIR] : < 2.2e-16       
                                          
                  Kappa : 0.8795          
 Mcnemar's Test P-Value : 3.091e-05       
                                          
            Sensitivity : 0.8306          
            Specificity : 0.9959          
         Pos Pred Value : 0.9682          
         Neg Pred Value : 0.9749          
             Prevalence : 0.1317          
         Detection Rate : 0.1094          
   Detection Prevalence : 0.1129          
      Balanced Accuracy : 0.9132          
                                          
       'Positive' Class : spam    


이제 일반적인 statistics를 알아보자.


■ The kappa statistic





■ Leave One Out Cross - Validation


cross validation 방법의 일종으로써


총 N개의 샘플을 생성 한다.

이때 N개는 해당 데이터 셋의 샘플들의 총 수를 말한다

즉, 100개의 데이터 샘플이 있다면 N은 100이다.


이에대해서 이제 N개의 모델을 생성 한다. 그리고 각각의 모델을 생성할때

하나의 샘플씩을 제외한다. 즉 N개의 모델은 N-1개의 샘플 수로 만들어지는 것이다.


그리고 각각의 모델에 대해서 그 제외한 샘플 1개를 이용해서 test를 수행한다.

그렇게 나온 test 결과 N개에대한 평균 값을 구하게 된다.



MSE가 측정 방법이라고 한다면 아래의 식과 같다.

$MSE_{ i }=(y_{ 2 }-\hat { y_{ 2 } } )^{ 2 }$


구하려고 하는 성능의 척도는 결국 아래와 같다.

$CV_{(n)}=\frac{1}{n}\sum_{i=1}^{n}{MSE_{i}}$



LOOCV의 장점은 결국 모든 샘플에 대해서 다 한번씩은 test하는 것이 되므로

어떠한 랜덤성도 존재하지 않게 된다. 따라서 굉장히 stable한 결과를 얻을 수 있다.


단점으로는 N개의 모델을 만들어서 N번 테스트 하게 되므로 computing time이 굉장히 오래 걸리게 된다.

또한 K-fold Cross validation에 비해서 bias의 비중이 높게 된다. 증 다양성을 포함하기 어렵게 된다.


아래는 작업을 수행한 코드이다.

# LOOCV 처리방법
library(ISLR)
glm.fit=glm(mpg~horsepower, data=Auto) #mpg를 horsepower에 대해서 linear regression을 힙니다.
library(boot) #cv.glm을 사용하기 위한 라이브러리입니다.
cv.err=cv.glm(Auto, glm.fit) #cv.glm함수를 통해 LOOCV를 시행합니다.
cv.err$delta #delta는 cross-validation 결과들을 담고 있습니다.

#linear model, polynomial model에 한해서 LOOCV에 간단한 형태의 공식을 사용할 수 있습니다.
loocv=function(fit){
    h=lm.influence(fit)$h
    mean((residuals(fit)/(1-h))^2)
}

loocv(glm.fit)

cv.error=rep(0,5)
degree=1:5 #1차부터 5차함수까지 fitting해 봅시다.
for(d in degree){
    glm.fit=glm(mpg~poly(horsepower,d), data=Auto) #poly함수를 이용해 d차 함수를 fit할 수 있습니다.
    cv.error[d]=loocv(glm.fit) #LOOCV 결과를 각 벡터에 저장합니다.
}
plot(degree,cv.error,type="b") #LOOCV 결과를 plot합니다.



5차원에서 가장 에러가 적은것을 알 수 있다.


자료출처: https://smlee729.github.io/r/machine%20learning/2015/03/19/1-loocv.html



















Naive Bayes with Caret package


이전 포스트에서 e1071 package로 구현 했던 것을 다시 caret package로 구현 한다.
caret package에는 많은 기능들이 포함되어 있으고 더 강력한것 같다.

Preliminary information

data set은 같은 것을 사용함.

  • 추가 package 사용 목록
  • caret package 사용
  • tm package 사용
  • pander package 사용: 출력을 보기좋게 표로 나타내줌.
  • doMC package: 멀티코어 병렬처리 가능. 하지만 내부적으로 Fork()를 이용해서 구현했기 때문에 Linux 환경에서만 동작 한다.
  • 몇가지 도우미 함수들 정의

Import Packages

# libraries needed by caret
library(klaR)
library(MASS)
# for the Naive Bayes modelling
library(caret)
# to process the text into a corpus
library(tm)
# to get nice looking tables
library(pander)
# to simplify selections
library(dplyr)

# doMC package use fork() internally. so, it it not working in Window OS.
#library(doMC)
#registerDoMC(cores=4)

# a utility function for % freq tables
frqtab <- function(x, caption) {
    round(100*prop.table(table(x)), 1)
}

# utility function to summarize model comparison results
sumpred <- function(cm) {
    summ <- list(TN=cm$table[1,1],  # true negatives
                 TP=cm$table[2,2],  # true positives
                 FN=cm$table[1,2],  # false negatives
                 FP=cm$table[2,1],  # false positives
                 acc=cm$overall["Accuracy"],  # accuracy
                 sens=cm$byClass["Sensitivity"],  # sensitivity
                 spec=cm$byClass["Specificity"])  # specificity
    lapply(summ, FUN=round, 2)
}

Reading and Preparing the data

다운로드 받아서 수행하는 것은 잘 안된다.

이전 POST의 e1071에 업로드한 csv 파일을 다운받아서 
데이터를 R object로 생성하는것은 똑같이 진행 한다.

# read the sms data into the sms data frame
sms_raw <- read.csv("sms_spam.csv", stringsAsFactors = FALSE)

sms_raw[1072,"text"] <- c("All done, all handed in. Don't know if mega shop in asda counts as celebration but thats what i'm doing!")
sms_raw[1072,"type"] <- c("ham")

# examine the structure of the sms data
str(sms_raw)

# convert spam/ham to factor.
sms_raw$type <- factor(sms_raw$type)

# examine the type variable more carefully
str(sms_raw$type)
table(sms_raw$type)

# build a corpus using the text mining (tm) package
library(tm)

# try to encode again to UTF-8
sms_raw$text <- iconv(enc2utf8(sms_raw$text),sub="byte")

sms_corpus <- Corpus(VectorSource(sms_raw$text))

# examine the sms corpus
print(sms_corpus)
inspect(sms_corpus[1:3])

Output

<<VCorpus>>
Metadata:  corpus specific: 0, document level (indexed): 0
Content:  documents: 3

[[1]]
<<PlainTextDocument>>
Metadata:  7
Content:  chars: 49

[[2]]
<<PlainTextDocument>>
Metadata:  7
Content:  chars: 23

[[3]]
<<PlainTextDocument>>
Metadata:  7
Content:  chars: 43

Preparing the data

이전에 수행한 방식과 마찬가지로 data cleanup 및 transformation을 수행한다.
이때 dplyr 문법을 사용해서 작업을 수행 한다.
아래의 명령어를 수행하면 상용법을 알수 있다.

browseVignettes(package = "dplyr")
# ------------------------------------
# ------------------------------------
# We will proceed in similar fashion as described in the book, but make use of "dplyr"
# syntax to execute the text cleanup / transformation operations
sms_corpus <- Corpus(VectorSource(sms_raw$text))
sms_corpus_clean <- tm_map(sms_corpus, content_transformer(tolower))
sms_corpus_clean <- tm_map(sms_corpus_clean, removeNumbers)
sms_corpus_clean <- tm_map(sms_corpus_clean, removeWords, stopwords())
sms_corpus_clean <- tm_map(sms_corpus_clean, removePunctuation)
sms_corpus_clean <- tm_map(sms_corpus_clean, stripWhitespace)

sms_dtm <- DocumentTermMatrix(sms_corpus_clean)

Creating a Classification model with Naive Bayes

1. Generating the training and testing datasets

데이터를 분할하고
분할한 training set과 test set 모두에서 spam의 비율을 똑같이 설정 한다.
이전과 다른것은 Data 분할을 createDataPartition()을 이용해서 분할 한다는 것이다.

# -----------------------------------
# Creating a classificiation model with Naive Bayes
# Generating the training and testing datasets
train_index <- createDataPartition(sms_raw$type, p=0.75, list=FALSE)
sms_raw_train <- sms_raw[train_index,]
sms_raw_test <- sms_raw[-train_index,]
sms_corpus_clean_train <- sms_corpus_clean[train_index]
sms_corpus_clean_test <- sms_corpus_clean[-train_index]
sms_dtm_train <- sms_dtm[train_index,]
sms_dtm_test <- sms_dtm[-train_index,]

# check proportions in the testing and training sets 
ft_orig <- frqtab(sms_raw$type)
ft_train <- frqtab(sms_raw_train$type)
ft_test <- frqtab(sms_raw_test$type)
ft_df <- as.data.frame(cbind(ft_orig, ft_train, ft_test))
colnames(ft_df) <- c("Original", "Training set", "Test set")
pander(ft_df, style="rmarkdown",
       caption=paste0("Comparison of SMS type frequencies among datasets"))

|       |  Original  |  Training set  |  Test set  |
|:----------:|:----------:|:--------------:|:----------:|
|  **ham**   |    86.6    |      86.5      |    86.6    |
|  **spam**  |    13.4    |      13.5      |    13.4    |

Table: Comparison of SMS type frequencies among datasets

일정 이상 빈도인 것들만 추려내며
Absent 와 Present 이진데이터로 변경 한다.

# we will pick terms that appear at least 5 times in the training doucment term matrix.
sms_dict <- findFreqTerms(sms_dtm_train, lowfreq=5)
sms_train <- DocumentTermMatrix(sms_corpus_clean_train, list(dictionary=sms_dict))
sms_test <- DocumentTermMatrix(sms_corpus_clean_test, list(dictionary=sms_dict))
# modified sligtly fron the code in the book
convert_counts <- function(x) {
    x <- ifelse(x > 0, 1, 0)
    x <- factor(x, levels = c(0, 1), labels = c("Absent", "Present"))
}
sms_train <- sms_train %>% apply(MARGIN=2, FUN=convert_counts)
sms_test <- sms_test %>% apply(MARGIN=2, FUN=convert_counts)

2. Training the two prediction models

Naive Bayes 을 이용해서 기계학습을 수행 한다.
생성은 10-fold cross validation을 사용해서 한다.

그리고 두개의 모델을 각각 나눠서 수행 한다.
각각의 모델은 라플라스 추정자와 kernel density를 각각 적용한 것과 그렇지 않은것으로 구분 한다.

우선 Caret pakcage에서 Naive Bayes 모델에 대해서 지원하는 Control parameter의 종류는 아래와 같다.

> modelLookup("nb")
  model parameter              label forReg forClass probModel
1    nb        fL Laplace Correction  FALSE     TRUE      TRUE
2    nb usekernel  Distribution Type  FALSE     TRUE      TRU

위와 같이 modelLookup()명령어를 통해서 필요한 Machine Learning모델의 파라메터 지원의 모든 종류를 확인 할 수 있다.

아래는 라플라스 조정자를 적용하지 않은것이다. default 값을 의미한다.

ctrl <- trainControl(method="cv", 10)
set.seed(12358)
sms_model1 <- train(sms_train, sms_raw_train$type, method="nb", trControl=ctrl)
sms_model1

Naive Bayes 

4170 samples
1234 predictors
   2 classes: 'ham', 'spam' 

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 3753, 3753, 3754, 3753, 3753, 3753, ... 
Resampling results across tuning parameters:

  usekernel  Accuracy   Kappa      Accuracy SD  Kappa SD  
  FALSE      0.9798567  0.9098827  0.003606845  0.01680031
   TRUE      0.9798567  0.9098827  0.003606845  0.01680031

Tuning parameter 'fL' was held constant at a value of 0
Accuracy was used to select the optimal model using  the largest value.
The final values used for the model were fL = 0 and usekernel = FALSE.

아래는 라플라스 조정자를 1로 설정하고 kernel density는 적용하지 않았다.

set.seed(12358)
sms_model2 <- train(sms_train, sms_raw_train$type, method="nb", 
                    tuneGrid=data.frame(.fL=1, .usekernel=FALSE),
                    trControl=ctrl)

> sms_model2
Naive Bayes 

4170 samples
1234 predictors
   2 classes: 'ham', 'spam' 

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 3753, 3753, 3754, 3753, 3753, 3753, ... 
Resampling results

  Accuracy   Kappa      Accuracy SD  Kappa SD  
  0.9793765  0.9071502  0.004822776  0.02320774

Tuning parameter 'fL' was held constant at a value of 1
Tuning parameter 'usekernel' was held constant at a value
 of FALSE

Testing the predictions

두개의 모델을 confusionMatrix()을 이용해서 평가한다.
positive result의 목적은 message가 SPAM으로 prediction 됬을 때를 의미한다.

confusionMatrix()의 사용법은 positive label만 설정해주고 두개의 비교할 라벨 데이터만 넣어주면된다.

# Testing the predictions
sms_predict1 <- predict(sms_model1, sms_test)
cm1 <- confusionMatrix(sms_predict1, sms_raw_test$type, positive="spam")
cm1
Confusion Matrix and Statistics

          Reference
Prediction  ham spam
      ham  1199   25
      spam    4  161

               Accuracy : 0.9791         
                 95% CI : (0.9702, 0.986)
    No Information Rate : 0.8661         
    P-Value [Acc > NIR] : < 2.2e-16      

                  Kappa : 0.9055         
 Mcnemar's Test P-Value : 0.0002041      

            Sensitivity : 0.8656         
            Specificity : 0.9967         
         Pos Pred Value : 0.9758         
         Neg Pred Value : 0.9796         
             Prevalence : 0.1339         
         Detection Rate : 0.1159         
   Detection Prevalence : 0.1188         
      Balanced Accuracy : 0.9311         

       'Positive' Class : spam 

Laplace estimator 설정 kernel density를 적용하지 않은 모델의 경우

> sms_predict2 <- predict(sms_model2, sms_test)
There were 50 or more warnings (use warnings() to see the first 50)
> cm2 <- confusionMatrix(sms_predict2, sms_raw_test$type, positive="spam")
> cm2
Confusion Matrix and Statistics

          Reference
Prediction  ham spam
      ham  1200   27
      spam    3  159

               Accuracy : 0.9784          
                 95% CI : (0.9693, 0.9854)
    No Information Rate : 0.8661          
    P-Value [Acc > NIR] : < 2.2e-16       

                  Kappa : 0.9015          
 Mcnemar's Test P-Value : 2.679e-05       

            Sensitivity : 0.8548          
            Specificity : 0.9975          
         Pos Pred Value : 0.9815          
         Neg Pred Value : 0.9780          
             Prevalence : 0.1339          
         Detection Rate : 0.1145          
   Detection Prevalence : 0.1166          
      Balanced Accuracy : 0.9262          

       'Positive' Class : spam            

라플라스 추정자를 설정하지 않을경우 0 확률이 존재해서 데이터가 작다면 매우 부정확해 질 수 있다. 즉 어느 하나가 0%이기 때문에 다른것에 상관없이 무조건 0 probablity가 나와 버린다.

caret based Naive Bayes와 e1071 based Naive Bayes의 비교

TP, TN, FP, FN
accuracy
sensitivity (also known as recall or true positive rate)
specificity (also known as true negative rate)

> # from the table on page 115 of the book
> tn=1203
> tp=151
> fn=32
> fp=4
> book_example1 <- list(
+     TN=tn,
+     TP=tp,
+     FN=fn,
+     FP=fp,
+     acc=(tp + tn)/(tp + tn + fp + fn),
+     sens=tp/(tp + fn),
+     spec=tn/(tn + fp))
> 
> # from the table on page 116 of the book
> tn=1204
> tp=152
> fn=31
> fp=3
> book_example2 <- list(
+     TN=tn,
+     TP=tp,
+     FN=fn,
+     FP=fp,
+     acc=(tp + tn)/(tp + tn + fp + fn),
+     sens=tp/(tp + fn),
+     spec=tn/(tn + fp))
> 
> b1 <- lapply(book_example1, FUN=round, 2)
> b2 <- lapply(book_example2, FUN=round, 2)
> m1 <- sumpred(cm1)
> m2 <- sumpred(cm2)
> model_comp <- as.data.frame(rbind(b1, b2, m1, m2))
> rownames(model_comp) <- c("Book model 1", "Book model 2", "Caret model 1", "Caret model 2")
> pander(model_comp, style="rmarkdown", split.tables=Inf, keep.trailing.zeros=TRUE,
+        caption="Model results when comparing predictions and test set")


|                |  TN  |  TP  |  FN  |  FP  |  acc  |  sens  |  spec  |
|:-------------------:|:----:|:----:|:----:|:----:|:-----:|:------:|:------:|
|  **Book model 1**   | 1203 | 151  |  32  |  4   | 0.97  |  0.83  |   1    |
|  **Book model 2**   | 1204 | 152  |  31  |  3   | 0.98  |  0.83  |   1    |
|  **Caret model 1**  | 1199 | 161  |  25  |  4   | 0.98  |  0.87  |   1    |
|  **Caret model 2**  | 1200 | 159  |  27  |  3   | 0.98  |  0.85  |   1    |

Table: Model results when comparing predictions and test set

비교결과 accuracy에 대해서는 e1071와 caret 두 package는 별다른 차이가 없다.
하지만, sensitivity 측면에서는 차이가 있는 것을 알 수 있다.

추가내용 참조


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는 무시하는 것이다.







+ Recent posts