Week 01: Prediction motivation, What is prediction?


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

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


Prediction motivation


Who predicts?

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


Machine Learning 성공 사례


Chris Volinsky

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

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




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

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




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

Kaggle에서 주최한 대회이다.




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

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

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

Bioinformatic 분야를 말한다.





Advanced Study를 위한 자료들


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

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

Machine Learning Course in coursera

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




What is prediction ?



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

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

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

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

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


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

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

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


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

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

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




■ Components of a predictor


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


question

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

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


input data

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

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

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


features

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

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


algorithm

machine learning algorithm을 적용한다.

Random Forest

Decision Trees


parameters

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

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


evaluation

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



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

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

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



1) Question

start with a general question

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

Make it concrete 

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


2) Input data

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


3) features


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


Dear Jeff,

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

Thanks,

Ben


Frequency of you = 2/17 = 0.118

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

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


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

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


좀더 분석해보면

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

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

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


4) our algorithm

Find a value C.

Frequency of "your" > C predict "spam"

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

5) Parameter

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

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


6) Evaluation

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

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

정확도는 TP + TN 이므로


0.459 + 0.292 = 0.751이 Accuracy가 된다.

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








Naive Bayes Classification with R


Bayesian rule에 대해서는 이전 theorem post를 참조 한다.

Bayes algorithm을 이용해서 mobile phone spam을 filtering하는 방법

Short Message Service (SMS)를 구분 하는 작업을 수행 한다.



Step 1 - collecting data


naive bayes classifer를 개발하기 위해서 SMS Spamcollection으로 부터 알고리즘을 적용 한다.

http://www.dt.fee.unicamp.br/~tiago/smsspamcollection/


이 스팸 데이터의 포맷은 아래와 같다.



spam 라벨은 junk message를 의미하고, ham 라벨은 legitimate message를 의미한다.


ham massage의 예:

  • Better. Made up for Friday and stuffed myself like a pig yesterday. Now I feel bleh. But at least its not writhing pain kind of bleh.
  • If he started searching he will get job in few days. He have great potential and talent.
  • I got another job! The one at the hospital doing data analysis or something, starts on monday! Not sure when my thesis will got finished


spam message의 예:

  • Congratulations ur awarded 500 of CD vouchers or 125gift guaranteed & Free entry 2 100 wkly draw txt MUSIC to 87066
  • December only! Had your mobile 11mths+? You are entitled to update to the latest colour camera mobile for Free! Call The Mobile Update Co FREE on 08002986906
  • Valentines Day Special! Win over £1000 in our quiz and take your partner on thetrip of a lifetime! Send GO to 83600 now. 150p/msg rcvd.
ham과 spam 메시지와의 차이는 우선 위의 메시지만을 고려해 볼 때,
세개 중 두개의 spam은 "free"라는 메시지를 사용 했다. 

이와 다르게, ham message의 경우 2개의 메시지들은 각각 상세한 날짜를 언급 하고 있다는 점이 다르다.

이러한 데이터에 naive bayes classifier를 적용할 경우, 위에서 언급한 단어의 발생 빈도를 이용해서 SMS message가 spam 인지 ham인지를 구분하게 된다.

단순히 free가 들어간 메시지를 spam으로 처리하는 것은 문제가 될 수 있다. 
왜냐하면, 같은 free라도
"are you free on Sunday?" 는 ham 이고
"free ringtones."는 spam 이다.
따라서 제안된 classifier는 확률을 이용해서 전체 메시지의 단어 빈도를 분석해서 spam 인지 아닌지를 결정 해야 한다.


Step 2 - exploring and preparing the data


text 파일을 처리가 어려움으로 csv 파일로 변경된 것을 사용 한다.

sms_spam.csv

#데이터 읽기
sms_raw <- read.csv("sms_spam.csv",stringsAsFactors =  FALSE)
#구조 분석 파악
> str(sms_raw)
'data.frame':	5559 obs. of  2 variables:
 $ type: chr  "ham" "ham" "ham" "spam" ...
 $ text: chr  "Hope you are having a good week. Just checking in" "K..give back my thanks." "Am also doing in cbe only. But have to pay." "complimentary 4 STAR Ibiza Holiday or 짙10,000 cash needs your URGENT collection. 09066364349 NOW from Landline not to lose out"| __truncated__ ...
#데이터 타입 분석
> class(sms_raw)
[1] "data.frame"

feature는 type과 text 두개로 구성되었다.
data frame의 구조를 가지며, 5559개의 열로 구성 되었다.

그리고 text feature에 SMS message의 raw 데이터가 기록 되어 있다.


현재 type은 stringAsFactors =  FALSE 로 설정 했기 때문에 factor가 아니라, character vector로 구성 되어 있다.
하지만, 이 type은 categorical variable 이기 때문에 factor로 변환 하는것이 좋다.
※ 처음 부터 factor로 만들지 않은 것은 text는 factor 타입보다는 character vector에 더 적합하기 때문이다.
#변경을 수행 한다.
> sms_raw$type <- factor(sms_raw$type)
#변경 결과를 확인하면 정상적으로 Factor가 된것을 알 수 있다.
> str(sms_raw)
'data.frame':	5559 obs. of  2 variables:
 $ type: Factor w/ 3 levels "All done, all handed in. Don't know if mega shop in asda counts as celebration but thats what i'm doing!",..: 2 2 2 3 3 2 2 2 3 2 ...
 $ text: chr  "Hope you are having a good week. Just checking in" "K..give back my thanks." "Am also doing in cbe only. But have to pay." "complimentary 4 STAR Ibiza Holiday or 짙10,000 cash needs your URGENT collection. 09066364349 NOW from Landline not to lose out"| __truncated__ ...
이상하게도 기본적으로 제공되는 csv 파일을 가지고 작업을 수행할 경우 문제가 발생한다.
따라서 아래의 코드 작업을 수행 해야 한다.
# 부족한 데이터를 삽입한다.
sms_raw[1072,"type"] <- factor("ham")
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!")


부족한 데이터 삽입전에는 아래와 같이 요인이 3개가 된다. 하나가 요인 값이랑 text 값이 잘못 되어 있기 때문이다.

> table(sms_raw$type)
All done, all handed in. Don't know if mega shop in asda counts as celebration but thats what i'm doing! 
                                                                                                       1 
                                                                                                     ham 
                                                                                                    4811 
                                                                                                    spam 
                                                                                                     747

잘못된 데이터를 수정 하면 아래와 같이 바뀐다.

> table(sms_raw$type)
 ham spam 
4812  747 


■ Data preparation - processing text data for analysis


Document Classification은 주어진 문서를 하나 이상의 분류로 구분하는 문제이다.

지금 다루는 스팸 인지 아닌지를 구분하는 것이 문서 분류의 가장 흔한 예라고 할 수 있다.

또 다른 예로는 제품 리뷰 글을 보고 해당 리뷰가 제품에 대한 긍정적인 리뷰인지 부정적인 리뷰인지를 구분하는 

감성 분석 (Sentiment Analysis)이 있다.


text 처리를 위해서 특화된 package인 Text Mining (tm)의 사용에 대해서 다루 겠다.

TM은 Ingo Feinerer에 의해서 Vienna University에서 박사학위 논문의 일환으로 만들어진 Package 이다.

전공은 Economics and Business이다. 해당 package에 대해서 좀 더 깊이 있는 학습을 원할경우 아래의 사이트를 참조 하자.

http://tm.r-forge.r-project.org/


install.packages("tm")

library(tm)


우선 corpus function을 이용해서 text 데이터를 오브젝트로 생성 한다.


포멧팅 오류를 막기 위해서, corpus 실행전에 UTF-8 en-coding을 수행 하자.

그다음 corpus 함수를 수행 한다.

아래와 같이 corpus 함수는 text를 정의하고 있는 파라메터를 입력 받는다. 이를 위해서 text를 일련의 vector로 만들었었다. 이것을 넘겨줄때 VectorSource()를 이용해서 vector임을 corpus에게 알려주게 된다.

최종적으로 corpus는 sms_corpus라고 이름 지어진 Object를 반환하게 된다. 이 Object를 이용해서 이제 Text Data 처리를 쉽게 할 수 있다.

# 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])
Metadata:  corpus specific: 0, document level (indexed): 0
Content:  documents: 3
[[1]]
Metadata:  7
Content:  chars: 49
[[2]]
Metadata:  7
Content:  chars: 23
[[3]]
Metadata:  7
Content:  chars: 43


Corpus는 정말로 유연한 문서 읽기 라이브러리이다. 

PDF나 Microsoft Word 문서 같은 것들을 읽을 수 있다. 좀 더 조사하고 싶다면, Data Input section에 대해서

tm package의 vignette를 이용해서 관련 문서를 확인하다.

command: print(vignette("tm"))


본격적으로 text를 분할해서 단어를 분석하기 전에 기본적으로 

데이터를 클린하는 것이 필요하다.

즉, punctuation과 의미 없는 단어들을 말한다.


각각의 단계는 아래와 같다.

# clean up the corpus using tm_map()
# 소문자로 모두 변경 한다.
corpus_clean <- tm_map(sms_corpus, content_transformer(tolower))
# 숫자를 모두 제거 한다.
corpus_clean <- tm_map(corpus_clean, removeNumbers)
# stop words로 알려진, "to", "and", "but", "or"를 모두 제거 한다.
# 이것을 위해서 stop word를 새로 정의하지 않고, 알려진 리스트인 stopword()를 이용 한다.
corpus_clean <- tm_map(corpus_clean, removeWords, stopwords())
# punctuation을 제거 한다.
corpus_clean <- tm_map(corpus_clean, removePunctuation)
# single space로 모두 만든다. 즉, whitespace(여백)을 모두 제거 한다.
corpus_clean <- tm_map(corpus_clean, stripWhitespace)


각각 변경된 내부 구조를 살펴 보면 아래와 같다.

> lapply(sms_corpus[1:3],as.character)
$`1`
[1] "Hope you are having a good week. Just checking in"
$`2`
[1] "K..give back my thanks."
$`3`
[1] "Am also doing in cbe only. But have to pay."
> lapply(corpus_clean[1:3],as.character)
$`1`
[1] "hope good week just checking "
$`2`
[1] "kgive back thanks"
$`3`
[1] " also cbe pay"


data pre-processing의 마지막 단계는 tokenization 단계이다.

해당 단계에서는 각각의 word를 하나의 컴포넌트로 구분하게 된다.


DocumentTermMatrix() 함수를 이용해서 sparse matrix를 구성 한다.

기본적으로 그냥 생성하면 SMS message를 나타내는 것은 5,559개 이며, term을 나타내는 것은 7,000개 이다.

> sms_dtm <- DocumentTermMatrix(corpus_clean)
> sms_dtm
<>
Non-/sparse entries: 42635/44407129
Sparsity           : 100%
Maximal term length: 40
Weighting          : term frequency (tf)

이제 sparse matrix을 생성 했으므로 word frequency를 수행 할 수 있다.



■ Data preparation - creating training and test datasets 

트레이닝과 테스트로 데이터를 나눠서 나중에 평가를 위해서도 사용 할 수 있도록 한다.


75 vs 25로 분할한다. 그리고 이미 임의로 섞여 있기 때문에 그냥 나누면 된다.


raw data / document-term matrix / corpus 이렇게 세가지 종류의 데이터 셋을 모두 분할 한다.

# creating training and test datasets
sms_raw_train <- sms_raw[1:4169, ]
sms_raw_test  <- sms_raw[4170:5559, ]

sms_dtm_train <- sms_dtm[1:4169, ]
sms_dtm_test  <- sms_dtm[4170:5559, ]

sms_corpus_train <- corpus_clean[1:4169]
sms_corpus_test  <- corpus_clean[4170:5559]

비율이 정상적으로 분할 되었는지는 아래의 명령어를 통해서 간단히 알 수 있다.

> # check that the proportion of spam is similar
> prop.table(table(sms_raw_train$type))
      ham      spam 
0.8647158 0.1352842 
> prop.table(table(sms_raw_test$type))
      ham      spam 
0.8683453 0.1316547 


■ Visualizing text data - word clouds

word cloud는 각 단어의 빈도를 text data로 묘사하게 된다.

여기서 보여지는 단어들의 배치는 랜덤이며 그 글자 크기가 빈도를 나타낸다.

이것을 통해서 경향을 파악할 수 있기 때문에 word cloud는 많이 사용 된다.


spam과 ham을 구분하는 예제에서는 word cloud를 그려 봄으로서 생성하려는 classifier가 성공적으로 동작 할지 안할지를

가늠 할 수 있게 된다.

word cloud는 Ian Fellows가 전문 통계학자로 UCLA에 있을때 만들어 진것이다.

http://cran.r-project.org/web/packages/wordcloud/index.html 에서 더 자세한 정보를 확인 할 수 있다.


install.packages("wordcloud")
library(wordcloud)
wordcloud(sms_corpus_train, min.freq = 30, random.order = FALSE)



random.order=FALSE 면, 높은 빈도일 수록 가운데에 집중 되는 경향을 보인다.

min.freq의 의미는 최소 빈도를 의미한다. 이것을 넘어야 cloud에서 보여지게 된다.

만약 word를 figure로 보지 못한다는 메시지를 본다면, min.freq를 조정 하면 된다.


이것을 spam과 ham에 대해서 각각 나눠서 수행 해 보자.

# subset the training data into spam and ham groups
spam <- subset(sms_raw_train, type == "spam")
ham  <- subset(sms_raw_train, type == "ham")
wordcloud(spam$text, max.words = 40, scale = c(3, 0.5))
wordcloud(ham$text, max.words = 40, scale = c(3, 0.5))



  


오른쪽이 스팸이고, 왼쪽이 Ham이다.

Spam의 경우 urgent, free, mobile, call, claim, stop 같은 것들이 있는것을 알 수 있다.

Ham의 경우 can, sorry, need, time이 나오는 것을 알 수 있다.



■ Data preparation - creating indicator features for frequent words

데이터 가공의 마지막 단계는 이러한 sparse matrix을 naive Bayes classifier가 처리할 수있는 데이터 타입으로 변형해 주는 것이다.

sparse matrix은 7000개의 feature들을 가지고 있다. 하지만 모든 feature들이 유용하지 않다는 것은 당연한 사실 이다.

따라서 이러한 feature들을 줄이는 작업을 수행 한다.


tm package에 있는 findFreqTerms() 함수를 이용 한다.

findFreqTerms(sms_dtm_train, 5)

위 command의 뜻은 최소 matrix으로 부터 최소 5번 이상 발생한 word로 구성된 character vector를 만들라는 명령어 이다.


이제 이러한 frequent word로만 구성 시켜서 matrix을 만들기 위해서 다시 DocumentTermMatrix을 수행 한다.

# indicator features for frequent words
sms_dict<- findFreqTerms(sms_dtm_train, 5)
sms_train <- DocumentTermMatrix(sms_corpus_train, list(dictionary = sms_dict))
sms_test  <- DocumentTermMatrix(sms_corpus_test, list(dictionary = sms_dict))

이렇게 수행 하면 최종적으로 7000개의 feature들은 1200개 수준으로 줄어 들게 된다.


naive Bayes classifier는 기본적으로 categorical feature들에 대해서만 학습을 수행 한다.

따라서 지금의 구조는 셀이 빈도를 나타내는 numerical type으로 표현 되므로 이것을 factor variable로 변경 해야 한다.

여기서는 "Yes", "No"와 같은 간단한 두 종류의 factor로 구분한다.

# convert counts to a factor
convert_counts <- function(x) {
  x <- ifelse(x > 0, 1, 0)
  x <- factor(x, levels = c(0, 1), labels = c("No", "Yes"))
}
# apply() convert_counts() to columns of train/test data
sms_train <- apply(sms_train, MARGIN = 2, convert_counts)
sms_test  <- apply(sms_test, MARGIN = 2, convert_counts)

apply를 이용해서 처리한다. margin=2의 의미는 column을 의미한다.

더 자세한 사항은 이전 포스트를 참조하자.




Step 3 - training a model on the data


이제 naive Bayes algorithm을 적용할 때가 왔다.

Machine Learning의 대부분의 시간은 지금과 같이 data 가공에 소모된다. 데이터만 가공된다면 적용하는것은 일도 아니다.

Naive Bayes algorithm의 원리는 이전 포스트의 "Probabilistic Learning - Classification using Naive Bayes

"를 참조 하자.


naive Bayes를 최적으로 구현하는 것은 쉬운 일이 아니므로, 이미 구현된 library를 사용하자.

"e1071" package에는 다양한 Machine Learning algorithm들이 구현되어 있다.

Vienna University of Technology (TU Wien)의 Statistics 학과에서 개발한 package이다.


install.packages("e1071")

library(e1071)


설치가 실패할 경우, 해당 package는 바이너리로 제공이 안되기 때문이다. 수작업으로 설치해 준다.

.libPaths() # 라이브러리 설치 경로 확인

https://cran.r-project.org/web/packages/e1071/index.html에서

Windows binaries항목의 zip파일을 다운 받은 다음 라이브러리가 저장된 폴더에 복사 한다.


사실 다른 package들도 많이 있다.

klaR 또한 naiveBayes를 지원 한다. 어느것을 쓰던 상관없으니 마음대로 찾아서 쓰면된다. 


Naive Bayes는 Learning과 Prediction을 구분해서 수행되는 알고리즘이다.

즉, eager learning 방식이다. 특별한 Model을 생성하고 prediction 하게 된다. 별도의 트레이닝 실행 시간을 필요로 하지만

prediction에 걸리는 시간은 트레이닝을 통해서 생성된 model에 기반하므로 Lazy Learning 방식 (KNN)에 비해서 빠르게 된다.


Building the classifier

m <- naiveBayes (train, class, laplace = 0)

  • train은 data frame 또는 matrix가 가능하다. training data를 포함하고 있다.
  • class는 factor vector 값이다. 각 행에서 class 값을 가지고 있는 것이다.
  • laplace 는 Laplace Estimator 사용을 위한 최소 값을 의미한다. Default 는 0이다.

해당 함수는 prediction을 위한 bayes model을 반환 한다.


Making Prediction

p <- predict (m, test, type = "class")

  • m은 model이다. naiveBayes()에 의해서 학습 되어진
  • test는 data frame 또는 matrix으로 test data set을 포함하고 있다. 당연히 training과 같은 형태와 수의 feature를 가지고 있어야 한다.
  • type은 "class" 또는 "raw"로 설정 할 수 있다. class는 가장 그럴것 같은 class로 예측해 주는것이고, raw는 확률을 반환해 주게 된다.

해당 함수는 type argument에 의해서 예측되어진 class 또는 확률의 vector를 반환 한다.

## Step 3: Training a model on the data ----
library(e1071)
sms_classifier <- naiveBayes(sms_train, sms_raw_train$type)
sms_classifier
$tables$yesterday
                  yesterday
sms_raw_train$type          No         Yes
              ham  0.995284327 0.004715673
              spam 0.996453901 0.003546099


데이터를 출력해서 보면 각각의 feature들에 대한 확률이 모두 계산되어진 것을 알 수 있다.

위와 같이 각 feature에 대한 조건 확률 들을 모두 계산해 두면 추후에 어떤 message에 대한 spam과 ham의 확률을 쉽게 구할 수 있다.

이것을 통해서 prediction을 즉각적으로 수행 하게 된다.




Step 4 - evaluating model performance 


테스팅을 위해서는 training에 사용하지 않는 message를 가지고 예측을 수행 하면 된다.


평가를 위해서는 이것저것 이전에 생성한 데이터 구조들을 사용 하게 된다.


sms_test 에는 보지 않은 데이터들의 feature들이 Yes와 No로써 저장되어 있다.

sms_raw_test에는 각 message가 "ham"인지 "spam"인지에 대한 참(true) 값이 저장 되어 있다.


학습을 통해서 생성한 classifier는 sms_classifier 이다. 그런 다음 생성한 prediction을 이용해서 true value와 비교하는 작업을 수행 한다.


prediction을 위해서 predict() 함수가 사용 되어 진다. 그리고 이러한 결과는 sms_test_pred vector에 저장 된다.

## Step 4: Evaluating model performance ----
sms_test_pred <- predict(sms_classifier, sms_test)

검증은 confusion matrix을 만들어서 수행 한다.

이를 위해서 CrossTable() 함수를 사용 한다.

> library(gmodels)
> CrossTable(sms_test_pred, sms_raw_test$type,
+            prop.chisq = FALSE, prop.t = FALSE, prop.r = FALSE,
+            dnn = c('predicted', 'actual'))

 
   Cell Contents
|-------------------------|
|                       N |
|           N / Col Total |
|-------------------------|

 
Total Observations in Table:  1390 

 
             | actual 
   predicted |       ham |      spam | Row Total | 
-------------|-----------|-----------|-----------|
         ham |      1202 |        31 |      1233 | 
             |     0.996 |     0.169 |           | 
-------------|-----------|-----------|-----------|
        spam |         5 |       152 |       157 | 
             |     0.004 |     0.831 |           | 
-------------|-----------|-----------|-----------|
Column Total |      1207 |       183 |      1390 | 
             |     0.868 |     0.132 |           | 
-------------|-----------|-----------|-----------|


위 confusion matrix을 통해서 괭장히 잘 prediction된 것을 알 수 있다.

오직 5개의 message만이 incorrectly 분류되었다 spam으로 이것은 전체 비중에서 0.4% 수준인 것이다.

31개 정도만이 그리고 spam인데 ham으로 prediction 되었다.

project에 투자한 노력에 비해서 상당히 우수한 prediction 실험 결과를 얻어낸 것을 알 수 있다.


하지만 문제는, 단 5개의 message만이 원래 ham인데 spam으로 분류 되었다 할지라도 이것은 심각한 문제를 야기할 수 있다.

즉 spam인데 ham으로 분류되는것은 단순히 불편함을 주지만, 중요한 메시지를 spam으로 분류해서 문제를 발생 시킨다면

그것이 99%의 정확도를 가질지라도 당장 해당 제품은 abandon 되어진다.

즉, False Negative 보다는 절대적으로 False Positive를 줄어야 하는 것이다.



Step 5 - improving model performance


오버피팅 문제를 야기할 수도 있다. 지금까지 생성한 모델은

왜냐하면 모델을 생성하기 위해서 사용한 트레이닝 데이터 셋에 "ringtone"이라는 feature가 오직 spam에서만 존재한다면

해당 경우에는 100% 확률로 spam으로 예측 된다.

의심할 여지 없이 문제가 있는 모델이다. 해당 트레이닝 데이터에서 최고의 정확도를 자랑하지만, 트레이닝 데이터가 현실의 모든 데이터를 반영하지 못하기 때문에 그것이 문제가 있다는 것은 직관적으로 알 수 있다.


laplace = 1로 설정해서 수행해 보자.

## Step 5: Improving model performance ----
sms_classifier2 <- naiveBayes(sms_train, sms_raw_train$type, laplace = 1)
sms_test_pred2 <- predict(sms_classifier2, sms_test)
CrossTable(sms_test_pred2, sms_raw_test$type,
           prop.chisq = FALSE, prop.t = FALSE, prop.r = FALSE,
           dnn = c('predicted', 'actual'))
   Cell Contents
|-------------------------|
|                       N |
|           N / Col Total |
|-------------------------|

 
Total Observations in Table:  1390 

 
             | actual 
   predicted |       ham |      spam | Row Total | 
-------------|-----------|-----------|-----------|
         ham |      1203 |        31 |      1234 | 
             |     0.997 |     0.169 |           | 
-------------|-----------|-----------|-----------|
        spam |         4 |       152 |       156 | 
             |     0.003 |     0.831 |           | 
-------------|-----------|-----------|-----------|
Column Total |      1207 |       183 |      1390 | 
             |     0.868 |     0.132 |           | 
-------------|-----------|-----------|-----------|


실험 결과 false positive가 5개에서 4개로 1개 줄어든 것을 알 수 있다.

비록 적은 향상이지만 이러한 false positive는 spam filtering product가 use 될지 abandon될지를 결정할 중요한 factor이므로 무시할 수는 없다.

그리고 여전히 false positive로 분류된 4개의 message에 대해서도 분석을 해봐야 할 것이다.








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

Ensemble method: Bagging (bootstrap aggregating)  (0) 2015.11.19
Bootstrapping  (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

통계처리 (기본)



Rounding of Numbers


정확한 계산을 필요로 하는 경우도 있지만, 때로는 반올림을 할 필요도 있다. 이 경우를 위해서 R은 아래와 같은 

몇가지 반올림 관련 함수들을 제공 한다.


ceiling(x)

floor(x)

trunc(x, ...)

round(x, digits =)

signif(x, digits =)


digits는 반올림할 decimal point의 위치를 결정 한다. 

상수면 소수점(decimal point)를 나타내며, 음수면 10,100의 자리를 나타낸다 (multiples of 10, 100).


round(123.456, digits=2)
[1] 123.46
round(-123.456, digits=-2)
[1] 100




만약 유효숫자(significant digits)를 숫자의 크기에 상관없이 명시하고 싶다면,

signif()를 사용할 수 있다.

> signif(-123.456,digits=4)
[1] -123.5
> signif(-123.456,digits=5)
[1] -123.46
> signif(-123.456,digits=1)
[1] -100
> signif(-123.456,digits=1)
[1] -100



round와 signif는 5를 기준으로 작은지 큰지에 따라 rounding을 수행 한다. 이와 다르게 한쪽 방향으로만 rounding을 수행하는

함수들도 존재 한다.


floor(x) 가장 작은 정수로 x가 결정 된다.

> floor(123.45)
[1] 123
> floor(-123.45)
[1] -124


ceiling(x) 가장 큰 정수로 x가 결정 된다.

> ceiling (123.45)
[1] 124
> ceiling (-123.45)
[1] -123



trunc(x) 가장 가까운 정수로 반올림되는데 방향이 0이랑 가장 근접한 쪽이다.

> trunc(123.45)
[1] 123
> trunc(-123.45)
[1] -123




No, you can't have it all


Technology는 언제나 사람들에게 선택할 기회를 주었다.

불은 인류에게 추운 날씨에서도 생존할 수 있는 선택의 기회를

전등은 밤에도 책을 읽을 수 있는 선택의 기회를

마약은 우리에게 스트레스로 부터 자유를 얻으며, 스스로의 삶을 망가뜨릴 선택의 기회를 주었다.


마지막으로 디지털 technology는 우리에게 동시에 하나 이상의 일을 할 수 있는 능력의 기회를 주었다. 최소한 그렇다고 느낄 수 잇게 했다.


Anne-Marie Slaugther의 새로운 책 "Unfinished Business: Women, Men, Work, Family"에서 그녀는 디지털 기술을 고려하지는 않고 있다.

하지만 멀티테스킹의 정신을 여자 남자의 관점에서 이야기 하고 있다. 즉 여자는 우선적으로 그들의 career와 family 사이에서 저글링하는 상황에 놓여 있다는 것이다.


이론적으로 50:50으로 나눠서 일을 하면 된다고 생각하지만 그것은 약간은 비현실적이다.

결국, 남자가 여자가 누가 현실을 위해서 헌신을 해야하는지에 대한 관념은 모두 버릴 필요가 있다.


슬프게도 여성들은 부모로써의 역할의 필요성에  봉착함으로써 그들의 커리어를 포기하게 된다.

Sheryl Sandberg는 그러한 의미에서 여성 leader의 힘이다. 그녀는 보모나 가정부 튜터 교사를 고용하기는 하지만 여전히 커리어를 지키고 있기 때문이다.


기술의 옹호자는들은 말한다. 우리는 기술을 통해서 멀티테스킹을 가능하게 한다고.

운전중에 이메일을 보내며, 트윗을 콘서트를 보면서 하며, 숙제를 스냅챗을 하면서 하게 된다.

하지만 이러한 현상들은 가짜 impression으로 규졍한다. 이것은 그렇게 보일뿐 실제로 효율이 매우 떨어지기 떄문이다.


즉 , 지금까지 보았던 모든 멀티 테스킹은 낮은 효과를 가져온다. 아무리 단일 작업으로 볼떄 멀티 테스킹을 통해서 하나 하나는 더 낮은 작업 시간만으로도 그것을 끝마쳤다고 할지라도 그것의 내부를 들여다 볼경우

그것은 더 낮은 정확도와 더 낮은 깊이를 가진다는 것이다.

우리는 낮음과 늦음을 구별할 필요가 있다.


기사에서 테크놀로지에서 종사하는 10명의 여성 리더는 다음과 같다.

사진은 각각 순서대로이다.


  • Susan Wojcicki, executive of YouTube
  • Sheryl Sandberg, Facebook's chief operating officer
  • Marissa Mayer, Yahoo chief Executive
  • Ursula Burns, Xerox (intern으로 1980년에 시작)
  • Cher Wang, co-founder and chairwoman of HTC cooperation
  • Virginia M. Rometty, Chief executive officer and chairwoman of IBM
  • Meg Whitman, president and chief executive officer of Hewlett-Packard ( previously the head of eBay)
  • Safra Catz, executive at Oracle Corporation
  • Sandy Carter, IBM's wordwide general manager
  • Angela Ahrendts, Chief executive of Burberry for many years.



데이터 분리 및 병합 (split, subset, merge)


split

split: 주어진 조건에 따라서 데이터를 분리 한다.
x # 분리할 벡터 또는 데이터 프레임
f # 분리할 기준을 지정한 factor

iris$Species에 따라서 분리하고 이것을 리스트에 저장 한다.

> head(split(iris, iris$Species))
$setosa
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa

$versicolor
    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
51           7.0         3.2          4.7         1.4 versicolor
52           6.4         3.2          4.5         1.5 versicolor

$virginica
    Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
101          6.3         3.3          6.0         2.5 virginica
102          5.8         2.7          5.1         1.9 virginica

split()의 실행 결과가 리스트므로, split()후 lapply()를 적용하면 iris의 종별 Sepal.Length의 평균을 구할 수 있다.

> lapply(split(iris$Sepal.Length, iris$Species),mean)
$setosa
[1] 5.006

$versicolor
[1] 5.936

$virginica
[1] 6.588

subset()

subset()
x # 일부를 취할 객체
subset # 데이터를 취할 것인지 여부

# 특정 조건에 의해서 데이터를 추출한다.
> subset(iris, Species == "setosa" & Sepal.Length > 5.0)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
6           5.4         3.9          1.7         0.4  setosa
11          5.4         3.7          1.5         0.2  setosa
15          5.8         4.0          1.2         0.2  setosa
16          5.7         4.4          1.5         0.4  setosa
17          5.4         3.9          1.3         0.4  setosa
18          5.1         3.5          1.4         0.3  setosa
#특정 컬럼을 선택해서 데이터를 추출 한다.
> subset(iris, select=c(Sepal.Length, Species))
    Sepal.Length    Species
1            5.1     setosa
2            4.9     setosa
3            4.7     setosa
4            4.6     setosa
5            5.0     setosa
#특정 컬럼을 제거하는 두가지 서로 다른 스타일의 방법이다.
> subset(iris, select=-c(Sepal.Length, Species))
    Sepal.Width Petal.Length Petal.Width
1           3.5          1.4         0.2
2           3.0          1.4         0.2
3           3.2          1.3         0.2
4           3.1          1.5         0.2
5           3.6          1.4         0.2
6           3.9          1.7         0.4
7           3.4          1.4         0.3
> iris[, !names(iris) %in% c("Sepal.Length","Species")]
    Sepal.Width Petal.Length Petal.Width
1           3.5          1.4         0.2
2           3.0          1.4         0.2
3           3.2          1.3         0.2
4           3.1          1.5         0.2
5           3.6          1.4         0.2
6           3.9          1.7         0.4

merge

merge(): 두 데이터 프레임을 공통된 값을 기준으로 묶는 함수다.
Database에서 join과 같은 역할을 하는 함수 이다.

다음은 name column을 기준으로 수학 점수가 저장된 데이터 프레임과 영어 점수가 저장된 데이터 프레임을 병합한 예이다.
x와 y에 name값이 서로 다른 순서로 저장되어 있으나 공통된 name 값을 기준으로 점수가 잘 병합된 것을 볼 수 있다.

> x <- data.frame(name=c("a","b","c"), math=c(1,2,3))
> y <- data.frame(name=c("c","b","a"), english=c(4,5,6))
> merge(x,y)
  name math english
1    a    1       6
2    b    2       5
3    c    3       4

cbind의 경우 단순히 column만 합치는 것이기 때문에 merge()하고 그 결과가 다르다.

> cbind(x,y)
  name math name english
1    a    1    c       4
2    b    2    b       5
3    c    3    a       6

merge() 수행 시 공통된 값이 한쪽에만 있는 경우에는 반대편 데이터가 비게 되고 이 경우 해당 행은 병합 결과에서 빠진다.
NA를 추가해서라도 전체 데이터를 모두 병합하고 싶다면 all 인자에 TRUE를 지정 한다.

아래의 예제는 all=FALSE(기본값)인 경우와 all=TRUE인 경우의 비교를 보인 것이다.
all=FALSE인 경우에는 공통된 name이 양측에 포함된 "a","b"만 결과에 나타나며, all=TRUE인 경우 공통된 값이 없는 쪽에 NA가 채워지면서 x,y의 전체 행이 결과에 포함된다.

> y <- data.frame(name=c("c","b","d"), english=c(4,5,6))
> merge(x,y)
  name math english
1    b    2       5
2    c    3       4
> merge(x,y, all=TRUE)
  name math english
1    a    1      NA
2    b    2       5
3    c    3       4
4    d   NA       6


'AI > R Basic' 카테고리의 다른 글

JSON in R using jsonlite  (0) 2015.12.12
통계처리 (기본)  (0) 2015.10.28
doBy package, 데이터 그룹 처리  (0) 2015.10.22
R 기본 디버깅 (Debugging) 및 RStudio 이용  (0) 2015.10.04
R Studio 설치법 및 사용 Tip  (0) 2015.10.04

doBy package, 데이터 그룹 처리


doBy 패키지에는 summaryBy(), orderBy(), sampleBy()와 같은 특정 값에 따라 데이터를 처리하는 유용한 함수들이 있다.

다음은 이 함수들의 특징을 요약한 것이다.


 함수

특징 

 doBy::summaryBy()

 데이터 프레임을 컬럼 값에 따라 그룹으로 묶은 후 요약 값 계산 

 doBy::orderBy()

 지정된 컬럼 값에 따라 데이터 프레임을 정렬

 doBy::sampleBy()

 데이터 프레임을 특정 컬럼 값에 따라 그룹으로 묶은 후 각 그룹에 샘플 추출



install.packages("doBy")

library(doBy)



▣ summaryBy()


doBy::summaryBy: 포뮬러에 따라 데이터를 그룹으로 묶고 요약한 결과를 반환한다.

formula, #요약을 수행할 포뮬러

data=parent.frame() # 포뮬러를 적용할 데이터


반환 값은 데이터 프레임이다.


저것을 사용하기 위해서 formula 문법에 대해서 알아야 한다.



 연산자

예 

의미 

 Y~X1+X2

 Y를 X1, X2로 모델링, 상수항은 암시적으로 허용 된다. 따라서 선형 회귀에 이 포뮬러를 사용하면 Y=a*X1 + b * X2 + c 를 의미한다.

-

 Y~X1-X2

 Y를 X1로 모델링하되 X2는 제외한다.


특히, 선형 회귀에서 Y ~ X1 + X2 - 1은 Y를 X1과 X2로 모델링하되 상수항은 제외 한다는 의미다. 즉, Y= a*x1 + b * X2를 의미한다.

|

 Y~X1 | X2

 X2의 값에 따라 데이터를 그룹으로 묶은 후 각 그룹별로 Y~X1을 적용한다. 

:

Y ~ X1:X2 

 Y를 X1과 X2의 상호 작용 (interaction)에 따라 모델링 한다. 상호 작용은 Y = a * X1 * X2 + b 와 같이 X1과 X2가 동시에 Y 값에 영향을 주는 상황을 말한다.


특히, 영향을 주는 방식이 (+) 합 연산자의 예제인 Y= A*X1 +b*X2 +c와 같은 형태와는 전적으로 다르다.

*

 Y ~ X1 * X2

 Y ~ X1 + X2 + X1:X2의 충약형 표현이다.



summaryBy는 특정 조건에 따라 컬럼의 값을 요약해서 보여주게 된다.

아래의 경우 Sepal.Length와 Sepal.With를 Species에 따라 출력해서 보는 방식이다.

> summaryBy(Sepal.Width + Sepal.Length ~ Species, iris)
     Species Sepal.Width.mean Sepal.Length.mean
1     setosa            3.428             5.006
2 versicolor            2.770             5.936
3  virginica            2.974             6.588



▣ orderBy


doBy::orderBy: 포뮬러에 따라 데이터를 정렬한다.

formula, # 정렬할 기준을 지정한 포뮬러

# ~의 좌측은 무시하며, ~ 우측에 나열한 이름에 따라 데이터가 정렬된다.

data, # 정렬할 데이터


기본은 ascending 이기 때문에 descending으로 하고 싶을 경우 - (마이너)를 붙인다.

orderBy(~-Mean, dataFrame) 이런 식이다.


# 다음의 코드는 Species, Sepal.Width 순으로 정렬한 예이다.
> orderBy(~Species + Sepal.Width, iris)
    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
42           4.5         2.3          1.3         0.3     setosa
9            4.4         2.9          1.4         0.2     setosa
2            4.9         3.0          1.4         0.2     setosa
13           4.8         3.0          1.4         0.1     setosa
14           4.3         3.0          1.1         0.1     setosa


▣ sampleBy


doBy::sampleBy
formula, # ~우측에 나열한 이름에 따라 데이터가 그룹으로 묶인다.
frac = 0.1 #추출할 샘플의 비율이며 기본값은 10%
replace = FALSE # 복원 추출 여부
data=parent.frame() # 데이터를 추출할 데이터 프레임
systematic=FALSE # 계통 추출 (Systematic Sampling)을 사용할지 여부

반환 값은 데이터 프레임이다.


샘플 함수는 정보를 추출하는 함수이다. 아래와 같다.

10개 중 5개를 랜덤으로 추출한다. replace=TRUE를 설정하면 중복을 허용하는 것이다.

sampleBy과 대응 되므로 같이 알아두면 좋다.

> sample(1:10,5)
[1]  1 10  7  3  8
> sample(1:10,5, replace=TRUE)
[1] 8 8 2 3 6


이러한 샘플링은 주어진 데이터를 Training DataTest Data로 분리하는데 유용하게 사용 할 수 있다.


절적한 모델 테스팅을 위해선 균일한 분푸로 Test Data를 생성하는 것이 좋다. 이럴떄 sampleBy가 유용하게 사용 된다.

다음은 Iris 데이터에서 각 Species 별로 10%의 데이터를 추출한 예이다. sampleBy()에서 Species를 지정했으므로 각 종별로 5개씩 데이터가 정확히 샘플로 추출된 것을 볼 수 있다.

> sampleBy(~Species, fra=0.1, data=iris)
              Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
setosa.13              4.8         3.0          1.4         0.1     setosa
setosa.24              5.1         3.3          1.7         0.5     setosa
setosa.27              5.0         3.4          1.6         0.4     setosa
setosa.35              4.9         3.1          1.5         0.2     setosa
setosa.40              5.1         3.4          1.5         0.2     setosa
versicolor.59          6.6         2.9          4.6         1.3 versicolor
versicolor.64          6.1         2.9          4.7         1.4 versicolor
versicolor.77          6.8         2.8          4.8         1.4 versicolor
versicolor.84          6.0         2.7          5.1         1.6 versicolor
versicolor.89          5.6         3.0          4.1         1.3 versicolor
virginica.102          5.8         2.7          5.1         1.9  virginica
virginica.104          6.3         2.9          5.6         1.8  virginica
virginica.121          6.9         3.2          5.7         2.3  virginica
virginica.132          7.9         3.8          6.4         2.0  virginica
virginica.144          6.8         3.2          5.9         2.3  virginica






Sensing Emotions (Affective Computing)


해당 기사는 ACM Communications Magazine에 2015년 9월에 실린 내용이다.

http://dx.doi.org/10.1145/2800498


"How computer systems detect the internal emotional states of users"라는 내용으로 2장 정도의 글을 담고 있다.


30명의 사람들로 구성된 인원이 슈퍼볼을 보고 있고, 이때의 그들의 얼굴 표정의 변화를 카메라가 인지하고 있다.

어떠한 광고가 지루한지 그러한 것들을 카메라를 이용한 얼굴 변화 인식을 통해서 알 수 있다.


그들이 amused, ambivalent, surprised 되는 각각의 양상을 현재 스크린에서 재생되는 영상과 매칭 시켜서 분석 할 수 있는 것이다.

이것을 바로 광고의 효과에 적용할 수 있다.

다들 아시다 시피 슈퍼볼 경기 앞에 들어가는 광고는 천문학 적인 금액을 지출하기 때문이다.


감정 인식의 활용은 광고의 효과를 인지하기 위해서 사용 한다 (market research)

온라인 학습 시스템에서는 언제 학생들이 성장하는지를 관찰한다.

healthcare 응용프로그램에서는 새로운 의약품에 대해서 우울증 환자들이 어떻게 반응 하는지를 다룬다.

home assistance robot들은 노인들의 감정 상태에 따라서 적절히 반응 할 수 있다.


이러한 위의 것들을 처리하는 컴퓨팅을 "affective computing"이라는 용어로서 1990년에 만들어 졌다. MIT 교수 Rosalind Picad에 의해서 단어가 생성됨.


(신조어) 분위기나 감정과 관련된 신체적 특성을 감지하기 위해 생체인식 센서를 사용하는 컴퓨터 기술. 분위기 및 감정의 컴퓨터 시뮬레이션


Focusing on Faces


사람의 vocal into nations, gestures, facial expression, 그리고 posture를 통해서 그 사람이 

engaged인지, distracted인지, annoyed인지를 알아 낼 수 있다.


사실이러한 것을 위해서 직접적인 사람의 해동변롸를 관찰하게 되는 것이 "affective computing"에서는 일반적인 것이다.

전통적으로 이렇게 사람의 얼굴과 몸동작을 관찰하는 방법을 많이 썻다.

하짐 입술의 떨림 같은것은 수염 때문에 알아내기 어렵고

입술, 눈, 코 입 과 같은 단일 부위에 대한 작용을 연결해서 감정으로 연결 시키는것은 사전에 심리 상태와 각 얼굴 부위별 반응에 따른 모델을 필요로 한다. 







Generating Quality Data


많은 이미지를 분석하기 위해서 컨설턴트가 동원 된다.

그다음 시스템을 지도학습 해야한다. 즉 어떤게 joy가 그렇지 않은지를 알려준다.

이때 joy에 관한 이미지를 사전에 사람이 분류해서 100,000 정도를 알려주게 된다.


각각의 이미지의 밝기를 비교하기도 한다.

그다음 각각의 statistical pattern recognition을 이용해서 어떤 사진이 joy 처럼 보이는지를 찾아내게 된다.

이제는 statistical pattern recognition는 "Deep learning"의 부분으로 이동 되었이며 이것이 훨신 powerful 하다고 한다. 




Deep Learning


계측적인 러닝 모델이다.


일단 픽셀에서 부터 일정한 패턴을 찾아서 군집하게 된다.

이것은 마치 어린아이가 자동차를 보았을때 그것이 무엇인지는 모르지만 하나의 영역이 생기고

앞으로 자동차와 비슷한 물건을 보면 처음본 이미지와 계속해서 연결되는 뇌의 구조를 모방하는 방식이다.


그리고 이러한 자동차의 모서리를 인지하고 그것의 모양을 각각의 차원으로 분할해서 저장한다.

따라서 어린아이는 자동차를 실제로 보던 TV를 통해서 2D 영상으로보던 모두 자동차로 인지하게 된다.




Applications and Multimodal Approaches


가장중요한 부분은 응용일것이다.


여전히 광고쪽이나 마케팅 쪽에서 그 효과를 측정할 수 있는 강력한 수단은 존재하지 않고 있다.


pain management for children. 아이들은 자신의 고통을 정확하게 설명하지 못한다. 하지만 이것을 통해서 진실을 알아낼 수 있다고 한다.

아이들의 pain level을 측정하는 수단이다.


physiological input: facial expressions, gestures, voice, 이러한 것들이 분명한 cue가 된다.




Conclusion


하지만 이러한 모든 방법은 사람의 집단주의에서 발생하는 감정의 숨김이라는 벽에 부닥치며

복잡한 이간의 감정을 예측하는것은 매우 어려운 일로 남아있다. 단순히 사람의 visual information만 가지고 판단할경우 잘못된 결과를 추출할 가능성이 매우 높게 된다.

철학자 스피노자가 말하길 인간의 감정은 48개라 한다. 이렇게 복잡한 감정을 컴퓨터가 이해하기란 애초부터 불가능 한것은 아닐까.

현재 컴퓨터 과학에서의 감정 인지는 걸음마 수준인것 같다.




Further Reading


Picard, R.W.

Affective Computing, The MIT Press, 2000.

Calvo, R.A., D’Mello, S.K., Gratch, J.,and Kappas, A. (Eds.)

The Oxford Handbook of Affective Computing, Oxford University Press, 2015.

Bartlett, M., Littlewort, G., Frank, M., and Lee, K.

Automated Detection of Deceptive Facial Expressions of Pain, Current Biology, 2014.

Narayanan, S., et. al.

Analysis of Emotion Recognition Using Facial Expressions, Speech and Multimodal Information, Proceedings of the International Conference on Multimodal Interfaces, 2004.

Emotient

https://vimeo.com/67741811











갤럭시 S3 루팅 하기


다운로드

https://drive.google.com/file/d/0B4pme20nXq8laGxlT2RMMFF0Z0E/view?usp=sharing



1) 삼성 통합 드라이버 설치


2) 스마트폰을 다운로드 모드로 진입하기

종료후 

볼룸 하 + 전원 + 홈

경고창이 뜨면 계속 진행


3) Odin 프로그램 실행 하고

연결이 정상적이면 파란색이기 그것이면 그대로 진행


PDA 눌러서 각자 통신사에 맞는 auto-root 파일 임포트

스타트 눌러서 시작


최종적으로 PASS 뜨고 재부팅 대면 성공

스마트폰에 superSU 있으면 성공




R 기본 디버깅 (Debugging) 및 RStudio 이용


디버깅 방법은 아래와 같이 크게 2가지로 나눠 진다.

  • print(), sprint(), cat()을 사용해서 메시지나 객체의 내용을 출력해보는 방법
  • browser()를 사용한 코드 디버깅 방법


print()


print()문으로 중간 중간 데이터를 찍어 보면서 수행 하도록 한다.

paste() 함수와 같이 쓰는면 유용하다.

인자간의 공백을 사용하지 않는 함수는 paste0() 함수 이다.

fibo <- function (n) {
    if (n == 1 || n == 2) {
        print (" base case ")
        return (1)
    }
    print ( paste0 (" fibo (", n - 1, ") + fibo (", n - 2, ")"))
    return ( fibo (n - 1) + fibo (n - 2))
}
> fibo(3)
[1] " fibo (2) + fibo (1)"
[1] " base case "
[1] " base case "
[1] 2


sprintf()


print()와 유사하지만 주어진 인자들을 특정한 규직에 맞게 문자열로 변환해 출력 한다.

sprintf("포멧팅 문자열",인자1,인자2,..인자n)
# %d / %f / %s (C언어의 문법과 유사하다)


cat()


행 바꿈을 수행하지 않고 출력하는 특징이 있다.

줄바꿈 하고 싶으면 "\n"을 수행 하면 된다.


이러한 특징 때문에 cat()을 사용해서 테스트 방식의 프로그레스 상태 메시지를 보여줄 수 있다.

> sum_to_ten <- function () {
+     sum <- 0
+     cat(" Adding ...")
+     for (i in 1:10) {
+         sum <- sum + i
+         cat(i, "...")
+     }
+     cat(" Done !", "\n")
+     return (sum)
+ }
> sum_to_ten()
 Adding ...1 ...2 ...3 ...4 ...5 ...6 ...7 ...8 ...9 ...10 ... Done ! 
[1] 55


Cat을 이용한 또다른 디버깅 코드이다.

#for detecting error, analyze each Corpus

sapply(1:length(vTitle), function(x){

    cat(x,'...')

    sms_corpus_clean <- tm_map(sms_corpus[x], content_transformer(tolower))

    if(x%%10 == 0){

        cat('\n')

    }

})



browser()


해당 함수가 호출 되면 명령어의 수행이 중지되고, 해당 시점부터 디버깅 모드가 시작된다.

원하는 부분에다가 직접 browser() 코드를 삽입 해야한다.

그럼 해당 코드 위치에 도달 했을때

Browse[1]> 이라는 명련 표시줄로 변경이 된다.

명령어는 gdb와 대부부 같다.

n,s,c

종료는 Q 이다.


browser()만의 장점은 다음과 같다.

  • 어떠한 editor에서도 사용하다.
  • 추가적으로 conditional breakpoint의 기능을 구현할수도 있다.
for (i in 1:1024) {
  start_work()
  if (i == 512)
    browser()
  finish_work()
}



R-Studio를 이용한 디버깅 방법



아래와 같이 편집기에서 마우스로 클릭하면 breakpoint를 설정 할 수 있다.

해당 라인에서 Shift + F9를 해도 된다.


breakpoint를 설정하면 아래와 같이 걸려있는 함수를 환경변수 패널에서 확인 할 수 있다.


만약 아래와 같은 경고가 나온다면 이유는 두가지 이다.

첫 번째는 source()를 통해서 해당 파일을 읽어 들이지 않아서 그래서 object가 생성되지 않았을 때이다.

두 번째는 editor 상의 file과 source()로 읽어들인 file간의 차이가 존재 했을 때이다.


위 두상황 모두 source()를 해주면 해결 된다.



정상적으로 breakpoint를 걸었다면,

이제 해당 코드를 실행하면 원하는 위치에서 멈추는거을 알 수 있다.

R Studio는 디버깅 명령어들을 모두 위즈윅 모드로 제공하므로 마우스를 써서 디버깅 하면 된다.


디버깅 실행 화면



만약 source 코드가 없는 상태에서 디버깅 하고 싶다면?


install.packages("devtools")


참고문헌: Debugging with RStudio





R Studio 설치법 및 사용 Tip



R Studio의 특징


대화식 R

R 그래픽 작업

코드 구조화, 다수의 프로젝트 관리

분석 내용 재현

R에 설치된 패키지 관리

분석 보고서 작성 및 공유

본인의 코드 공유 및 다른 사용자와의 협업

다양한 적용 가능 플랫폼

윈도우

리눅스

맥 OS X



Comprehensive R Archive Network


R언어를 일단 잘알아야 RStudio를 통해서 통계분석이 가능하다.

위즈윅(WYSIWYG)에 익숙한 사람들, 즉 마우스로 클릭하고 데이터를 이동하는것에 익숙 했던 사람들은 여간 사용하기 어려운것이 아니다.



하지만, 분석의 재현을 위해서는 반드시 각 분석 단계를 소스코드 형태로 저장해야한다.

그래야 분석 과정을 재현하기 쉽다.


프로그래밍 방식은 또한 

단순히 사전식으로 해당 기능에대해서만 동작하는 위즈윅 방식의 툴보다 훨씬 유연하며 강력한 기능을 조합을통해서 달성 할 수 있다.



항상 최신 버전을 사용하라

View(news()) 를통해서 최신 정보를 알 수 있다.

update.packages()를 통해서 페키지를 업데이트 하라



설치방법


1. R을 설치해야한다.


Rstudio는 기본적으로 2.11 이상의 R을 설치해야한다. 

공식 사이트: http://www.r-project.org/

이곳에서 가장 가까운 서버인

http://cran.nexr.com/

위 사이트에서 Window용 R을 다운 받았다.

Tip: 항상 최신 버전의 알을 수시로 확인해서 다운받아서 설치하자


1.1 업데이트 방법

기본적으로 자동 업데이트는 제공하고 있지 않으므로, 이전 버전을 제거한다음 새로 설치하면 된다.


이전 package 설치본들을 복사한 다음 붙여 넣기 한다.

그 다음 현재 package들을 업데이트 한다.

update.packages(checkBuilt=TRUE, ask=FALSE) 


개인 라이브러리의 경우 아래의 경로에 저장 되어 있다.

C:\Users\<사용자이름>\Documents\R\win-library\3.3


현재 R에 설치된 라이브러리 리스트를 얻어서 그대로 재설치하는 방법도 있다.

library()


현재 R의 버전을 알아내는 방법


package_version(R.version)


아래의 명령어를 통해서 설치된 package와 설치된 version을 알 수 있다.


installed.packages()[,c("Package","Version")]
> installed.packages()[,c("Package","Version")]
             Package        Version   
BH           "BH"           "1.58.0-1"
bitops       "bitops"       "1.0-6"   
brew         "brew"         "1.0-6"   
caTools      "caTools"      "1.17.1"  
colorspace   "colorspace"   "1.2-6"   
curl         "curl"         "0.9.3"   



2. R studio 설치

공식 사이트: http://www.rstudio.com/products/rstudio/download/

Tip: RStudio에서

Help > Check for Updates를 클릭하여 신규 업데이트 정보를 확인하자.

업데이트가 필요하면 위 공식 사이트에가서 신규버전으로 다시 설치하자.

아직까지는 자동 업데이트 기능은 없는것 같다.


3. 필수 package 설치 및 로드

R studio의 하단에 보면 package tab이 있다. 이곳에서 이미 설치된 package들의 리스트를 확인 할 수 있다. 


update 버튼을 통해서 기존 package들을 업데이트 할 수도 있다. 


그리고 install을 통해서 새로운 package들을 쉽게 설치 할 수 있다. 


추가로 설치한 리스트

install.packages("ggplot2")

xlsx 

knitr // A General-Purpose Package for Dynamic Report Generation in R


설치된 package를 로드하기위해서는

library 명령어를 타이핑 해도되고

package 창에서 마우스로 check 해도 된다.



단축키 (shortcuts)


Keyboard Shortcuts: R support





GIt을 이용한 버전 관리


git을 설치한다.

자신의 운영체제에 맞춰서 설치파일을 다운로드 한다.

https://git-scm.com/downloads



Next > Next 만을 선택해서 설치한다.

설치확인 방법은 아래와 같이 적당한 디렉터리 아무곳에서나 오른쪽 마우스 클릭을해서

Git bash here 와 같은 명령어들이 모이면 정상적으로 설치된 것이다.




RStudio와 연동하기

메뉴 바에서

Toos -> Global Options -> Git/SVN 에서 Git을 설치한 디렉터리에서 git 실행파일을 연결해 준다.


git



이렇게 하고 재부팅을 해준다.

아래와 같이 정상적으로 git tab이 생성되는것을 알 수 있다.





자료형(integer,character) 변환 및 데이터 구조(dataFrame, list) 변환



자료형


각각의 자료형들간의 변환은 아래의 함수들을 이용 한다.

as.character(x)

as.complex(x)

as.numeric(x) or as.double(x)

as.integer(x)

as.logical(x)





R에서는 데이터 분석을 위한 유용한 데이터 구조를 기본으로 제공해 준다.

데이터 구조(5개): vector, list, data frame, matrix(array), factor 


모드: 

R에서 해당 객체를 메모리에 어떻게 저장할 것인가를 가리키는 것이 "모드"이다

숫자로 저장할 것인가?

문자열 ?

다른 객체로의 포인터로된 리스트들?

함수?

위의 다양한 것들로서 메모리에 저장 될 수 있다.


객체, 예, 모드

숫자, 3.21415, 수치형

숫자백터, c(2, 3), 수치형

문자열, "More", 문자형

문자열 백터, c("More","Larry","Curly"), 문자형

요인, factors(c("NY","CA","IL")),수치형

리스트, list("More","Larry","Curly"), 리스트

데이터 프레임, data.frame(x=1:3, y=c("NY","CA","IL")), 리스트

함수, print, 함수


알아내느 방법

mode()



Class: 추상적인 자료형


R에서는 모든 객체는 추상 자료형인 '클래스'도 가지고 있다.

거리, 시간, 무게 모두 어떤 숫자이므로 모드는 숫자(numeric)이다.

하지만 각각의 해석 방법이 다르므로 클래스는 상이할 수 있다.


결국 클래스가 R에서 직접적인 데이터 처리 방식을 결정하게 된다.


예를들면 print()라는 함수는 입력된 데이터의 class에 따라서 그 처리를 다르게 하는 것이다.

위에서 설명한 모드는 메모리에 저장되는 형태지, 논리적으로 프로그래밍 할 때 쓰는 단위는 아니다.





Factor (범주형 자료)



생성 방법

factor(

x, #팩터로 표현하고자 하는 값(주로 문자열 벡터로 지정)

levels, #값의 레벨

ordered #TRUE면 순서형, FALSE면 명목형 데이터를 뜻한다. 기본값은 FALSE다.

)


팩터에서 레벨의 개수를 반환함.

nlevels(

x # 팩터 값

)


중간에 값 넣기

factor(append(as.character(proximity),"TRUE"))


factor level rename

http://www.cookbook-r.com/Manipulating_data/Renaming_levels_of_a_factor/



Vectors


백터는 동질적이다.

같은 자료형을 가진다.

같은 모드를 가지고 있어야 한다.


스칼라와 백터의 관계는 통상 엄밀히 구분하지만 R에서는 딱히 구분하지 않는다.

하나의 값으로 구성된 백터가 스칼라고

여러개 있으면 백터라고 생각하면 된다.




List


이질적이다.

다양한 자료형을 포함 할수 있다.


생성방법

list <- list(x,y,z) #이질적인 데이터도 가능함.

list <- list(mid=0.5, right=0.841, far=0.9)



접근방법

리스트 변수[[인덱스] # 값을 접근함

리스트 변수[인덱스] # (키,값) 의 형태로 서브 리스트를 반환 한다.


제거방법

x[-2] # without 2nd element

x[-c(2,3)] # without 2nd and 3rd

x["arrival_time"] <- NULL


빈리스트를 생성하고 인덱스를 이름으로 지정하는 방법

vecNames <- list.files("./ESLABCollector/")
filenames <- sapply(vecNames,list)  

Foreach를 사용할 때 list 인덱스의 이름을 유지하는 방법

jsonDfList <- foreach (x = rawDataList, .final = function(x) setNames(x, names(filenames))) %do% {

    jsonTodf(x)

}


.final 을 이용한다.

결국 setNames란 아래의 것을 축약한 기능이다.

setNames( 1:3, c("foo", "bar", "baz") )

# this is just a short form of

tmp <- 1:3

names(tmp) <-  c("foo", "bar", "baz")

tmp



List 중간에 값을 삽입 하기


append(testList, list(x=42), 3)

$`1`

[1] 1

$`2`

[1] 2

$`3`

[1] 3

$x

[1] 42

$`4`

[1] 4


append(lst, list(f=1:5), after=0)# after - position to append

Helper 함수를 생성하는 방법

lappend <- function (lst, ...){
lst <- c(lst, list(...))
  return(lst)
}

> a <- list()
> a
list()

> lappend(a,c(1,2,3))
[[1]]
[1] 1 2 3

> lappend(a, c(4,5,6), c(7,8,9))
[[1]]
[1] 4 5 6

[[2]]
[1] 7 8 9




Matrix


백터에 차원을 정해주면 바로 Matrix로 변경 된다.


백터의 dim 속성이 처음엔 NULL 이지만 이것을 주게 되면 matrix가 된다.

dim(2,3) # 2 by 3 행렬


list도 dim 변경을해서 행렬화 할 수 있다.

하지만 list의 특성상 이질적인 행렬을 만들어 낼 수 있으므로 그러한 것들은 조심해야 한다.




Array (배열)


3차원 matrix 부터는 배열이라는 이름을 쓴다.


Factor(요인)

백터처럼 생겼지만 특별한 속성이 있다.

R은 백터에 있는 고유한 값(unique value)의 정보를 얻어 내는데, 이 고유 값들을 요인의 '수준(level)'이라고 일컫는다.

요인들은 간단하고 효율적인 형태로 데이터 프레임에 저장된다.

다른 프로그래밍 언어에서는 요인을 '열거형 값(enumerated value)들로 이루어진 백터로 표현한다.


요인의 사용처는 아래와 같다.


범주형 변수>

요인 하나는 범주형 변수 하나를 나타낼 수 있다. 

범주형 변수들은 분할표, 선형 회귀, 변량 분석, 로지스틱 회귀 분석 등 많은 분야에서 사용 된다.


집단 분류

이것은 데이터 항목에다가 집다에 따른 라벨을 붙이거나 태깅을 할 때 쓰는 방법이다.




데이터 프레임 (Data Frame)


가장 중요한 데이터 타입이다.

표 형태의 데이터를 표현하기 위함이다.


특징

행은 모두 같은 길이이다. 열은 하나의 엘리먼트를 나타낸다.

행렬과 다른점은 각각의 행들이 서로다른 데이터 타입들을 가질 수 있다는 것이다.

즉, 각각의 열들은 같은 타입으로 이뤄지지만, 모든 열이 모두 같을 필요는 없다.

데이터 프레임의 속성은 row.names()를 통해서 알 수 있다.

통상 read.table() 또는 read.csv()를 통해서 생성 한다.

행렬을 data frame으로 변경 할 수 있다. data.matrix() 호출을 통해서



▣ 데이터 프레임 생성하기

data.frame()을 사용


g <- c("A","B")

x <- 1:3

dat <- data.frame(g,x)


▣ 리스트를 프레임 데이터로 변경

frame.data(list)



▣ 프레임의 구조를 알려준다.

str(data)

> str(ac)

'data.frame': 356 obs. of  2 variables:

 $ Time : num  0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 ...

 $ Power: num  14.8 14.1 19.9 14.6 14.1 ...



▣ 프레임에서 열들만 따로 출력하는 방법이다.

data$time



▣ 데이터 프레임의 Index를 알아내는 방법

> a <- data.frame(1:6,11:16)

> a

  X1.6 X11.16

1    1     11

2    2     12

3    3     13

4    4     14

5    5     15

6    6     16

> grep(15,a[,2])

[1] 5


▣ 해당 컬럼 이름이 몇번째 인지를 알아내는 방법

> grep("X11.16",colnames(a))

[1] 2



▣ 프레임에서 행과 열만 따로 출력하는 방법이다.

data$time[0]



▣ 위치로 데이터 프레임의 열 선택하기


스타일에 따라 또는 데이터프레임 두가지 자료형중 하나로 반환 된다.


데이터 프레임 스타일의 선택 방법

dfm[[n]] # 하나의 열을 반환 한다.

dfm[n] # n번째 열 단독으로만 구성된 '데이터 프레임'을 반환 한다.

dfm[c(n1,n2,...,nk)] # n1,n2,....,nk 위치에 있는 열들로 만든 "데이터 프레임"을 반환한다.


행렬 방식의 첨자 지정을 이용해서 선택 하는 방법

dfm[,n] # n번째 을 반환 한다

dfm[,c(n1,n2,...,nk)] # n1,n2,...,nk 위치에 있는 열들로 만든 "데이터 프레임"을 반환 한다.



▣ 프레임 열의 이름을 변경하는 방법이다.

names(data) <- c("name1", "name2", "name3")

 


▣ 특정 열을 찾아서 이름을 변경하는 방법

> names(ac)[names(ac)=="Time"] <- c("newTime")

> names(ac)

[1] "newTime" "Power"  

> names(ac)[names(ac)=="newTime"] <- c("Time")

> names(ac)

[1] "Time"  "Power"



▣ 데이터 프레임에 열 추가하기

새로운 열의 이름을 설정하고 "NA"로 채운다.

data$newcol <- NA


새로운 열의 이름을 설정하고 백터를 삽입한다.

data$newcol <- vec



▣ 데이터 프레임에 열을 제거하기

해당열에 NULL을 대입한다.


data$badcol <- NULL

subset(data, select = -badcol)

subset(data, select = c(-badcol, -othercol)



▣ 데이터 프레임 열 순서 변경하기

#숫자로 해당열을 선택해서 변경한다.

dat <- dat[c(1,3,2)]


#이름으로 선택해서 변경 한다.

data <- dat[c("col1","col3","col2")]



▣ 데이터 프레임의 부분 집합 취하기

subset() 함수를 이용해서 부분 집합을 취할 수 있다.


일련의 조건을 기입하고 그 조건에 맞는 행등을 추출 할 수 있다.


subset(climate, Source == "Berkeley", select = c(Year, Anomaly10y))

# 데이터 셋 climate에서

# Source 열이 "Berkeley인 것에 대해서

# Year 와 Anomaly10y의 열에 대해서만 그 값을 추출 


논리 연산자를 조합하면 일정 범위 내의 데이터를 추출 할 수도 있다.


1900년에서 2000년 사이의 source가 "Berkeley"인 행들만 선택 한다.

subset(climate, Source == "Berkeley" & Year >= 1900 & Year <= 2000, select = c(Year, Anomaly10y))



▣ 여러가지 방법을 이용한 데이터 프레임 합치기


데이터 프레임 합치기

cbind # 두개의 데이터를 열로 쌓는다.

rbind # 두개의 데이터를 행으로 쌓는다.


연속적인 리스트라면,

do.call(rbind,mylist)를 하면된다.


주의: 위방법들은 모두 행열이 같은 크기일때만 가능함

크기가 서로 다르면 반복해서 아랫부분을 채워준다고 하지만 이상하게 동작하지 않는다.


서로다른 데이터 프레임 합치기

merge # SQL에서 join에 해당하는 명령어이다

default로 동작은 그냥 다순히 합치는 것이다.

일치하지 않는것이 있다면 데이터의양이 NxM의 양으로 늘어 난다.


일치하는 부분만 합치고 싶으면,

merge(A,B, by="열 이름") 

으로 설정한다.


merge의 다른 option들

## S3 method for class 'data.frame'
merge (x, y, by = intersect(names(x), names(y)),
      by.x = by, by.y = by, all = FALSE, all.x = all, all.y = all,
      sort = TRUE, suffixes = c(".x",".y"),
      incomparables = NULL, ...)

x, y

data frames, or objects to be coerced to one.

by, by.x, by.y

해당 기준으로 합친다. 없는것는들은 제거한다.

즉, 가장 짧은 기준으로 합친다.

5, 10 이라면 5만큼 길이가 설정됨.

all

logical; all = L is shorthand for all.x = L and all.y = L, where L is either TRUE or FALSE.

all.x

logical; if TRUE, then extra rows will be added to the output, one for each row in x that has no matching row in y. These rows will have NAs in those columns that are usually filled with values from y. The default is FALSE, so that only rows with data from both x and y are included in the output.

all.y

logical; analogous to all.x.

sort

logical. Should the result be sorted on the by columns?

suffixes

a character vector of length 2 specifying the suffixes to be used for making unique the names of columns in the result which not used for merging (appearing in by etc).

incomparables

values which cannot be matched. See match. This is intended to be used for merging on one column, so these are incomparable values of that column.


서로다른 크기의 데이터 프레임 합치기

일치하지 않는 컬럼을 단순히 <NA>로 채우고 싶다면,

plyr package의 rbind.fill을 사용하면 된다.



향상된 데이터 프레임 합치기

reshape2 package

본인 정리

Reshape and aggregate data with the R package reshape2


plyr package

본인정리


데이터 프레임 행과 열 크기 알아내기

nrow()

ncol()


help(package = "reshape2")

원본 참고 사이트: http://seananderson.ca/2013/10/19/reshape.html

reshape 2 website: http://had.co.nz/reshape/



서로 다른 데이터 타입들간의 데이터 상호 변환




변환 

방법 

주석 

 벡터 -> 리스트

as.list(vec) 

 

 벡터 -> 행렬

cbind(), as.matrix()

rbind(), matrix(vec,n,m) # n by m 행렬 

생성 

 

 벡터 ->데이터 프레임

#열 한 개짜리 데이터 프레임

as.data.frame(vec)

# 행 한 개짜리 데이터 프레임

as.data.frame(rbind(vec))

 

 리스트 -> 벡터

unlist(list)

as.vector 대신에 unlist가 좋다. 

 리스트 -> 행렬 

열 한 개짜리 행렬: as.matrix(list)

행 한 개짜리 행렬: as.matrix(rbind(list))

n by m 행렬: matrix(list,n,m) 

 

 리스트 -> 데이터 프레임

목록 원소들이 데이터의 열이면:

as.data.frame(list)

 

 

 행렬 -> 벡터

 as.vector(mat) 

 행렬의 모든 원소들을 벡터로 반환 한다. 

 행렬 -> 리스트

 as.list(mat)

 행렬의 모든 원소들을 리스트로 변환 한다.

 행렬 -> 데이터 프레임

 as.data.frame(mat) 

  

 데이터 프레임 -> 벡터

 dfm[1,]#행 하나 짜리 데이터 프레임 변환

 dfm[,1] or dfm[[1]] #열 하나짜리 데이터 프레임 변환

 

 데이터 프레임 -> 리스트

 as.list(dfm)

 

 데이터 프레임 -> 행렬

 as.matrix(dfm)

 






'AI > R Basic' 카테고리의 다른 글

R 기본 디버깅 (Debugging) 및 RStudio 이용  (0) 2015.10.04
R Studio 설치법 및 사용 Tip  (0) 2015.10.04
Apply 함수 (데이터 조작)  (1) 2015.10.03
R의 문자열 처리 및 비교  (0) 2015.10.03
Plyr package (데이터 조작)  (0) 2015.10.01

R에서는 주로 벡터 기반으로 데이터를 처리 한다.

벡터기반 처리는 개별 요소를 for 루프 등으로 하나씩 처리하는 방식보다 빠르게 수행될 뿐만 아니라 손쉽게 병렬화가 가능하다.

따라서 대부분의 Machine Learning이나 통계 함수들은 입력값으로 벡터를 받는다.


따라서 데이터를 벡터로 변환하고 다시 벡터데이터를 가독성 높은 데이터 프레임으로 변경하는 것을 자유 자재로 할 수 있어야한다.

앞으로 보게될 많은 R 코드들은 모두 이러한 벡터 연산들을 이용하기 때문에 벡터를 다루는 함수들을 잘 알고 있어야 한다.



Apply 함수 (데이터 조작)


벡터화된 연산과 apply함수를 이용해서 일괄 실행함으로써 계산을 간소화하고 고속화를 도모 한다.

다양한 데이터를 임의의 함수에 적용하 결과를 얻는 방법으로 apply  함수들을 이용하는 방법이 있다.

이들 함수는 벡터, 행렬, 리스트, 데이터 프레임에 적용할 함수를 명시하는 형태로서, 함수형 언어 스타일에 가깝다고 볼 수 있다.



apply 함수들의 요약


apply() 

배열 또는 행렬에 주어진 함수를 적용한 뒤 그 결과를 벡터, 배열 또는 리스트로 반환

배열 또는 행렬에 적용 가능


lapply()

벡터, 리스트 또는 표현식에 함수를 적용하여 그 결과를 리스트로 반환

결과가 리스트


sapply() 

lappy()와 유사하지만 결과를 벡터, 행렬 또는 배열로 반환

결과가 벡터, 행렬 또는 배열


tapply()

벡터에 있는 데이터를 특정 기준에 따라 그룹으로 묶은 뒤 각 그룹맏 주어진 함수를 적용하고 그 결과를 반환

여러 데이터를 함수의 인자로 적용


mapply() 

sapply의 확장된 버전으로, 여러 개의 벡터 또는 리스트를 인자로 받아 함수에 각 데이터의 첫째 요소들을 적용한 결과,

둘째 요소들을 적용한 결과, 셋째 요소들을 적용한 결과 등을 반환

여러 데이터를 함수의 인자로 적용 가능



▣ Apply 사용법


apply: 배열 또는 행렬에 함수 f를 d방향으로 적용하여 결과를 벡터, 배열 또는 리스트로 반환 한다.

apply( X, d, f)

X #배열 또는 행렬

d # 함수를 적용하는 방향, 1은 행방향, 2는 열 방향

  # c(1,2)는 행과 열 방향 모두를 의미

FUN # 적용할 함수


예제

#합 구하는 함수
> sum(1:10)
[1] 55
# 메트릭스 생성
> d <- matrix(1:9, ncol=3)
> d
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
# 각각의 행을 더해서 벡터로 반환 한다.
> apply(d,1,sum)
[1] 12 15 18
# 각각의 열을 더해서 벡터로 반환 하다.
> apply(d,2,sum) 
[1]  6 15 24


> head(iris[c(1,2,3,4)])
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1          5.1         3.5          1.4         0.2
2          4.9         3.0          1.4         0.2
3          4.7         3.2          1.3         0.2
4          4.6         3.1          1.5         0.2
5          5.0         3.6          1.4         0.2
6          5.4         3.9          1.7         0.4
# 벡터 스타일의 선택
> apply(iris[c(1,2,3,4)],2,sum)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
       876.5        458.6        563.7        179.9 
# 메트릭스 스타일의 선택
> apply(iris[,1:4],2,sum)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
       876.5        458.6        563.7        179.9




▣ lapply 사용법


리스트로 반환하는 특징이 있는 apply 계열 함수이다.


lapply (X, FUN, ...#추가인자) 

반환 값은 X와 같은 길이의 리스트이다.

X는 벡터, 리스트, 표현식, 데이터 프레임을 받을 수 있다.


리스트를 다른 타입으로 변환 하는 방법 

unlist( x, recursive=FALSE, use.name=TRUE )

반환 값은 벡터이다.


do.call # 함수를 리스트로 주어진 인자에 적용하여 결과를 반환한다.

(적용할 함수, 데이터 리스트)

반환 값은 함수 호출 결과다.



# 벡터 입력을 받아서 리스트로 반환하는 코드이다.
> result <- lapply(1:3, function(x){x*2})
> result
[[1]]
[1] 2

[[2]]
[1] 4

[[3]]
[1] 6

> result[[1]]
> unlist(result) # list 구조를  벡터로 변경 한다.
[1] 2 4 6


입력을 list로 받을 수도 있다.

> x <- list(a=1:3, b=4:6)
> x
$a
[1] 1 2 3

$b
[1] 4 5 6

> lapply(x,mean)
$a
[1] 2

$b
[1] 5


# iris의 데이터 구조를 보여줌
> head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

# list로 반환됨 각각의 열들의 평균을 구한다음
> lapply(iris[,1:4],mean)
$Sepal.Length
[1] 5.843333

$Sepal.Width
[1] 3.057333

$Petal.Length
[1] 3.758

$Petal.Width
[1] 1.199333

#각 열에 대한 평균을 구하게 된다.
> colMeans(iris[,1:4])
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333


데이터 프레임을 처리한 결과를 리스트로 얻은 뒤 해당 리스트를 다시 데이터 프레임으로 변활할 필요가 있다. 

이 변환은 몇 단계를 거쳐서 처리해야 한다.

  • unlist()를 통해 리스트를 벡터로 변환한다.
  • matrix()를 사용해 벡터를 행렬로 변환한다.
  • as.data.frame()을 사용해 행렬을 데이터 프레임으로 변환한다.
  • names()를 사용해 리스트로부터 변수명을 얻어와 데이터 프레임의 각 컬럼에 이름을 부여한다.


iris 데이터의 각 열의 평균을 구한다음

이 결과는 list로 반환 되므로 이것을 다시 데이터 프레임으로 변경해서 출력하는 예제이다.

># 데이터 프레임으로 변겨하는 코드이다.
# matrix()로 먼저 변환 하는 것은 vector를 바로 data frame으로 변경하면 단일 열로 밖에 변경을 못하기 때문이다.
 d <- as.data.frame(matrix(unlist(lapply(iris[,1:4],mean)),ncol=4,byrow=TRUE))
> d
        V1       V2    V3       V4
1 5.843333 3.057333 3.758 1.199333
> d <- as.data.frame(matrix(unlist(lapply(iris[,1:4],mean)),ncol=4,byrow=TRUE))
> d
        V1       V2    V3       V4
1 5.843333 3.057333 3.758 1.199333
#위와 같이 이름이 자동으로 설정되므로 가독성을 위해서 이름을 변경해 준다.
> names(d) <- names(iris[,1:4])
> d
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.843333    3.057333        3.758    1.199333



unlist 방식의 경우 벡터로 바꾸기 때문에 데이터 타입이 서로 다를 경우 엉뚱한 값으로 바꿔버리게 된다.

> x <- list(data.frame(name="foo",value=1),data.frame(name="bar",value=2))
> x
[[1]]
  name value
1  foo     1

[[2]]
  name value
1  bar     2

> unlist(x)
 name value  name value 
    1     1     1     2 

이렇게 서로 다른 데이터로 구성된 list를 데이터 프레임으로 변경 해야한다면,

do.call() 함수를 이용 해야 한다.

> do.call(rbind,x)
  name value
1  foo     1
2  bar     2

하지만, 해당 방식은 속도면에서 문제가 발생 한다.

그래서 rbindlist()를 사용하게 된다.




▣ sapply 사용법


lapply의 사용자 친화 버전이다. 해당 함수는 리스트 대신에 
행렬과 벡터 등의 데이터 타입으로 결과를 반환하는 특징이 있는 함수 이다.

벡터 리스트 표현식 데이터 프레임등에 함수를 적용하고 그 결과를 벡터 또는 행렬로 반환한다.
sapply {
X, # 벡터, 리스트, 표현식 또는 데이터 프레임
FUN, # 적용할 함수
....., # 추가 인자, 이 인자들은 FUN에 전달된다.
}

> sapply(iris[,1:4],mean)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333 
> class(sapply(iris[,1:4],mean))
[1] "numeric"


sapply로 연산하고 벡터를 data frame으로 변경하는 방법이다.

> sapply(iris[,1:4],mean)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333 
> class(sapply(iris[,1:4],mean))
[1] "numeric"
> x <- sapply(iris[,1:4],mean)
> as.data.frame(x)
                    x
Sepal.Length 5.843333
Sepal.Width  3.057333
Petal.Length 3.758000
Petal.Width  1.199333
> as.data.frame(t(x))
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.843333    3.057333        3.758    1.199333


sapply를 이용해서 각 컬럼의 데이터 타입을 구할 수도 있다.

> sapply(iris,class)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
   "numeric"    "numeric"    "numeric"    "numeric"     "factor"

다음은 조건문을 이용해서 iris 데이터 집합중에서 3보다 큰지 여부를 판단하는 코드이다.

반환값은 행렬이 된다.

> y <- sapply(iris[,1:4], function(x) {x>3})
> class(y)
[1] "matrix"
> head(y)
     Sepal.Length Sepal.Width Petal.Length Petal.Width
[1,]         TRUE        TRUE        FALSE       FALSE
[2,]         TRUE       FALSE        FALSE       FALSE
[3,]         TRUE        TRUE        FALSE       FALSE
[4,]         TRUE        TRUE        FALSE       FALSE
[5,]         TRUE        TRUE        FALSE       FALSE
[6,]         TRUE        TRUE        FALSE       FALSE

주의해야할 사항은 벡터를 반환 하기 떄문에 sapply를 사용할 때는 데이터 타입을 혼합하여 처리하면 안된다.

데이터 타입을 혼합해야 할 경우에는 lapply를 사용하거나 plyr 페키지에 있는 ddply를 사용해야 한다.


▣ tapply() 사용법


tapply{

X 벡터

Index 데이터를 그룹으로 묶을 색인, 팩터를 지정해야 하며 팩터가 아닌 타입이 지정되면 팩터로 형 변환된다.

FUN 각 그룹마다 적용 할 함수

...., 추가 인자. 이 인자들은 FUN에 전달된다.

}

반환 값은 배열이다.


아래의 코드는 간단한 하나의 그룹 1에 대한 합을 나타낸다.

# rep는 1을 10번 반복하라는 뜻이다. 이렇게해서 1:10 까지의 벡터에 factor 데이터 1을 모두 맵핑해서 하나의 그룹으로 만들어 준다.
> rep(1,10)
 [1] 1 1 1 1 1 1 1 1 1 1
> tapply(1:10, rep(1,10),sum)
 1 
55


# 홀수 짝수를 나누어서 연산하는 것이다.
tapply(1:10,1:10%%2 ==1,sum)
FALSE  TRUE 
   30    25 


조금더 복잡한 연산으로 iris 데이터들중에서 length의 평균을 구하는데 그것을 specie에 따라서 구하는 것이다.

> head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa
> tapply(iris$Sepal.Length, iris$Species, mean)
    setosa versicolor  virginica 
     5.006      5.936      6.588 


이제 더 복잡한 예제를 살펴보자. 아래의 예제는 추후에 클러스터링 알고리즘을 적용한 다음에 (k-mean clustering)

같은 cluster에 속한 데이터들의 x와 y 좌표의 각가그이 평균을 구하는 용도로 사용 될 수 있다.

#데이터를 아래와 같이 생성 한다.
> m <- matrix(1:8, ncol=2, dimnames=list(c("spring","summer","fall","winter"),c("male","female")))
> m
       male female
spring    1      5
summer    2      6
fall      3      7
winter    4      8

위와 같이 데이터 구조를 생성 했을 때

이때 분기별 과 성별 셀의 합을 구해보자.


상반기 봄, 여름에 대한 남성의 셀 합은 1+2로 구할 수 있다. 그리고 여성의 합은 5+6이다.

하반기 가을, 겨울의 남성의 셀 합은 3+4이고 여성의 합은 7+8이다.


Index를 설정하기 위해서 (n,m)에서 n을 먼저 나열한 뒤 m 값을 나열한다. 

즉, 그룹 (n1, m1), (n2, m2)는 list( c(n1,n2), c(m1,m2))로 표현된다.

> tapply(m, list(c(1,1,2,2,1,1,2,2),c(1,1,1,1,2,2,2,2)),sum)
  1  2
1 3 11
2 7 15


▣ mapply() 사용법


sapply와 유사하지만 다수의 인자를 함수에 넘긴다는 점에서 차이가 존재 한다.

sapply 처럼 행렬과 벡터반환 하게 된다.


1) 여러개의 인자를 보내야 하는 경우에 사용 한다.

2) 어떤 함수에 여러개의 벡터를 입력으로 주고 싶은 경우

a,b를 받아서 처리하는 함수가 있을때

c(....), c(....) 이런식으로 2개의 벡터를 입력으로 보내서 연속적인 처리를 할 수 있다.



mapply: 함수에 리스트 또는 벡터로 주어진 인자를 적용한 결과를 반환 한다.

Fun #실행할 함수

... # 적용할 인자



rnorm의 경우 n개의 데이터를 mean에 대해서 sd인 정규 분포를 생성 한다.


그냥 rnorm을 세번 호출하면 되지만 편의를 위해서 mapply를 이용했다.

세개인자를 rnorm함수로 전달해서 연살을 수행하게 된다.

> mapply(rnorm, c(1,2,3),c(0,10,100),c(1,1,1))
[[1]]
[1] 0.5746612

[[2]]
[1] 10.026820  9.574186

[[3]]
[1]  99.53101  98.92185 101.26264

#iris 데이터의 경우 아래와 같이 수행 된다.
> mapply(mean,iris[,1:4])
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333 

> sapply(iris[,1:4],mean)
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
    5.843333     3.057333     3.758000     1.199333 

> lapply(iris[,1:4],mean)
$Sepal.Length
[1] 5.843333

$Sepal.Width
[1] 3.057333

$Petal.Length
[1] 3.758

$Petal.Width
[1] 1.199333




R의 문자열 처리 및 비교


문자열 길이 알아내기

nchar

문자열 연결 하기

paste("Everybody", "loves", "you.")

비칸을 이용해서 합쳐지며, 다른 문자를 쓰고 싶으면 seq="" 옵션을 이용 한다.

하위 문자열 추출 하기

substr(string,start,end)

string에서 strat에서 시작하고 end에서 끝나는 문자열을 추출 한다.

구분자료 문차열 추출

strsplit(문자열, 구분자)
반환값은 리스트이고
각각의 리스트 원소들은 백터이다.
이렇게 두개의 수준으로 된 구조가 필요한 이유는 
첫 인자가 문자열로 된 백터일 수 있기 때문이다.
각 문자열은 자신의 하위 문자열들(백터)로 분할 된다.
그리고 나서 이 벡터들이 리스트로 반환되는 것이다.

> path <- "/home/mike/data/trials.csv"
> strsplit(path,"/")
[[1]]
[1] ""           "home"       "mike"       "data"       "trials.csv"
> paths <- c("/home/mike/data/trials.csv","/home/mike/data/data.csv","/home/mike/data/error.csv") 
> path <- "/home/mike/data/trials.csv"
> strsplit(paths,"/")
[[1]]
[1] ""           "home"       "mike"       "data"       "trials.csv"

[[2]]
[1] ""         "home"     "mike"     "data"     "data.csv"

[[3]]
[1] ""          "home"      "mike"      "data"      "error.csv"

하위 문자열 대체하기

sub(old,new,string)
첫 번째 하위 문자열을 대체한다.

gsub(old,new,string)
모든 하위 문자열을 대체한다.

정규 표현식을 없앨려면 fixed = TRUE 옵션을 사용 한다.

문자열 특수문자 보기

cat

문자열의 모든 쌍별 조합 생성

m <- outer(문자열1, 문자열2, paste, seq="")

문자열 비교하는 함수

가능한 함수는 아래와 같고
grepgreplregexprgregexprregexec

grep을 이용해서 
어떤 패턴의 문자열을 
원하는 문자로 변경하는 방법은 아래와 같다.

#아래와 같은 샘플이 있다고 가정하자.
Sample <- c("BU1", "BU2", "BM1", "BD1", "BU3") 

#grep을 수행 할 경우
> grep("^BU", Sample) 
c(1,2,5)

> section <- character(length(Sample)) 
> section[grepl("^BU", Sample)] <- "up" 
> section[grepl("^BM", Sample)] <- "mid" 
> section[grepl("^BD", Sample)] <- "down" 
> section
[1] "up"   "up"   "mid"  "down" "up"

# mapping 방식을 이용한 것도 있다.
# 방법 1
map <- c(BU="up", BM="mid", BD="down") 
section <- unname(map[substring(Sample, 1, 2)]) 
section
[1] "up"   "up"   "mid"  "down" "up" 

# 방법 2
from <- c("BU", "BM", "BD") 
to <- c("up", "mid", "down") 
section <- to[match(substring(Sample,1,2), from)] 
section
[1] "up"   "up"   "mid"  "down" "up"  

IF 와 grep을 혼용해서 사용하는 방법

if(length(grep(x,y))==0)
any(grep(x,y))

반복문을 돌면서 두개의 문자열이 같은지 비교하는 코드

pmatch를 이용한다.

sapply(1:length(singleplace$V1), function(x){

    #pmatch(singleplace$V1[x],multieplace$V1[x])
    pmatch(singleplace$V2[x],multieplace$V2[x])
}
)

기타 Match함수로는 아래의 것들이 있다.

> as.logical(match(x,1,nomatch=FALSE))
[1] FALSE
> 1:10 %in% c(1,3,5,9)
 [1]  TRUE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE


Plyr package (데이터 조작)


plyr는 reshape2와 마찬가지로 Hadley Wickham에 의해서 개발 되었다.
2011년에 해당 논문이 아래와 같이 출간되었다.

The split-apply-combine strategy for data analysis(2011, Journal of Statistical Software, Vol 40).

데이터들을 쪼개고, 일부부늘 취하며, 어떤 특정 함수를 특정 부분에 적용하고
그리고 결과들을 조합하는 향상된 기능을 제공하는 패키지이다.

그 밖에도
loop의 재배치를 제공한다.

로드법

install.packages("plyr")
library(plyr)

apply 종류가 많다. 하지만 데이터 프레임을 위한것은 없다.
이때 plyr package에 있는 ddply를 이용한다.

함수 제공 형태

  • 배열(a)
  • 데이터 프레임(d)
  • 리스트(l)
  • _는 아무런 출력도 내보내지 않음을 의미함.
{adl}{adl_}ply
입력 데이터 타입출력 데이터 타입

유용한 함수: adply()ddply()mdply()
유용한 유틸리티 함수: transform()mutate()summarise()subset()

Adply()

Adply()는 배열(a)를 받아 데이터 프레임(d)을 반환하는 함수이다. 
입력이 반드시 배열일 필요는 없고 숫자 색인으로 접근 가능 하기만 하면된다.
따라서 데이터 프레임도 입력으로 사용이 가능하다.

apply()의 단점인 문자열 데이터가 섞여 있다면 데이터가 모두 문자열로 반환된다는 점을 개선한 것이다.

adply(
.data, # 행렬, 배열, 또는 데이터 프레임
# 함수를 적용할 방향. 1(행 방향), 2(열 방향) 또는 c(1,2) 행과 열의 모든 방향을 지정 한다.
.margins,
.fun=NULL # .margin 방향으로 잘려진 데이터에 적용할 함수

반환 값은 데이터 프레임이다.

apply와 유사하지만 반환 값이 데이터 프레임이라는 차이가 있다.

예제

#적용 전
 Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
adply(iris, 1 , function(row){ row$Sepal.Length >= 5.0 & row$Species == "setosa"})

    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species    V1
1            5.1         3.5          1.4         0.2     setosa  TRUE
2            4.9         3.0          1.4         0.2     setosa FALSE
3            4.7         3.2          1.3         0.2     setosa FALSE

예제: 컬럼에 이름 부여

adply(iris, 1 , function(row)
{ 
    data.frame( sepal_ge_5_setosa = c(row$Sepal.Length >= 5.0 & row$Species == "setosa"))
}
)

    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species sepal_ge_5_setosa
1            5.1         3.5          1.4         0.2     setosa              TRUE
2            4.9         3.0          1.4         0.2     setosa             FALSE

Ddply()

ddply()는 데이터 프레임(d)을 입력으로 받아 데이터 프레임(d)을 내보내는 함수 이다.

ddply(
.data,
.variables, #데이터를 그룹 지을 변수명
.fun=NULL
)

반환 값은 데이터 프레임이다.

adply()와 ddply()의 가장 큰 차이점이라면 adply()는 행 또는 컬럼 단위로 함수를 적용하는 반면
ddply()는 .variables에 나열한 컬럼에 따라 데이터를 나눈 뒤 함수를 적용한다는 점이다.

아래와 같이.()안의 컬럼으로 데이터를 묶은 다음에 function안에 있는 함수를 적용 하게 된다.
데이터 프레임의 컬럼의 이름은 sepal.width.mean이며, 각 Species에 대해서 묶고 그것들의 Sepal.Width의 평균을 구하는 코드이다.

ddply(iris, .(Species), function(sub){
    data.frame(sepal.width.mean = mean(sub$Sepal.Width))
})
     Species sepal.width.mean
1     setosa            3.428
2 versicolor            2.770
3  virginica            2.974

추가 조건을 기입한 예제는 아래와 같다.

ddply(iris, .(Species, Sepal.Length > 5.0), function(sub){
    data.frame(sepal.width.mean = mean(sub$Sepal.Width))
})

     Species Sepal.Length > 5 sepal.width.mean
1     setosa            FALSE         3.203571
2     setosa             TRUE         3.713636
3 versicolor            FALSE         2.233333
4 versicolor             TRUE         2.804255
5  virginica            FALSE         2.500000
6  virginica             TRUE         2.983673

Mdply()

m{adl_}ply(), 즉 maply()mdply()mlply()m_ply()함수는 데이터 프레임 또는 
배열을 인자로 받아 각 컬럼을 주어진 함수에 적용하고 그 실행 결과들을 조합한다.
여기서는 이들 중 mdply()에 대해서 살펴본다.

plyr::mdply(
.data, # 인자로 사용할 행렬 또는 데이터 프레임
.fun, # 호출할 함수
)
# 반환 값은 데이터 프레임이다.

Transform, Mutate, Summarise, Subset

데이터 프레임을 반환 한다.

base::transform( 
.data # 변환할 객체
...   # 태그=값 형태의 인자들
)

데이터 프레임 _data에 ...에 지정한 연산을 수행한 뒤 그 결과를 지정한 새로운 컬럼을 추가한 데이터 프레임을 반환한다.

데이터 프레임에 새로운 컬럼을 추가하거나 기존 컬럼을 수정 한다.

plyr::mutate(
.data, # 변환할 데이터 프레임
... # 새로운 컬럼 정의. 컬럼명 = 값 형식
)

변환이 이루어진다는 점은 transform()과 같지만 컬럼명=값 형태로 지정된 연산이 여러 개 있을 때 앞서의 연산 결과를 뒤에 나오는 연산에서 참조할 수 있다는 차이가 있다.

plyr:summarise: 데이터 프레임을 요약 한다.

plyr::summarise(
.data, # 요약할 데이터 프레임
... # 변수=값 형태의 인자들
)

...에 지정된 그룹마다의 요약을 수행한 뒤 그 결과를 저장한 새로운 컬럼이 추가된 데이터 프레임을 반환한다.

subset은 이전 POST 참조

Transform()

transform은 연산 결과를 데이터 프레임의 새로운 컬럼에 저장하는 함수이다.

이를 사용해 baseball 데이터에 각 행이 선수의 몇 년차 통계인지를 뜻하는 cyear 컬럼을 추가해보자.
다음 코드는 데이터를 선수id로 분할하여 그룹 지은 뒤, 각 그룹에세 year의 최솟값과 현재 행의 year값의 차이를 cyear에 저장 한다.

> head(ddply(baseball, .(id), transform, cyear = year - min(year) + 1))

         id year stint team lg   g  ab   r   h X2b X3b hr rbi sb cs bb so ibb hbp sh sf gidp cyear
1 aaronha01 1954     1  ML1 NL 122 468  58 131  27   6 13  69  2  2 28 39  NA   3  6  4   13     1
2 aaronha01 1955     1  ML1 NL 153 602 105 189  37   9 27 106  3  1 49 61   5   3  7  4   20     2
3 aaronha01 1956     1  ML1 NL 153 609 106 200  34  14 26  92  2  4 37 54   6   2  5  7   21     3
4 aaronha01 1957     1  ML1 NL 151 615 118 198  27   6 44 132  1  1 57 58  15   0  0  3   13     4
5 aaronha01 1958     1  ML1 NL 153 601 109 196  34   4 30  95  4  1 59 49  16   1  0  3   21     5
6 aaronha01 1959     1  ML1 NL 154 629 116 223  46   7 39 123  8  0 51 54  17   4  0  9   19     6

Mutate()

base::transform()을 개선한 plyr::mutate() 함수가 있다. 이 함수는 여러 컬럼을 데이터 프레임에 추가할 때 바로 앞서 추가한 컬럼을 뒤에 추가하는 컬럼에서 참조할 수 있어 편리하다. 예를 들어, 아래 코드에서 muate()를 이용해 transform() 예에서처럼 cyear를 계산한 뒤log(cyear)를 log_cyear컬럼으로 추가 한다. 
만약 mutate()가 아닌 transform()을 사용하면 이 경우 에러가 발생 한다.

> head( ddply(baseball, .(id), mutate, cyear=year - min(year)+1, log_cyear = log(cyear)))
> 
         id year stint team lg   g  ab   r   h X2b X3b hr rbi sb cs bb so ibb hbp sh sf gidp cyear log_cyear
1 aaronha01 1954     1  ML1 NL 122 468  58 131  27   6 13  69  2  2 28 39  NA   3  6  4   13     1 0.0000000
2 aaronha01 1955     1  ML1 NL 153 602 105 189  37   9 27 106  3  1 49 61   5   3  7  4   20     2 0.6931472
3 aaronha01 1956     1  ML1 NL 153 609 106 200  34  14 26  92  2  4 37 54   6   2  5  7   21     3 1.0986123
4 aaronha01 1957     1  ML1 NL 151 615 118 198  27   6 44 132  1  1 57 58  15   0  0  3   13     4 1.3862944
5 aaronha01 1958     1  ML1 NL 153 601 109 196  34   4 30  95  4  1 59 49  16   1  0  3   21     5 1.6094379
6 aaronha01 1959     1  ML1 NL 154 629 116 223  46   7 39 123  8  0 51 54  17   4  0  9   19     6 1.7917595

Summarise()

transform이 인자로 주어진 계산 결과를 새로운 컬럼에 추가한 데이터 프레임을 반환하는 반면,
summarise()는 계산 결과만을 담은 새로운 데이터 프레임을 반환 한다.

baseball 데이터에서 각 선수의 최초 데이터가 몇 년도인지를 조사해보자.
아래 예에서는 데이터를 id마다 그룹지은 뒤 각 그룹마다 year의 최솟값을 계산한 minyear 컬럼을 생성 했다.
연산 시 사용할 함수로 summarise()를 지정했으므로 그룹을 짓는 변수인 id와 각 그룹의 요약 값 minyear만 저장된 데이터 프레임이 반환됐다.

> head (ddply(baseball, .(id), summarise, minyear=min(year)))
         id minyear

1 aaronha01    1954
2 abernte02    1955
3 adairje01    1958
4 adamsba01    1906
5 adamsbo03    1946
6 adcocjo01    1950

만약 여러 요약 값을 구하고 싶다면 요약 값 계산을 계속 나열한다.

> head (ddply(baseball, .(id), summarise, minyear=min(year), maxyear=max(year)))
         id minyear maxyear

1 aaronha01    1954    1976
2 abernte02    1955    1972
3 adairje01    1958    1970
4 adamsba01    1906    1926
5 adamsbo03    1946    1959
6 adcocjo01    1950    1966


'AI > R Basic' 카테고리의 다른 글

Apply 함수 (데이터 조작)  (1) 2015.10.03
R의 문자열 처리 및 비교  (0) 2015.10.03
Reshape2 pacakge (데이터 조작)  (0) 2015.10.01
R 자주 사용하는 팁 및 한글 주석 깨짐 해결  (2) 2015.07.30
R의 철학  (0) 2015.04.17

Reshape2 pacakge (데이터 조작)


해당 페키지는 Handley Wickham에 의해서 2007년에 개발된 것이다.

해당 기능은 아래의 저널에 게재 되었다. 해당저널은 JCR 기준 상위 5%이내의 저널이다.

Reshaping Data with the reshape Package. Journal of Statistical Software



reshape2 package를 이용하는 방법

CRAN에서 제공하는 페키지이다. 좀더 향상된 기능의 자르고 쪼개고 재결합하는 기능을 담고 있다.


우리는 때때로 Wide-format 또는 Long-format을 시시각각 원한다.



Wide-format data

ozone   wind  temp
1 23.62 11.623 65.55
2 29.44 10.267 79.10
3 59.12  8.942 83.90
4 59.96  8.794 83.97



Long-format data

    variable  value
 1     ozone 23.615
 2     ozone 29.444
 3     ozone 59.115
 4     ozone 59.962
 5      wind 11.623
 6      wind 10.267
 7      wind  8.942
 8      wind  8.794
 9      temp 65.548
 10     temp 79.100
 11     temp 83.903
 12     temp 83.968


wide-format의 경우 데이터를 분석 할때 주로 쓰이고

long-format은 그외의 모든 경우에 이용된다.

ggplot2

plyr

modeling functions ( lm(), glm(), gam(), etc)


해당 페키지의 key function은 아래와 같다.


melt: wide-format data를 읽어서 그것을 long-format으로 변경함.

cast: long-format data를 읽어서 그것을 wide-format으로 변경함.



melt 설명

melt은 value와 variable로 구분되서 동작한다.

즉 변수(variable)에 대해서 값(value)를 매칭하는 방식으로 넓게 퍼진 데이터를 길게 변경한다.


melt default의 동작 방식은

numeric data를 포함하는 모든 열들이 변수(variable)이 된다.


원래 프레임의 열이 6개고 모든 열이 numeric data라면 

그리고 행이 135개라면 이것을 default melt으로 변경하면

135 * 6 = 918개의 데이터로 길어 지게 된다.



만약 특정 열에대해서 다른 값들을 정리하고 싶다면, vars = c("x","y") 의 옵션을 사용 한다.

즉, X,Y를 ID 변수로 설정하고 이것의 값들은 변경하지 않는다. 


$원래의 행의 수 \times ( 총 열의수 - ID변수의 수)  = 새로 생성될 행의 수$


> aql <- melt(airquality, id.vars = c("month","day"))


실행결과

> str(airquality)
'data.frame':	153 obs. of  6 variables:
 $ ozone  : int  41 36 12 18 NA 28 23 19 8 NA ...
 $ solar.r: int  190 118 149 313 NA NA 299 99 19 194 ...
 $ wind   : num  7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ...
 $ temp   : int  67 72 74 62 56 66 65 59 61 69 ...
 $ month  : int  5 5 5 5 5 5 5 5 5 5 ...
 $ day    : int  1 2 3 4 5 6 7 8 9 10 ...
> aql <- melt(airquality, id.vars = c("month","day"))
> str(aql)
'data.frame':	612 obs. of  4 variables:
 $ month   : int  5 5 5 5 5 5 5 5 5 5 ...
 $ day     : int  1 2 3 4 5 6 7 8 9 10 ...
 $ variable: Factor w/ 4 levels "ozone","solar.r",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ value   : num  41 36 12 18 NA 28 23 19 8 NA ...


이름변경 방법

aql <- melt(airquality, id.vars = c("month", "day"),
  variable.name = "climate_variable", 
  value.name = "climate_value")
head(aql)




#   month day climate_variable climate_value

# 1     5   1            ozone            41

# 2     5   2            ozone            36

# 3     5   3            ozone            12

# 4     5   4            ozone            18

# 5     5   5            ozone            NA

# 6     5   6            ozone            28



cast 함수의 이해


인간이 이해하기에는 wide-format data가 가장 좋다.

따라서 스크래치 단계에서 많이 사용된다.


cast는 데이터 타입별로 지원한다. 하지만 여기서는 data.frame에 대해서 주로 다루겠다.


aql <- melt(airquality, id.vars = c("month", "day"))

aqw <- dcast(aql, month + day ~ variable)

head(aqw)


#   month day ozone solar.r wind temp

# 1     5   1    41     190  7.4   67

# 2     5   2    36     118  8.0   72

# 3     5   3    12     149 12.6   74

# 4     5   4    18     313 11.5   62

# 5     5   5    NA      NA 14.3   56

# 6     5   6    28      NA 14.9   66


head(airquality) # original data


#   ozone solar.r wind temp month day

# 1    41     190  7.4   67     5   1

# 2    36     118  8.0   72     5   2

# 3    12     149 12.6   74     5   3

# 4    18     313 11.5   62     5   4

# 5    NA      NA 14.3   56     5   5

# 6    28      NA 14.9   66     5   6



동작 방식을 그림으로 정리하면 아래와 같다.




추가적인 정보는 아래의 명령어로 알 수 있다.

[Highlight.js] Tistory 소스코드 하이라이트


Highlight.js 소개


홈페이지: click

라이브 데모: click



설치방법


1) 홈페이지가서 다운로드 받음

2) 파일업로드

highlight.pack.js

styles/"원하는 하이라이트 파일"

ex: monokai_sublime.css

아래의 데모에서 각각의 스타일의 표시 방식을 볼 수 있다.

라이브 데모: click


3) CSS/HTML 수정

<head> ... </head>

저 사이에 아래의 코드를 삽입 해야한다.

<link rel="stylesheet" href="//cdn.jsdelivr.net/highlight.js/8.7/styles/monokai_sublime.min.css">
<script src="//cdn.jsdelivr.net/highlight.js/8.7/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

<script src="//cdn.jsdelivr.net/highlight.js/8.7/highlight.min.js"></script>

위코드에서 빨간색 부분이 스타일을 나타낸다.



사용방법


Html 편집 모드에서 아래의 코드를 앞뒤로 삽입 하면 된다.

<pre><code class="html">...</code></pre>


참고사이트



http://webdir.tistory.com/439



'일상 > 정보 수집' 카테고리의 다른 글

markdown 사용법  (0) 2016.03.25
[SyntaxHighlighter] Tistory 소스코드 하이라이트  (0) 2015.06.29
원격  (0) 2013.11.20
소스코드 하이라이트  (0) 2013.06.04
원격 데스크탑 설정 가이드 라인  (0) 2013.01.11

Feature (Attribute) Selection


어떤 feature를 뽑아야 좋은 model을 생성 할 수 있을까?

해당 질문은 매우 어려운 문제이다.



해당 분야에 대한 깊은 지식이 없는 사람은 feature를 선택하기가 쉽지 않다.

이것을 자동으로 결정해 준다면 매우 좋을것이다. 이러한것을 목표로 하는 것이 feature selection 이다.



Feature selection이란 결국 가장 관련있는 feature들의 subset을 골라 내는 작업을 말한다.

이것은 Dimensionality reduction과 유사해 보일 수 있지만 그렇지 않다.



Feature Selection을 통해서 해결 되는 문제점들


관련 없는 데이터 제거

중복성 제거

정확도에 높은 모델에 기여되는 feature들이 무엇인지를 알아냄

심지어 어떤 feature들은 참여 됨으로써 정확도를 떨어뜨림 이런것들을 찾아냄


feature들을 최대한 적게 써서 model을 만드는 것이 좋다.

왜냐하면, 성능도 좋고 복잡하지 않으므로 이해하기도 쉽다. 그리고 설명도 쉽게 된다.



Feature Selection Algorithms

일반적으로 feature 선택 알고리즘은 세가지로 구분 된다.


filter method

wrapper method

embedded method


- Filter Method

각각의 feature들에 통계적인 점수를 부여하는 방법이다.

그리고 각각의 feature들은 score에 의해서 rank매겨 진다.


Example of some filter methods include the Chi squared test, information gain and correlation coefficient scores.



- Wrapper Method

search problem으로써 feature들의 집합을 선택한다.

An example if a wrapper method is the recursive feature elimination algorithm.




- Embedded Method


어떻 feature가 가장 크게 기여하는지를 찾아내는 방법이다.

Examples of regularization algorithms are the LASSO, Elastic Net and Ridge Regression.




Feature Selection Tutorials and Recipes

We have seen a number of examples of features selection before on this blog.


Weka: For a tutorial showing how to perform feature selection using Weka see “Feature Selection to Improve Accuracy and Decrease Training Time“.

Scikit-Learn: For a recipe of Recursive Feature Elimination in Python using scikit-learn, see “Feature Selection in Python with Scikit-Learn“.

R: For a recipe of Recursive Feature Elimination using the Caret R package, see Feature Selection with the Caret R Package









Single Attribute Evaluator: infoGainAttributeEval

Evaluate attribute based on information 


'AI > Theory' 카테고리의 다른 글

Fast Convolution  (3) 2020.02.13
Loss functions  (0) 2018.08.09
Ensemble Method  (0) 2015.09.15
Active Learning  (0) 2015.08.19
기계학습을 구현하기 위해서 어떤 언어가 좋은가?  (0) 2015.07.11

Ensemble Method


Random Forests


decision tree classifier들을 위해서 디자인 된것으로써 다중 decision tree를 이용 한다.

각각의 트리들은 독립적인 랜덤 셋 백터를 생성하게 된다.

'AI > Theory' 카테고리의 다른 글

Loss functions  (0) 2018.08.09
Feature (Attribute) Selection  (0) 2015.09.15
Active Learning  (0) 2015.08.19
기계학습을 구현하기 위해서 어떤 언어가 좋은가?  (0) 2015.07.11
순차데이터 분석을 위한 Hidden Markov Model (HMM)  (0) 2015.06.08

Certificate & Comment

강의가 수료되고 약 2주가 지나면 certificate가 발급이 된다.


강의 자체보다는 숙제와 퀴즈를 통해서 학습되는 양이 더 많은것 같다.


Coursera의 많은 강의들이 OnDemand 형태로 제공 되어지므로 

certificate를 얻을 수 있는 기회가 줄어들고 있지만,

돈을 내지 않는다면 완강을 하기란 힘들어 보인다.


총점수가 70/100 일경우 certificate가 발급되며

90/100일 경우 with distinction으로 특별한 문구가 삽입된다.




Battery Historian 2.0 사용 방법


Google I/O 2015에서 battery historian 2.0으로 개선된 것이 공개 되었다.

기존의 1.0은 python만 설치하면 동작 했었지만 2.0은 설치방법과 사용방법이 그것보다는 약간 더 복잡한 상황이다.

이것에 대해서 다루도록 한다.


GiHub 주소: Battery-Historian



Battery Historian 2.0에서의  사용방법



<요구사항>

android 5.0 이상

android API 21+

2.0에 오면서 go와 javascript를 이용해서 다시 작성 되었다.


<Go Download>

download (다른 운영체제)

Linux: go1.5.linux-amd64.tar.gz


tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz

export PATH=$PATH:/usr/local/go/bin

또는 profile에 추가.



<Workspace 생성> - 필수적으로 해야함 -

#디렉터리 생성

$HOME은 나의경우 /root 이다.

mkdir $HOME/go-worksapce/goCode

#GOPATH 설정

export GOPATH=$HOME/work

#GOBIN 설정

export GOBIN=$GOPATH/bin



< install Go support for Protocol Buffers by running go get>

# Grab the code from the repository and install the proto package.

$ go get -u github.com/golang/protobuf/proto

$ go get -u github.com/golang/protobuf/protoc-gen-go

#이것을 설치하면, $GOBIN으로 설정한 곳에 설치가 된다. 따라서 이것을 하기전에 $GOBIN의 PATH 설정을 필수 이다.



실행 결과로 bin과 pkg에 각각의 파일들이 생성 된다. 핵심은 해당 디렉터리는 $GOPATH로 설정한 곳이라는 것이다.




<download the battery historian 2.0 code>

$ go get -u github.com/google/battery-historian

$ cd $GOPATH/src/github.com/google/battery-historian




<Compile Javascript files using the Closure compiler>

$ bash setup.sh





<Run Historian on your machine (make sure PATH contains GOBIN)

$ go run cmd/battery-historian/battery-historian.go [--port <default:9999>]

주의: $GOPATH/src/github.com/google/battery-historian 항상 이곳에서 실행 해야 한다.

#그다음 웹브라우저로 실행 한다.

http://localhost:9999





<프로파일링 로그 생성>

# bugreport 파일은 dumpsys, dumpstate, locat 파일을 모두 포함 한다.

$ adb bugreport > bugreport.txt

# 로그를 초기화 한다.

$ adb shell dumpsys batterystats --reset


#full wake lock을 활성화 시키고 싶으면 아래의 옵션을 활성화 시킨다.

$ adb shell dumpsys batterystats --enable full-wake-history






이전 version에서의 사용 방법 (Summary)


> adb kill-server

> adb devices

> adb shell dumpsys batterystats --reset


<disconnect and play with app>...<reconnect> (연결 되면 배터리 충전 되므로 이러한 방법을 사용 함).


>adb devices

>adb shell dumpsys batterystats > batterystats.txt

> python historian.py batterystats.txt > batterystats.html




Android wear app


환경설정


emulator


adb -d forward tcp:5601 tcp:5601


real device


Host: disconnected

Target: connected


adb forward tcp:4444 localabstract:/adb-hub

adb connect localhost:4444


Host: connected

Target: connected




Create a Project


mobile app과

wear app이 동시에 설치 되게 된다.


WatchViewStub을 이용해서 "Hello World"가 화면에 표시되어 진다.

WatchViewStub은 one of the UI widget으로 wearable support library로써 제공 된다.


appropriate module을 build.gradle 안에다가 넣어서 처리 해야 한다.


Notification

android v4 support library가 wearable을 위해서 화장된 것이다.

API level 20이라고 하면 처리가 가능하다.



Wearable Data Layer

watch와 smartphone이 서로 동기화 되어지기 위해서 Data Layer가 사용 된다.

이것을 위해서는 the latest version of Google Play services가 중요 하다


Wearable UI support library

비공식적인 UI 라이브러리를 말한다.



여기서는 단순히 Layout을 디자인 하는 정도 수준이다.



Sending and Syncing Data


이러한 data layer를 이용해서 Google Play service단에서 communication channel을 이용해서 상호 동기화를 수행 한다.


Data Items

어떠한 스토리지로써 hanheld와 wearable 사이에서 데이터를 동기화 시켜주기 위한 것이다.


Messages

MessageAPI로써 이것은 RPC를 위한 좋은 도구이다.

스마트폰의 media player와 같은 것들을 pause, resume 하는 등의 작업으로써 이용할 수 있다.


또한 단방향 통신 매커니즘으로도 좋다.

실행 결과는 둘사이의 연결 상태에 의존 한다.



Asset

image와 같은 데이터 전송을 위한 것이며,

이것을 이요할 경우 자동적으로 bluetooth power 소모를 줄여주며,

large asset들을 자동으로 cahcing 하여 re-transmission을 줄여 준다.



WearableListenerService (for services)

이것을 상속받아서 확장 함으로써 data layer에서의 중요한 이벤트들을 알아낼수 있다.

필요할때 binding 하고 필요 없을때 unbinding을 하면 된다.



DataListener (for foreground activities)

사용자가 해당 앱을 foregorund에만 사용 중일 때만 이벤트를 읽어 오는 기능을 한다



Channel

채널을 이용해서 큰 데이터 아이템을 전송 할 ㅅ 있다.

음악 파일, 영화와 같은 것이다.

이것을 handheld to wearable로 전송하게 된다.



아래와 같이 직접 싱크를 맞추던가 Cloud Node를 이용해서 싱크를 맞추게 된다.

결국 핵심은 여러 장치들이 모두 동기화 되어진다는 것이다.







































'Computer Science > Android Application' 카테고리의 다른 글

Gradle  (0) 2016.06.03
Android Plot Libraries  (0) 2016.01.22
Android Studio 자동 import 기능  (0) 2015.07.15
Android Wear 개발환경 구축  (0) 2015.07.15
Notifications API Guide  (0) 2015.06.29

Active Learning



semi-supervised machine learning 


이것은 interactively query를 이용해서 desired output을 새로운 데이터 포인트에서 획득 하는 방식을 의미한다.



사용하는 상황은


unlabeled data가 매우 많아서 수작업으로 그것을 라벨링 하기 어려울 때

active learning 알고리즘을 이용해서 지도자에게 질의 하여 라벨링을 할 수 있다.


즉 uncertainty sampling 데이터가 많은 상황에서 사용하는 방법이다.



좋은점은

학습에 필요한 라벨된 데이터의 양을 줄일 수 있다.

이유는 학습자가 능도적으로 데이터를 선택하기 때문이다.



'AI > Theory' 카테고리의 다른 글

Feature (Attribute) Selection  (0) 2015.09.15
Ensemble Method  (0) 2015.09.15
기계학습을 구현하기 위해서 어떤 언어가 좋은가?  (0) 2015.07.11
순차데이터 분석을 위한 Hidden Markov Model (HMM)  (0) 2015.06.08
Anomaly Detection  (0) 2015.06.07

Google Alphabet




Alphabet = umbrella company


세르게이, 레리페이지는 이 회사의 CEO가 되었다.


Alphabet will operate as the parent company for a number of smaller companies, 


Other departments spinning off into their own sub-companies including 

research focused Life Sciences (Google contact lenses), 

the Google X lab (driverless cars, Google Glass, drone delivery), 

Calico (increasing longevity), and 

the company's robotics division. 


Google Ventures and Google Capital will also become independent Alphabet companies.



Nets -> Tony Fadell

Sidewalk Labs -> Dan Doctoroff

Calico -> Arthur Levinson

YouTube -> Susan Wojcicki

Google X -> Brin


Google의 CEO는 세번째로 sundar pichai가 그 자리에 올랐다.

Pichai의 나이는 43이다. 인도에서 태어 났다.

IIT를 졸업하고 대학원으로 Stanford Univ.에서 공부 했다. 거기서 석사학위를 받았다.


2004년에 처음 구글에 입사했고, 2008년에 Chrome을 출시하면서 이미 인터넷 브라우저 시장은 끝났다고 생각했지만, 그 판도를 뒤짚어 버렸다. IE와 Firefox가 자리잡고 있던 브라우저 시장을 석권 했다.


크롬은 그렇다고 가장 많이 쓰는 브라우저는 아니다.

하지만 크롬은 하나의 OS로써 크롬북과 같은 형태로 많은 학교에서 사용 하고 있다.


2013년에 크롬 사업부와 android 사업부를 통합하면서 앤디루빈이 회사를 떠나고

Pichai는 Senior vice president의 자리에 올랐다.


그리고 올해 그는 마침네 구글의 세번쨰 CEO 자리에 올랐다.

외국이며 젊은 나이에 그 자리에 올랐다는것으로 이것은 매우 이례적이며 인도인들에게 큰 자긍심이 될수 있다.

오랜 세월전 그는 단순이 수줍고 예의바른 학생일 뿐이었다.


그의 가능성을 기대해보자.




[Week 3] Logistic Regression Regularization


Classification




'MOOC > Machine Learning (python)' 카테고리의 다른 글

Week 01 Linear Algebra Review  (0) 2015.12.17
Week 01: Parameter Learning  (0) 2015.12.06
Week 01: Model And Cost Function  (0) 2015.12.05
Week 08: Dimensionality Reduction  (0) 2015.11.18
Week 01: Bonus-Course Wiki Lecture Notes  (0) 2015.07.06


R 자주 사용하는 팁 및 한글 주석 깨짐 해결


1. 자주 사용하는 RStudio 단축키와 명령

    –  Console 화면에서 Ctrl_l (Ctrl_소문자L) : 화면을 깨끗하게 지웁니다.

    –  rm(list=ls(all=TRUE)) : 작업 영역을 깨끗이 청소 합니다.

    –  Ctrl_+ : 화면에 표시되는 문자의 크기를 크게 합니다.

    –  Ctrl_- : 화면에 표시되는 문자의 크기를 작게 합니다.

    –  "Tools -> Global Options…" 메뉴를 선택한 후 "General" 메뉴에서

        "Default working directory (when not in a project):" : RStudio에서 사용할 작업용 폴더를 지정 합니다.

        "Default text encoding: " : ~.R 파일의 인코딩을 지정 합니다.  저는 "UTF-8"을 지정하여 사용하고 있습니다.

 

    –  RScript 편집 화면에서 Ctrl_Enter : 커서가 있는 라인을 Console 화면에서 실행 합니다.

    –  ? ~ : help(~)와 동일한 기능으로 함수, 데이터셋 등에 대한 도움말을 표시 합니다.

        사용 예 1)  ? iris                 : iris 데이터셋에 대한 도움말

        사용 예 2)  ? summary         : summary 함수에 대한 도움말

    –  ??  ~ : help.search("~")와 동일한 기능으로 함수 등의 이름을 명확히 알지 못할 경우, 검색을 할 때 사용 합니다.

    –  help(package = "~"), library(help = "~") : 패키지(라이브러리) 도움말로 제공하는 함수 목록을 확인할 수 있습니다.

        사용 예)  library(help = "stats") : stats 패키지의 도움말 화면을 표시 합니다.

    –  methods(~) : ~이 대표하는 함수들의 목록을 표시 합니다.

        사용 예)  methods(plot) : 다양한 데이터 타입을 사용하여 챠트를 그려주는 함수명을 확인할 수 있습니다.

                     시계열 데이터를 그려주는 plot.ts(~) 대신에 

                      대표 함수명인 plot(~)를 사용하면 내부적으로 plot.ts(~)가 실행이 됩니다.

    –  args(~) : ~ 함수의 인자 정보를 조회 합니다.

        사용 예) args(lm) : 회귀분석에서 사용하는 lm 함수의 인자 정보를 확인 합니다.

    –  attributes(~) : 데이터셋의 인자 정보를 조회 합니다.

    –  TAB : 자동 완성 기능으로 console 창에서 몇글자를 입력한 후 TAB키를 누르면

                입력한 글자로 시작되는 함수 목록을 보여 주어 자동 완성 기능을 사용할 수 있도록 합니다.

 

 

2.  문자셋 관련 사항

  –  UTF-8 문자셋으로 저장된 ~.R 파일을 사용할 경우

      –  "Tools -> Global Options…" 메뉴를 선택한 후 "General" 메뉴에서

        "Default text encoding: " : ~.R 파일의 인코딩을 지정 합니다.  "UTF-8"을 지정하세요.

 


  –  UTF-8 문자셋으로 저장된 데이터 (csv 파일 등)을 읽을 경우

     read.table(생략, encoding = "UTF-8")                            #— 문자셋 정보를 명시 합니다.

 

  –  R의 인코딩 정보 확인

      localeToCharset()

      Sys.getlocale()

  –  오류 메시지를 영문으로 보기 (영문 오류 메시지가 명확하고 구글 등의 검색을 통해서 확인하기가 편리 합니다.)

      Sys.setlocale("LC_ALL", "English_United States.1252")  #— 영문 문자셋을 지정 합니다.

      Sys.setlocale()                                                          #— 원래 디폴트로 설정된 문자셋으로 복구 됩니다.

  –   데이터의 인코딩 정보 확인

      Encoding(~)

  –  문자열의 인코딩 변환

      iconv(~, "CP949", "UTF-8) #— "CP949"로 인코딩된 ~라는 데이터에 저장된 문자열을 "UTF-8"로 인코딩된 문자열로 변환

 

  –  "Notepad++" 텍스트 편집기 : 오픈소스로 제공되는 편집기로 사용이 편리 합니다.

      –   다운로드 사이트 : http://notepad-plus-plus.org/

      –   파일의 문자셋 변경 방법

           편집기의 우측 하단 영역에 문자셋이 표시 됩니다.  (ANSI, ANSI as UTF-8 등)

              윈도우의 디폴드 문자셋인 CP949를 사용할 경우 ANSI로 표시됨

              BOM이 없는 UTF-8 문자셋을 사용할 경우 ANSI as UTF-8로 표시됨

           "인코딩" 메뉴에서

              "ANSI로 변환" 메뉴 선택                    : UTF-8 문자셋으로 저장된 파일을 CP949 문자셋으로 변환 

              "UTF-8 (BOM 없음)로 변환" 메뉴 선택 : CP949 문자셋으로 저장된 파일을 UTF-8 문자셋으로 변환

[4 Week] Str & Simulation & R Profiler



str: Compactly display the internal structure of an R object


A diagnostic function and an alternative to 'summary'

It is especially well suited to compactly display the (abbreviated) contents of (possibly nested) lists.

Roughly one line per basic object




Simulation - Generating Random Numbers


Functions for probability distributions in R


rnorm: generate random Normal variates with a given mean and standard deviation

dnorm: evaluate the Normal probability density (with a given mean/SD) at a point (or vector of

points)

pnorm: evaluate the cumulative distribution function for a Normal distribution

rpois: generate random Poisson variates with a given rate



Probability distribution functions usually have four functions associated with them. The functions are

prefixed with a

  • d for density
  • r for random number generation
  • p for cumulative distribution
  • q for quantile function
  • n the number of random variable
  • lambda: vector of (non-negative) means.


dnorm(x, mean = 0, sd = 1, log = FALSE) pnorm(q, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE) # cumulative distribution function qnorm(p, mean = 0, sd = 1, lower.tail = TRUE, log.p = FALSE) # p^-1 이다. rnorm(n, mean = 0, sd = 1) dpois(x, lambda, log = FALSE) ppois(q, lambda, lower.tail = TRUE, log.p = FALSE) qpois(p, lambda, lower.tail = TRUE, log.p = FALSE) rpois(n, lambda) # lambda는 평균이다. 대충 평균 저정도 값이 나오는 포아송 분포를 생성해 준다.




seed 설정을 통해서 같은 값을 생성 할 수 있다.




<generating Poisson data>


the Poisson distribution, the mean is going to be equal to the rate (rpois에서의 두번째 인자값이 rate이다).

아래것을 계산해보면 1짜리는 0.8이고 2짜리는 2.2 이다. 정확히 rate과 일치하는것은 아니지만, 최대한 비슷한 분포를 만들어 주려고 한다.


So you can see that roughly in each of these three cases, the mean is roughly equal to the rate that I specified (1,2,20).






Simulation - Simulating a Linear Model



Suppose we want to simulate from the following linear model

$$y=\beta _{ 0 }+\beta _{ 1 }+\epsilon $$


where $\epsilon$ ~ $N(0,2^2)$. Assume $x$ ~ $N(0,1^2)$, $\beta_0=0.5$ and $\beta_1 = 2$




x를 만약 binary로 설정 한다면




Suppose we want to simulate from a Poisson model where 

$$ Y  = Poisson(\mu) $$

$$ \log (\mu) = \beta_0+\beta_{1}x$$

and $\beta_0 = 0.5$ and $\beta_1 = 0.3$. We need to use the rpois function for this








Simulation - Random Sampling



The sample function draws randomly from a specified set of (scalar) objects allowing you to sample from arbitrary distributions


Usage

sample(x, size, replace = FALSE, prob = NULL)

sample.int(n, size = n, replace = FALSE, prob = NULL)


Arguments

x

Either a vector of one or more elements from which to choose, or a positive integer. See ‘Details.’

n

a positive number, the number of items to choose from. See ‘Details.’

size

a non-negative integer giving the number of items to choose.

replace

Should sampling be with replacement?

prob

A vector of probability weights for obtaining the elements of the vector being sampled.





요약

확류분포를 r* 종류의 함수로 나타낼 수 있다.

Normal, Poisson, Binomial, Exponential, Gamma, etc를 표준 분포로서 생성 할 수 있다.

Sample 함수는 arbitrary vector를 생성하는 수단으로 사용 할 수 있다.

seed를 통해서 같은 number를 재생성 할 수 있다.




R Pro filer








Assignment 03


병원에서 환자의 케어를 제대로 했는지 안했는지에 대한 데이터 셋이다. 총 4000개의 U.S. 병원의 정보가 담겨져 있다.


세개의 파일은 다음과 같다.

outcome-of-care-measures.csv: 30 day mortality and readmission rates for heart attacks, heart failure, and pneumonia for over 4,000 hospitals.

hospital-data.csv: 각각의 병원에 대한 정보를 담고 있다.

Hospital Revised Flatfiles.pdf: 각각의 파일에 대한 설명.




1) Plot the 30-day mortality rates for heart attack

outcome-of-care-measures.csv를 보면 많은 column들이 존재 한다.

얼마나 많은 column들이 존재하는지는 ncol을 통해서 알 수 있다.

얼마나 많은 row들이 있는지는 nrow를 통해서 알 수 있다.

각각의 column들의 이름을 알기 위해서는 names(outcome)을 실행 한다.





2) Finding the best hospital in a state

함수 이름은 best

두개의 arguments를 받음: 미국 주의 약어와 outcome name

리턴값은 가장 30일 시한부 인생이 적은것을 설정한 주에서 찾아낸다. 그 해당 병원의 이름이 있는 문자열 백터를 반환 한다.


best <- function(state, outcome) {

## Read outcome data

## Check that state and outcome are valid

## Return hospital name in that state with lowest 30-day death

## rate

}


먼저 입력된 주가 올바른지 부터 확인 한다.




3) Ranking hospitals by outcome in a state


rankospital은 세개의 아규먼트를 가져 온다. 

첫번째: 주 이름

두번째: outcome

세번째: ranking of a hosptial in that state for that outcome (num).


예)

> rankhospital("MD", "heart failure", 5)

heart failure에 의해서 30일 사망이 5번째로 작은 병원의 이름을 포함하는 백터를 반환 한다.

Note that: 마지막 세번째 숫자 인자는 "best"와 "worst"값을 가져올 수 있다.

만약 마지막 숫자가 포함한 병원의 수보다 큰 값이면 "NA"를 반환 한다.





4) Ranking hospitals in all states

rankall이란 함수를 만든다. 인자는 두개이다.

아웃컴과 병원 랭킹







'MOOC > R Programming' 카테고리의 다른 글

Certificate & Comment  (0) 2015.08.26
[3 Week] Loop Functions & Debugging Tools  (1) 2015.07.24
[2 Week] Programming with R  (0) 2015.07.16
[1 Week] Getting stated and R Nuts and Bolts  (0) 2015.07.08

복합관계대명사 & 복합관계부사


  • 복합관계대명사 + 불완전한 문장

  • 복합관계부사 + 완전한 문장

  • 복합관계대명사 뜻 : ..든지

  • 복합관계부사의 뜻 : ..라도

복합관계대명사 종류 5가지

whatever / whichever / who(m)ever / whosever (소유격)

회화에서는 whomever 대신, whoever 많이 쓰임.

※ 관계대명사도 목적격 whom 대신, who 많이 씀.

명사절, 형용사절로 사용 될 수 있다.

예문

부사절 역할

  • Whoever parked in the street, please move your vehicle. [부사절 역할]
  • Wherever I eat, it seems price have gone up. [부사절 역할]

명사절 역할

  • Whatever Mr. Moor suggests always helps me a lot. [명사절 역할]
  • Sandra won’t forgive whoever spoiled her garden. [명사절 역할]
  • The dessert is whichever you’d like [명사절 역할]

복합관계부사 종류 (3가지)

whenever, wherever, however, wherever 철자 주의 (e 빠짐), however 는 특이한 복합관계부사 (아래에서 설명)

부사절로만 사용 된다.

특이한 복합관계부사 : however

  • 용법 (어순 주의) : however + 형용사/부사+ 주어+ 동사

    • 원래 how는 (how+형용사), (how+부사)의 뜻으로 자주 쓰였으니 그와 비슷하다고 생각하면 된다.
  • 뜻 : 비록(아무리) -라도, 비록 ..인데도

  • 특징 : 형용사 or 부사와 대개 한 뭉텅이로 쓰임!

  • 물론, however 는 연결사로 그러나 도 있습니다.

예문

  • However rich you are, you can't buy happiness with money.

명사절 사용

Whenever it's convenient for you is okay with me.

위와 같은 형태는 Whenever가 이끄는 절이 주어로 사용되어 마치 명사절로 쓰였다.
원래의 문장은 아래와 같다.
It's okay with me whenever it's convenient for you.

이것은 구지 whenever를 쓰지 않아도 되지만 써서 수사법(rhetoric)을 표현하기 위해서
사용한 것이다.
한마디로 있어 보이기 위해서 말에 기교를 부린 것이라고 보면 된다.

no matter 용법

  • No matter how, what, who, where
    아무리, 무엇이, 누가, 어디서 ~ 하더라도

예문

  • No matter how rich you are, you can’t buy happiness with money.
  • I’ll follow you no matter where you go.
  • No matter what he says, don’t trust him.


'영어 > 영문법' 카테고리의 다른 글

조동사 정리  (0) 2016.04.07
Leverage 명사 동사  (0) 2016.02.21
전치사 + 관계대명사  (0) 2015.04.28
efficiently and effectively  (0) 2015.03.02
As well as 구문  (0) 2015.02.23

The history of Facebook.


Facebook은 10년이상 변화해 왔던 기업이다. 그것은 2014년 2월 4일 Mark Zuckerberg (오른쪽 사진) Dustin Moskovitz 그리고 3명의 하버드 기숙사 classmate들에 의해서 탄생된 것이다. 시작은 어색했지만, 그것은 현재 14억 사용자를 보유하고 있는 지상 최대의 Social Network Service 이다.


이러한 Facebook의 변천사를 함께 가보자.





In 2004, Facebook launches


하버드 학생들간의 연결 방법으로써 처음으로 "thefacebook"이라는 이름으로 그것은 처음 세상에 알려지게 된다.

social networking 사이트는 이것을 시작으로 컴림비아, 스탠포드, 예일 대학으로 각각 매달 퍼져 나갔다. 마침내12월이 되서 "thefacebook"은 가입자 100만이 넘어가는 상황에 이르렀다.





In 2005, Students spread the word


해당 사이트는 아이비리그를 넘어서 800개 이상의 대학을 포함하게 된다. 이때가 2005년 5월이다. 그리고 공식적인 이름을 "Thefacebook"에서 그냥 "Facebook"으로 8월에 변경하게 된다. 그리고 9월에 일반 고등학생들도 Facebook에 가입 할 수 있도록 허용 했다.





In 2006, Meet the News Feed


2006년까지 만 13세 이상이면 누구나 Facebook에 가입이 가능하도록 했다. 같은 해에 Facebook은 the News Feed를 소개 했다. 이것은 자신의 소셜 네트웍안에서의 새로운 업데이트나 사진 같은 것들을 하이라이트해서 보여주는 기능이다.

하지만, 이것을 기점으로 Facebook 유저들은 많은 요청을 하기 시작했다. 다시 예전으로 돌아가고자 희망하는 사용자가 적지 않았다.

그들은 대부분 이렇게 말했다 "I don't need to know everything about EVERYONE".





In 2007, Another new design


2007년 사월 Facebook은 그것의 디자인을 대대적으로 변경 했다. 

왼쪽 바에다가는 포토 노트 그룹 이벤트 같은것들을 위치 시켰고 친구, 네트워크 등은 최상위 inbox 안으로 이동 시켰다.

오월에 Facebook은 플랫폼을 launch 했다. 이것은 개발자들에게 third-party app을 개발할 수 있도록 한다. 이러한 앱들은 추후에 사용자들의 데이터를 과도하게 남용함으로써 또다른 문제를 야기 시키게 된다. 200년 말 Facebook은 광고를 출시하게 되고 이것은 몇몇 사용자들 다시 MySpace 같은 플랫폼으로 돌아가게 하는 결과를 낳는다.





In 2008, New profile pages





In 2009, The 'Like' button






In 2010, Growing privacy concerns

In 2010, Facebook adds 'check-ins'

Foursqaure와 같은 위치기반 체크인 서비스를 출시 한다.

In 2011, Photos, Photos everywhere

In 2011, Facebook Messenger

In 2012, Hello, Timeline

In 2013, Going mobile

2013년 후반기에 12억 사용자중 9억명의 사용자가 Facebook을 smartphone 또는 Tablet으로 접속하게 된다.

Facebook은 처음 web-first product 였지만, 이제는 이러한 사용 방식을 고려해볼 때 Mobile 기반의 기능이 강화되어야 함을 알 수 있다.

In 2013, Hashtags

In 2015, Embedded Facebook videos



아래의 그림은 2013년에 Facebook에서 나타낸 세계의 맵이다. 보면 China와 아프리카를 제외하고 대부분이 연결 되어 있음을 알 수 있다.

하지만 소셜 네트웍은 이미 포화 상태이며 변덕이 심한 젊은층이 어떻게 변화할지는 아무도 예상 할 수 없다.

이러한 요소를 빛추워 봤을 때 그렇게 낙관적이지 많은 않다.







[3 Week] Loop Functions & Debugging Tools


Loop Functions


lapply: Loop over a list and evaluate a function on each element

sapply: Same as lapply but try to simplify the result

apply: Apply a function over the margins of an array

tapply: Apply a function over subsets of a vector

mapply: Multivariate version of lapply



rnorm function (The normal Distribution)

Density, distribution function, quantile function and random generation for the normal distribution. 



Loop Functions - lapply 



lapply takes three arguments: 

(1) a list x; 

(2) a function (or the name of a function) FUN; 

(3) other arguments via its ... argument.

If x is not a list, it will be coerced to a list using as.list.



lapply always returns a list, regardless of the class of the input.


> x <- list(a=1:5, b = rnorm(10))
> x
$a
[1] 1 2 3 4 5

$b
 [1]  0.34766773  1.88039654 -0.29986269  1.88896873  0.07806339 -1.63535799
 [7]  1.12373391  0.66304757  0.64747795 -0.38855335

> lapply(x,mean)
$a
[1] 3

$b
[1] 0.4305582



> x <- list(a=1:4, b=rnorm(10), c=rnorm(20,1), d=rnorm(100,5))
> lapply(x,mean)
$a
[1] 2.5

$b
[1] 0.0315751

$c
[1] 1.193494

$d
[1] 4.999784



> x <- 1:4
> lappy(x,runif)
Error: could not find function "lappy"
> lapply(x, runif)
[[1]]
[1] 0.1516973

[[2]]
[1] 0.5303134 0.7188454

[[3]]
[1] 0.61570965 0.03625812 0.79371658

[[4]]
[1] 0.06210734 0.59349463 0.83711023 0.38416463

"runif" function은 random 변수를 생성하기 위한 함수 이다.



I want to generate a uniform between zero and ten.

for that, we are passing these arguments (min, max) through the dot dot dot argument.

So here, we are calling lapply using several arguments.



> x<-1:4
> lapply(x,runif,min=0,max=10)
[[1]]
[1] 1.384929

[[2]]
[1] 4.474732 3.952107

[[3]]
[1] 2.406658 5.489504 7.572002

[[4]]
[1] 5.534824 0.325385 4.289476 4.976774



An anonymous function for extracting the first column of each matrix.


> x<- list(a=matrix(1:4,2,2), b=matrix(1:6,3,2))
> x
$a
     [,1] [,2]
[1,]    1    3
[2,]    2    4

$b
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6

> lapply(x, function(elt) elt[,1])
$a
[1] 1 2

$b
[1] 1 2 3



Loop Functions - apply


apply is used to a evaluate a function (often an anonymous one) over the margins of an array.

It is most often used to apply a function to the rows or columns of a matrix.

It can be used with general arrays, e.g. taking the average of an array of matrices.

It is not really faster than writing a loop, but it works in one line !


> str(apply)

function (X, MARGIN, FUN, ...)

  • X is an array
  • MARGIN is an integer vector indicating which margins should be “retained”.
  • FUN is a function to be applied
  • ... is for other arguments to be passed to FUN





For sums and means of matrix dimensions, we have some shorcuts.


  • rowSums = apply(x, 1, sum)
  • rowMeans = apply(x, 1, mean)
  • colSums = apply(x, 2, sum)
  • colMeans = apply(x, 2, mean)

This shorcut functions are much faster, but you won't notice unless you're using a large matrix.



Quantiles of the rows of a matrix.







Loop Functions - mapply







Loop Functions - tapply







Loop Functions - split



Split takes a vector or other objects and splits it into groups determined by a factor or list of factors.



< Splitting a Data Frame >



lapply를 이용해서 각각을 처리한 것이다.

there are five columns.




instead of using lapply, we can use sapply to simplify the result.

What we will do is put all these numbers into a matrix.


where the three rows and in this case 5 columns.

For each of the tree variables, in a much more compact format, it's a matrix, instead of a list.

Of course we still got NA's for a lot of them, because the missing values in the original data.


So on thing I knew is I was going to pass the na.rm argument to call.


here you can see the monthly means




< Splitting on More than One Level >




Debugging


상태 정보의 종류

  • message: A generic notification/diagnostic message produced by the message function; execution of the function continues
  • warning: An indication that something is wrong but not necessarily fatal; execution of the function continues; generated by the warning function.
  • error: An indication that a fatal problem has occurred; execution stops; produced by the stop function
  • condition: A generic concept for indicating that something unexpected can occur; programmers can create their own conditions


디버깅에 활용할 수 있는 도구들

  • traceback: prints out the function call stack after an error occurs; does nothing if there's no error.



  • debug: flags a function for "debug" mode which allows you to step through execution of a function one line at a time.
  • browser: suspends the execution of a function wherever it is called and puts the function in debug mode.




  • trace: allows you to insert debugging code into a function a specific places.

  • recover: allows you to modify the error behavior so that you can browse the function call stack.







Programming Assignment 2


특이한점은 peer Assessments를 이용해서 과제를 제출한 사람들끼리 서로 서로 평가하는 방식을 택한다.

나름 부정행위를 막으려는 취지인것 같다.

최소한 1명의 과제를 체점해야 한다. 그렇지 않으면 20%의 감점을 당하게 된다.



Introduction

이미 한번 연산된 결과를 재사용하는 방법을 배우는 실습이다.



Example: Caching the Mean of Vector


<<- operator는 전역을 위한 것이다.



makeVector <- function(x = numeric()) {
        m <- NULL
        set <- function(y) {
                x <<- y # 전역변수
                m <<- NULL  #전역변수
        }
        get <- function() x
        setmean <- function(mean) m <<- mean
        getmean <- function() m
        list(set = set, get = get,
             setmean = setmean,
             getmean = getmean)
}

Assignment: Caching the inverse of a Matrix


아래와 같이 코드를 최종 작성하고 제출 했다.




# Overall, makeCacheMatrix() sustains cache data for resuing it.
# cacheSolve() cacluates the inverse of a Matrix from Matrix or makeCachematrix().
# to validate my won code, you can use the following seqeunces:
# > m <- makeCacheMatrix()
# > m$set(matrix(c(4,2,2,4),2,2))
# > m$get()
#        [,1] [,2]
# [1,]    4    2
# [2,]    2    4
#
# > cacheSolve(m)
#             [,1]       [,2]
# [1,]  0.3333333 -0.1666667
# [2,] -0.1666667  0.3333333
#
# > cacheSolve(m)
# getting cached data
#             [,1]       [,2]
# [1,]  0.3333333 -0.1666667
# [2,] -0.1666667  0.3333333


# makeCacheMatrix: return a list of functions to:
# 1. Set the value of the matrix
# 2. Get the value of the matrix
# 3. Set the value of the inverse
# 4. Get the value of the inverse
makeCacheMatrix <- function(x = matrix()) {
    ## Initialize m
    m <- NULL                                      
    
    ## Create a function which is to keep global_x and global_m as passed matrix and Null, respectively.
    set <- function(y) {
        # y is the initial matrix from user. so it is stored in global_x.
        global_x <<- y 
        # initialize global_m 
        global_m <<- NULL                                
    }
    
    # Create one line function(). a matrix stored by set() is returned.
    get <- function() return(global_x)
    # Create one line function(). a matrix is stored as global value.
    set_global_m <- function(m) global_m <<- m    
    # Create one line function(). a matrix stored by set_global_m() is returned.
    get_global_m <- function() return(global_m)                       
    list(set = set, get = get,
         set_global_m = set_global_m,
         get_global_m = get_global_m)
}

# This function computes the inverse of matrix.
# by checking previous history, this function avoids for redundancy.
cacheSolve <- function(x) {
    # try to get the value from the global environment.
    m<- x$get_global_m()               
    if(!is.null(m)) { # Check the result.
        # by checking if m is NULL, we can know whether this matrix was already computed or not.
        # if so, return computed value in last time, then print the message.
        message("getting cached data")
        return(m)
    }
    # if m is NULL, the inverse of matrix is computed by solve() function.
    # Then, this result should be stored in global value for reusing.
    data <- x$get()               
    inverseMatrix <- solve(data)   
    x$set_global_m(inverseMatrix)             
    return(inverseMatrix)                            
}


'MOOC > R Programming' 카테고리의 다른 글

Certificate & Comment  (0) 2015.08.26
[4 Week] Str & Simulation & R Profiler  (0) 2015.07.30
[2 Week] Programming with R  (0) 2015.07.16
[1 Week] Getting stated and R Nuts and Bolts  (0) 2015.07.08

Ubuntu 14.04에서 VMware Unity Mode 활성화


VMware Unity mode는 매우 좋은 기능이다.

이것을 Ubuntu 14.04에서도 활성화 시키는 방법에 대해서 다루도록 하겠다.


GNOME Flashback/Fallback 


위 버전을 기본으로 한다. 

Ubuntu 14.04는 Unity 환경이므로 이것을 Fallback으로 변경 해야 한다 (관련글 참조)


원래는 Classic gnome을 VMware가 지원 하므로 자동으로 되야 하는데 뭔가 차이가 있어서 안된다고 한다.


diff /usr/bin/vmware-xdg-detect-de \

     $HOME/vmware-tools-distrib/lib/bin32/vmware-xdg-detect-de

58,60d57

< DE=gnome

< xdgDE=gnome


그래서 첨부 파일을 해당 경로에 덮어씌워 줘야 한다.

위 파일은 txt 파일이므로 적절히 확장자를 제거한 후 "/usr/bin/"로 이동 시키자.



그다음 재부팅을 하면 정상적으로 Unity mode가 동작하는 것을 볼 수 있다.




아래는 표는 VMware가 Unity mode를 지원하는 GUI 환경들을 정리한 것이다.


Testing Result of Desktop Environment for VMWare Unity Mode on Ubuntu 14.04 (Trusty)
Desktop EnvironmentDisplay Name in Login ScreenVMWare Unity Mode Works?
Ubuntu UnityUbuntu DefaultNo
GNOME 3GNOMENo
GNOME 3GNOME Flashback (Compwiz)No
GNOME 3GNOME Flashback (Metacity)Yes (See the note on Gnome above and
download vmware-xdg-detect-de)
XfceXfceYes
XfceXUbuntuYes
LXDELXDEYes
LXDELUbuntuYes
MateMateYes (See the note on Mate above and
download vmware-xdg-detect-de)
AwesomeAwesomeNo




참고 자료



[1] Ubuntu 14.04 (Trusty) and VMware Unity Mode


+ Recent posts