"R"의 두 판 사이의 차이
둘러보기로 가기
검색하러 가기
잔글 |
잔글 |
||
1,937번째 줄: | 1,937번째 줄: | ||
**[http://data.seoul.go.kr/ 서울 열린 데이터 광장] | **[http://data.seoul.go.kr/ 서울 열린 데이터 광장] | ||
**[http://kosis.kr/statisticsList/statisticsList_01List.jsp?vwcd=MT_ZTITLE&parmTabId=M_01_01#SubCont 통계청] | **[http://kosis.kr/statisticsList/statisticsList_01List.jsp?vwcd=MT_ZTITLE&parmTabId=M_01_01#SubCont 통계청] | ||
+ | **[http://data.gg.go.kr/ 경기도 공공데이터 공개 포털] | ||
== 온라인교육 == | == 온라인교육 == |
2014년 11월 25일 (화) 17:58 판
통계소프트웨어인 GNU R language를 정리 합니다.
- 한글 위키 : http://r-project.kr/wiki/CentOS
- http://journal.r-project.org/
- http://www.jstatsoft.org/
- http://www.rstudio.com/ide/
- CRAN (Comprehensive R Archive Network)
- R 매뉴얼 : http://r4pda.co.kr/
- 다운로드 : http://cran.rstudio.com/, http://cran.r-project.org/mirrors.html
- 라이센스 : GNU GPL
- 플랫폼 : R Language
목차
R 개요
통계/데이터 마이닝 및 그래프를 위한 언어
- 데이터 분석용 객체지향언어인 GNU S language의 구현
- 통계 분석과 그래픽 처리 분야에 특화된 프로그램 언어와 패키지로 구성된 소프트웨어 환경
- CRAN (Comprehensive R Archive Network)라는 R package site 제공
- 3826개 이상의 package
- 많이 사용하는 통계 Software
- SaS
- Rapid Miner, Weka
- Minitab, SPSS, Systat, RATS, KXEN
R 데이터 종류
개요도
데이터 속성
- 비율식 (Ratio) < 구간식 (Interval) < 순서식 (Ordinal) < 명명식 (Nominal)
데이터 속성 | 상세 |
명명식 (Nominal) |
|
순서식 (Ordinal) |
|
구간식 (Interval) |
|
비율식 (Ratio) |
|
변수
변수 | 상세 |
연속형 변수 |
|
이산형 변수 |
|
데이터 품질
데이터 품질 | 상세 |
특이값 |
|
결측값 |
|
중복 |
|
정확도 |
|
정밀도 |
|
편향 |
|
데이터 형
- 기본형
데이터형 | 상세 |
numeric (수치형) |
|
logical (논리형) |
|
character (문자형) |
|
- 구조형
- 동일한 자료형을 가지는 데이터를 가짐
데이터형 | 상세 |
Scalar (스칼라) |
|
Factor (요인) |
sex <- factor("남", levels=c("남", "여")) #--- 명명식 (Nominal) sex <- factor(c("남", "여"), levels=c("남", "여")) #--- 명명식 (Nominal) factor(c("a", "b", "c"), ordered=TRUE) #--- 순서식 (Ordinal) ordered("a", "b", "c") #--- 순서식 (Ordinal) nlevels(~) #--- 범주의 수 levels(~) #--- 범주 목록 sex[1] #--- 첫번재 값 표시 (1, 2, 3, …) |
Vector (벡터) |
vectorA <- c(1, 2, 3) #--- c. concatenating vectorA <- vector(mode = "numeric", length = 3) names(vectorA) <- c("aaa", "bbb", "ccc") #--- 이름 지정 vectorA["aaa"] #--- 이름으로 데이터 반환 vectorA[2] #--- 두번째 값 반환 (1, 2, 3, …) vectorA[-1] #--- 첫번째 값을 제외하고 반환 vectorA[c(1, 3)] #--- 첫번째와 세번째 값 반환 vectorA[vectorA > 5] #--- 5보다 큰 값 vectorA[c(FALSE, FALSE, TRUE)] #--- TRUE로 표시된 순서의 데이터 반환 vectorC = append(~, ~), vectorC <- c(~, ~) #--- 두개의 Vector 결합 1 %in% vectorA #--- vectorA에 1이 포함되어 있으면 TRUE 반환 union(~, ~), intersect(~, ~), setdiff(~, ~) #--- 합집합, 교집합, 차집합 setequal(~, ~) #--- Vector간 비교 |
Matrix (행렬) |
matrixA <- matrix(1:15, nrow=3, ncol=5) #--- 열부터 데이터 채움 matrixA <- matrix(c(1, 3, 5, 7), nrow=2, ncol=2, #--- 행부터 데이터 채움 byrow=TRUE, dimnames=list(c('R1', 'R2'), c('C1', 'C2))) matrixA[row, col] #--- row 또는 col은 생략 가능 (1, 2, 3, …) matrixA[1:2,] #--- 1행과 2행 데이터 반환 matrixA[-3,] #--- 3행을 제외한 데이터 반환 matrixA["R1", "C1", drop=FALSE] #--- R1 행, C1열 데이터를 Matrix 형태로 반환 matrixA %*% matrixB #--- 행렬 곱 solve(~) #--- 역행렬 t(~) #--- 전치 행렬 (행과 열을 교환) |
Array (배열) |
arrayA <- array(1:12, dim=c(3, 4)) #--- 2차원 배열 생성 attr(arrayA, "dim") <- NULL #--- Array에서 dim 속성을 삭제하면 vector가 됨 Vector #--- dim 속성이 없음 Matrix #--- dim 속성이 c(~, ~) 임 Array #--- dim 속성이 있음 |
- 복합형
- 서로 다른 자료형의 데이터를 가질 수 있음
데이터형 | 상세 |
List (리스트) |
listA <- list(name='aa', age=45) list$name, listA1 #--- 'aa' 반환 listA[1] #--- list(name='aa') 반환 list$name <- NULL #--- List에서 name 항목 삭제 vectorB <- unlist(listA) #--- list를 vector로 변환 sort(~), ~[sort(~)] #--- 정렬 |
Data Frame (데이터 프레임) |
data <- data.frame(x=c(1, 2, 3), y=(4, 5, 6)) #--- x, y열을 같는 데이터 정의 data <- data.frame(cols1, cols2, cols3) data <- data.frame(1:3, c("col1", "col2", "col3")) names(~), colnames(~) #--- 열이름 조회 colnames(~) <- c(~, ~) #--- 열이름 지정 rownames(~) #--- 행 이름 조회 dim(~) #--- 차수(5행 * 2열)를 조회 data[row, col] #--- row/col (1, 2, 3, …) data["rowName", "colName"] data$col1 #--- 컬럼 이름에 해당하는 데이터 #--- R search path에 data 등록, col1 이름을 직접 사용 가능 attach(data) data[, 1] #--- 결과를 Vector로 반환 data[, 1, drop=FALSE] #--- 결과를 Data Frame으로 반환 data[, names(data) %in% c("col2", "col3")] #--- col2, col3 열 표시 data[, c(FALSE, TRUE, TRUE)] #--- 위 라인과 동일한 결과 표시 data[, !names(data) %in% c("col1")] #--- col1 열을 제외한 열 표시 head(~), head(~, 12) #--- 몇 개의 시작 데이터만 조회 tail(~), tail(~, 3) #--- 몇 개의 마지막 데이터만 조회 subset(data, math > 6), data[data$math > 6) #--- 조건을 만족하는 데이터 반환 data[, "math" <- data2[, "math"] + 1 transform(data, math = math + 1) rbind(~, ~), cbind(~, ~) #--- 두개의 data를 행기준, 열기준으로 결합 split(data$a, data$b) #--- b를 기준으로 그룹화된 list 반환 |
- Special Values
데이터 | 상세 |
NULL |
is.null(~) |
NA |
var1[!complete.cases(var1),] #--- var1에서 NA 데이터가 포함된 레코드 제외 var1[is.na(!var1$field1), ] #--- var1에서 field1이 NA인 데이터 레코드 제외 na.omit(data) #--- NA가 포함된 행 제외 na.pass(data) #--- NA 여부에 상관없이 처리 na.fail(data) #--- NA 포함시 Exception 발생 library(Amelia) data(freetrade) #--- year, country를 고려하고 5개의 파일을 만들어 NA 데이터 처리 imsi <- amelia(freetrade, m=5, ts="year", cs="country") freetrade$tariff <- imsi$imputation5$tariff missmap(freetrade) hist(imsi$imputations3$tariff, col="grey", border="white") write.amelia(obj=imsi, file.stem="outdata") #--- outdata1.csv ~ outdata5.csv |
NaN |
is.nan(var1) |
Inf |
is.finite(var1) |
- Formulas
- y ~ x : y는 x로 기술됨
- + : 효과 추가 (y ~ x1 + x2)
- : : Interaction ( y ~ x1 : x2)
- * : Main effect + interaction (y ~ x1 * x2는 다음과 동일 y ~ x1 + x2 + x1 : x2)
- I(~) : I(~)를 사용하여 수식 형태의 독립변수 추가, 예) I(x^2)
- (x1 + x2 + x3)^2 : 최대 2개까지의 변수가 상호 작용이 있음
- x1 + x2 + x3 + x1:x2 + x1:x3 + x2:x3
- -1 : Remove intercept
빅데이터 분석
- 요약 변수 (Summary Variables)
- 빅데이터 분석을 위해서 1차 가공한 변수
- 연속형 변수 : 구간화
- 시계열 : 기간별 ~, 요일별 ~, 주중/주말별 ~
- Trend : 증감액, 증감비율
- 순서 : 구매 순서
- SNS 데이터 : 단어 빈도
- 파생 변수 (Derived Variables)
- 분석자의 판단에 따라 특정 조건을 만족하는 변수
- 예) 가중치를 부여한 데이터, 주구매 상품 10개
- 예) 근무시간 구매지수, 주구매 매장, 주 활동 지역, 주구매 상품(10개), 구매 상품 다양성, 가격 선호대, 시즌 선호 고객, Life Stage, Life Style, 행사 민감, 휴면 가망, 최대 가치, 고객 생애 가치 (CLV), Best Call Time
- 독립 변수
- 종속 변수를 설명하기 위해서 사용하는 변수
- 종속 변수
- 분석의 대상이 되는 변수
- 독립 변수로 설명을 하고자 하는 변수
- 데이터의 속성을 확인하는 함수
- class(~) : 변수의 type을 표시
- is.numeric, is.factor, is.matrix, is.data.frame 등의 함수 제공
- typeof(~) : 저장된 데이터 type을 표시
- mode(~) : 데이터의 저장 구조 표시
- str(~) : 데이터의 내부 구조 표시
- 데이터 변환
- 생성자의 인자로 데이터를 전달하여 변환
- as.character, as.numberic, as.factor 등의 함수 제공
- R의 객체는 불변하므로 객체 연산을 하는 것이 속도와 메모리 측면에서 유리
CentOS에서 R 설치
사전 준비 사항
설치
- R을 설치 합니다.
yum install R R-* R --version
- 관련 패키지 설치
R install.packages("KoNLP")
- 설치 정보
- 홈 디렉토리 : /usr/lib64/R
- 라이브러리 설치 폴더 : /usr/lib64/R/library
- R_SHARE_DIR=/usr/share/R
- R_INCLUDE_DIR=/usr/include/R
- R_DOC_DIR=/usr/share/doc/R-3.0.0
- 실행
R q() 와 n을 입력하여 종료 합니다.
Windows에서 R 설치
R 설치
- http://cran.rstudio.com/ 사이트에서 Windows용 R 설치 파일(R-3.0.2-win.exe)을 다운로드 하여 설치 합니다.
- Windows의 시작 메뉴에서 "R -> R x86 3.0.2" 메뉴를 선택하여 R을 실행 합니다.
q() //--- R 종료
RStudio 설치
- http://www.rstudio.com/ide/download/desktop 사이트에서 윈도우용 RStudio 설치 파일(RStudio-0.98.501.exe)을 다운로드 하여 설치 합니다.
- Windows의 시작 메뉴에서 "RStudio -> RStudio" 메뉴를 선택하여 RStudio를 실행 합니다.
R 매뉴얼
R의 기본 문법
- R 기본 명령어
? cmd //--- 명령어/함수 등에 대한 도움말 help(cmd) //--- 명령어/함수 등에 대한 도움말 ?? cmd //--- 명령어/함수 검색 install.packages("~") //--- Package 설치 library(package) //--- Package 로딩 q() //--- 종료
- 제어문
- var : 데이터의 내용 표시
- var <- val : 변수에 값 지정
- while (~) { break; continue; }
- if (~) { ~ }
- 함수 선언 : funcName <- function(~) { return(result) }
- Sequence value : 1:5 -> 1, 2, 3, 4, 5
1:5 seq(0, 10, by=1) seq(0, 10, length=20) rep(5, 10) //--- 5를 10번 반복
- debug(함수명), undebug(함수명) : 함수 실행시 debug 모드로 실행
- n : 함수를 한줄씩 실행
- c : 함수의 현단계 마지막까지 실행함
- ls() : 확인 가능한 변수를 보여줌
- where : 활성화된 함수의 traeback 목록 표시
- Q : Debug Browser 종료
- 기본 함수
- summary(~) : 통계 정보
- range(~) : 최대/최소, quantile(~) : 4분위 수, var(~) : 분산, sqrt(~) : 표준펀차
- hist(~) : Histogram, plot(~) : 선 그래프, boxplot(~), plot(~) : 산점도 행렬
- 데이터 입력
- 표준 입력 : scan()
- 파일 입력 : read.table(), text, csv, 압축파일 (zip, gzip, bzip 등)
- 데이터 소스 입력 : URL, Database 등
varA <- read.csv(~.csv) load("~.Rdata")
- 데이터 처리
print(varA) rm(varA) //--- varA 변수를 삭제 rm(list=ls(pattern="a01?")) //--- a01로 시작하는 모든 변수 삭제 data(varA) describe(varA) summary(varA)
- 데이터 저장
write.csv(varA, "~.csv") save(varA, file="~.Rdata") //--- 데이터 파일로 저장
R 사용법
- R
memory.limit(4096) #--- Memory를 4GB로 설정
- Package Library
- bigmemory package
install.packages("bigmemory", repos="Http://R-Forge.R-project.org")
- biganalytics package
install.packages("biganalytics", repos="Http://R-Forge.R-project.org")
- doSMP
- Rhipe (R and Hadoop Integrated Processing Environment)
- Google Protocol Buffers (protobuf 2.4.1)
R CMD INSTALL Rhipe_version.tar.gz library(Rhipe) system("wget ~") rhput("~", "hdfs://user/root/~") map<-expression({ words_vector<-unlist(strsplit(unlist(map.values), " ")) lapply(words_vector, function(i) rhcollect(i, 1)) }) reduce<-expression( pre={total <- 0}, reduce={total<-sum(total, unlist(reduce.values))}, post={rhcollect(reduce.key, total)} ) Job <- rhmr( map=map, reduce=reduce, inout=c("text", "sequence"), ifolder="hdfs://user/root/~", ofolder="hdfs://user/root/out/~", jobname="word_count" ) rhex(job) x<-rhread("hdfs://user/root/out/~") head(do.call("rbind", lapply(x, function(x) list(xx, x2)))) m <- expression({ for (i in 1:length(map.values)) rhcollect(map.keyi, map.valuesi) }) res <- rhmr(map=m, inout=c("seq", "map") ifolder="hdfs://user/root/out/~", ofolder="hdfs://user/root/out2/~", ) rhex(res) rhgetkey(list("whale"), "hdfs://user/root/out2/~")
R 한글
샘플링
###----------------------------------------------------------------------------- ### Sample 추출 ###----------------------------------------------------------------------------- data <- iris #--- Index를 사용한 샘플링 #--- replace = TRUE : 복원 추출 #--- 2. 그룹수, 70% : 30% idx <- sample(2, nrow(data), replace = TRUE, prob = c(0.7, 0.3)) train <- data[idx == 1, ] test <- data[idx == 2, ] #--- 데이터를 랜덤하게 섞은 후 샘플링 idx <- sample(1:nrow(data), nrow(data), replace = FALSE) data01 <- data[idx, ] train <- data01[1:floor(nrow(data) * 0.7), ] test <- data01[(floor(nrow(data) * 0.7) + 1):nrow(data), ] #--- 가장 나쁜 샘플링 idx1 <- sample(1:nrow(data), floor(nrow(data) * 0.7), replace = FALSE) idx2 <- setdiff(1:nrow(data), idx1) train <- data[idx1, ] test <- data[idx2, ] rm(list = c("idx1", "idx2")) #--- 분류별 샘플 추출 library(doBy) train <- sampleBy(~ Species, frac = 0.7, replace = FALSE, data = data) train <- sampleBy(~ Species, frac = 0.7, systematic = TRUE, data = data) #--- 계통 추출 #--- 층화 임의 추출 library(sampling) #--- 비복원 단순 임의 추출, Species의 3가지 종류별로 3개, 4개, 5개 샘플 추출 idx <- strata(c("Species"), size = c(3, 4, 5), method = "srswor", data = data) train <- getdata(data, idx) #--- 복원 단순 임의 추출, Species의 3가지 종류별로 3개, 4개, 5개 샘플 추출 idx <- strata(c("Species"), size = c(3, 4, 5), method = "srswr", data = data) train <- getdata(data, idx) #--- K-Fold Cross Validation library(cvTools) m <- cvFolds(nrow(data), K = 10, R = 3) #--- 1/10만큼 테스트 데이터 추출 idx <- m$subset[which(m$which == 1), 1] #--- 첫번째 반복에 사용할 행 번호 train <- data[-idx, ] test <- data[idx, ] #--- createDataPartition library(caret) part <- createDataPartition(data$Species, p = 0.7) #--- 70% 샘플링 train <- data[part$Resample1, ] test <- data[-part$Resample1, ] #--- 불균형을 없애는 샘플링 library(caret) train <- upSample(subset(data, select = - Species), data$Species) train <- downSample(subset(data, select = - Species), data$Species) library(DMwR) train <- SMOTE(Species ~ ., data, perc.over = 600, perc.under = 100) pSample <- function(data, prob = c(0.7, 0.3), type = 1) { if (type == 1) { idx <- sample(2, nrow(data), replace = TRUE, prob = prob) train <- data[idx == 1, ] test <- data[idx == 2, ] list(train = train, test = test) } else { idx <- sample(1:nrow(data), nrow(data), replace = FALSE) data01 <- data[idx, ] train <- data01[1:floor(nrow(data) * prob[1]), ] test <- data01[(floor(nrow(data) * prob[1]) + 1):nrow(data), ] list(train = train, test = test) } } data <- pSample(iris, type = 2) data$train data$test rm(list=ls(all=TRUE)) #--- 작업 영역에 저장된 데이터 모두 삭제
데이터 입출력
- 데이터 로딩
data <- read.table("data/ADV_4_2_003.csv", header=TRUE, sep=",", stringsAsFactors=FALSE, na.strings=c('NIL'), comment.char="#", encoding="UTF-8") load("~.RData")
- 데이터 저장
write.table(data, file="data/data.csv", append=FALSE, quote=FALSE, sep=",", row.names=FALSE) save(data, "~.RData)
Package
knitr
R에는 Markdown을 지원하는 markdown 이라는 패키지가 있습니다. 여기에 knitr 패키지를 사용하면 손쉽게 R 코드를 사용하여 HTML 문서를 만들수 있습니다.
- 패키지 설치
install.packages("knitr") install.packages("markdown")
- Rmd 파일로 HTML 파일 생성
1. 첨부된 SampleKnitr.Rmd 파일을 RStudio의 작업 폴더로 복사 합니다.
2. RStudio에서 SampleKnitr.Rmd 파일을 오픈 합니다.
방법 1. "File --> Open File..." 메뉴를 선택하여 파일을 오픈 합니다. 방법 2. 작업 폴더에서 해당 파일을 마우스로 클릭하여 오픈 합니다.
3. "Knit HTML" 아이콘을 선택하여 Rmd 파일을 HTML 파일(SampleKnitr.html)로 변환 합니다.
- Markdown 문법
~.Rmd 파일에서 사용할 수 있는 markdown 문법은 간단하기 때문에
아래 SampleKnitr.Rmd 파일을 RStudio에서 HTML로 변환하여 비교를 하여 보세요.
Markdown 사용법 = 기본 문법 - ### 줄바꾸기 한 라인의 끝에 두자 이상의 공백 문자를 사용하면 줄이 변경 됩니다. ### 설명문 > 라인의 시작을 ">" 문자로 시작하면 > 설명문을 표시 합니다. ### 참조 #### 링크 http://www.jopenbusiness.com/ [오픈소스 비즈니스 컨설팅](http://www.jopenbusiness.com/) [오픈소스 비즈니스 컨설팅][id1]. [id1]: http://www.jopenbusiness.com/ "Title" #### 이미지 ![오픈소스 비즈니스 컨설팅](h ttp://www.jopenbusiness.com/mediawiki/images/2/28/Namecard_10.png) ![오픈소스 비즈니스 컨설팅][id2] [id2]: h ttp://www.jopenbusiness.com/mediawiki/images/2/28/Namecard_10.png "Title" ### 글씨체 등 *이탤릭체* **볼드체** 위 첨자^2 ~~삭제된 문장~~ 목록 - ### 순서 없는 목록 * 항목 1 * 항목 2 * 항목 2-1 * 항목 2-2 ### 순서 있는 목록 1. 항목 1 2. 항목 2 1. 항목 2-1 2. 항목 2-2 ### 테이블 제목 1 | 제목 2 ----------|---------- 항목 11 | 항목 21 항목 12 | 항목 22 R 코드 실행 - ### 코드 블럭 추가 ```{r} #--- R 코드 추가, R 코드 실행 결과 표시 summary(iris) ``` ``` #--- R 코드 추가 summary(iris) ``` ### 인라인 코드 추가 R 코드 실행 결과 추가 : iris의 dimension은 `r dim(iris)` 입니다. R 코드만 추가 : iris의 dimension은 `dim(iris)` 입니다.
- knitr 패키지 사용법
library(knitr) library(markdown) knit("~.Rmd") markdownToHTML("~.md", "~.html")
- 참고 문헌
dplyr
- dplyr 패키지
library(dplyr) data(iris)
함수 상세 tbl_df() - data.frame 데이터를 data.frame table 형태의 데이터로 변환 합니다.
- print() 시 한 페이지에 해당하는 데이터만 보여주는 기능외에는 특별한 기능은 없습니다.
(data <- tbl_df(iris))
filter() - 데이터 추출
- 조건 : & - AND (,로 구분시), | - OR
- data <- filter(data, 조건1, 조건2)
(data <- filter(data, Species == 'setosa' | Species == 'versicolor'))
arrange() - 정렬 : desc() 사용시 내림차순으로 정렬
- data <- arrange(data, field1, desc(field2))
(data <- arrange(data, Sepal.Length))
select() - 열 추출 (- 사용시 추출에서 제외할 열 지정)
- data <- select(data, field1, -field2)
(data <- select(data, Sepal.Length, Sepal.Width, Species))
mutate() - 열 추가 : 새로 추가된 열은 다음 계산식에서 사용 가능
- data <- mutate(data, newField = 계산식)
(data <- mutate(data, Total = Sepal.Length + Sepal.Width))
group_by() - 그룹화 : field1의 값으로 그룹화
- data <- group_by(data, field1)
(data <- group_by(data, Species))
summarise() - 집계 : group_by()로 지정한 그룹을 기준으로 집계
- summarise(data, t1 = 수식, t2 = 수식)
summarise(data, meanLength = mean(Sepal.Length), meanWidth = mean(Sepal.Width))
- dplyr는 chain 형태로도 사용할 수 있습니다.
- data %.% 함수1 %.% 함수2 %.% 함수3
data(iris) (data <- iris) (data <- data %.% filter(Species == 'setosa' | Species == 'versicolor') %.% arrange(Sepal.Length) %.% select(Sepal.Length, Sepal.Width, Species) %.% mutate(Total = Sepal.Length + Sepal.Width) %.% group_by(Species) %.% summarise(meanLength = mean(Sepal.Length), meanWidth = mean(Sepal.Width)) )
Classification
분류 분석
- 분류 분석 개요
#--- MASS : m <- lda(Species ~ ., data=train); pred$class #--- MASS : m <- qda(Species ~ ., data=train); pred$class #--- party : m <- ctree(Species ~ ., data=train); pred #--- party : m <- cforest(Species ~ ., data = train, control = cforest_unbiased(mtry = 3)); pred #--- randomForest : m <- randomForest(Species ~ ., data = train, ntree = 100, proximity = TRUE); pred #--- rpart : m <- rpart(Species ~ ., data = train, control = rpart.control(minsplit = 10))) #--- predict(result$m, result$train) #--- class가 숫자일 경우 사용
- 분류 분석
###--- 데이터 준비 data <- iris idx <- sample(2, nrow(data), replace = TRUE, prob = c(0.7, 0.3)) train <- data[idx == 1, ] test <- data[idx == 2, ] cls <- "Species" formula = Species ~ . ###--- 분류 분석 (아래에서 한가지 선택) library(MASS) m <- lda(formula, data=train) #--- Linear Discriminant Analysis, 선형 판별 분석 library(MASS) m <- qda(formula, data=train) #--- Quadratic Discriminant Analysis, 이차 판별 분석 library(party) m <- ctree(formula, data=train) library(party) m <- cforest(formula, data = train, control = cforest_unbiased(mtry = 3)) library(randomForest) m <- randomForest(formula, data = train, ntree = 100, proximity = TRUE) #--- ntree = 100 : 최대 트리개수 100개 #--- proximity = TRUE : 다양한 트리분할 시도 ###--- data로부터 분류 산정 pred <- predict(m) #--- cforest pred <- predict(m, train) #--- ctree, randomForest pred <- predict(m, train)$class #--- lda, qda ###--- 분류 분석 시각화 plot(m) #--- lda, ctree, randomForest plot(m, type = "simple") #--- ctree ###--- 변수 및 분류 분석 평가 margin(m, data[, cls]) #--- randomForest varImpPlot(m) #--- randomForest importance(m) #--- randomForest table(pred, train[, cls]) #--- 예측값과 실제값의 비교 correct <- pred == train[, cls] print(paste(round(mean(correct) * 100, 2), "% of predicted classifications correct for train", sep="")) ###--- 분류 분석을 통한 예측 pred <- predict(m, newdata = test) #--- ctree, cforest, randomForest pred <- predict(m, newdata = test)$class #--- lda, qda table(pred, test[, cls]) #--- 예측값과 실제값의 비교 correct <- pred == test[, cls] print(paste(round(mean(correct) * 100, 2), "% of predicted classifications correct for test", sep=""))
Estimation
formula
- 문자열을 사용하여 R Language에서 제공하는 formula 생성하기
formula("문자열")
회귀분석
###--- 데이터 준비 data <- iris left <- "Sepal.Length" upper = "~ Sepal.Width + Petal.Length + Petal.Width" ###--- 수작업으로 회귀 분석, 유의한 결과가 나올 때까지 formula를 변경해 가면서 적용 plot(data) #--- 데이터의 분포를 보고 초기 회귀식을 작성 m <- lm(formula(paste(left, upper)), data = data) #--- 회귀식 : Sepal.Length = 1.8560 + 0.6508 * Petal.Length + 0.7091 * v - 0.5565 * Petal.Width #--- formula(paste(left, upper)) 부분을 원하는 formula로 변경해 가면서 회귀식을 작성 하세요. summary(m) #--- F 통계량 (F-statistic) #--- p-value : 유의수준 5%하에서 0.05보다 작으면 통계적으로 유의함 #--- 결정 계수 (Multiple R-Squared) : 회귀식이 데이터를 설명하는 정도 #--- 수정 결정 계수 (Adjusted R-squared) #--- 유의수준 (Pr(>|t|)) : 회귀계수들의 p-value, 0.05보다 작으면 통계적으로 유의함 #--- 후진제거법으로 변수 선택시, 유의수준이 높은 변수부터 제거 합니다. ###--- 자동으로 회귀 분석 step(lm(formula(paste(left, "~ 1")), data=data), scope=list(lower=~ 1, upper=formula(upper)), direction="forward") #--- 전진선택법 step(lm(formula(paste(left, upper)), da ta=data), scope=list(lower=~ 1, upper=formula(upper)), direction="backward") #--- 후진소거법 step(lm(formula(paste(left, "~ 1")), data=data), scope=list(lower=~ 1, upper=formula(upper)), direction="both") #--- 단계적방법
시계열 분석
###--- 데이터 준비 (data <- c(60, 43, 67, 50, 56, 42, 50, 65, 68, 43, 65, 34, 47, 34, 49, 41, 13, 35, 53, 56, 16, 43, 69, 59, 48, 59, 86, 55, 68, 51, 33, 49, 67, 77, 81, 67, 71, 81, 68, 70, 77, 56)) (data <- ts(data)) #--- 데이터를 시계열 자료 형식으로 변환 ###----------------------------------------------------------------------------- #--- 자동으로 시계열 모형 선택 library(forecast) auto.arima(data) #--- 자동으로 최적의 ARIMA 모형을 제시 ###----------------------------------------------------------------------------- #--- 수동으로 시계열 모형 선택 plot(data) #--- 각 요인(추세, 순환, 계절, 불규칙)을 시각적으로 확인 data01 <- data #--- 평활 : 들쭉날쭉한 시계열자료 값을 평탄한 값으로 변환 #--- 이동평균법, 지수평활법 등 library(TTR) #--- 평활 plot(data01) plot(SMA(data01, n = 2)) #--- 2년마다 평균을 낸 데이터로 변환 plot(SMA(data01, n = 3)) #--- 3년마다 평균을 낸 데이터로 변환 plot(SMA(data01, n = 4)) #--- 4년마다 평균을 낸 데이터로 변환 plot(SMA(data01, n = 5)) #--- 5년마다 평균을 낸 데이터로 변환 plot(SMA(data01, n = 6)) #--- 6년마다 평균을 낸 데이터로 변환 plot(SMA(data01, n = 7)) #--- 7년마다 평균을 낸 데이터로 변환 plot(SMA(data01, n = 8)) #--- 8년마다 평균을 낸 데이터로 변환 plot(SMA(data01, n = 9)) #--- 9년마다 평균을 낸 데이터로 변환 (data01 <- SMA(data01, n = 3)) #--- n의 값은 위 그래프를 보고 판단 #--- 정상형 시계열 자료로 만들기 위해서 차분을 진행 plot(data01) plot(diff(data01, differences = 1)) #--- 1차 차분 (difference), ARIMA(p, 1, q) 모델 plot(diff(data01, differences = 2)) #--- 2차 차분 (difference), ARIMA(p, 2, q) 모델 plot(diff(data01, differences = 3)) #--- 3차 차분 (difference), ARIMA(p, 3, q) 모델 plot(diff(data01, differences = 4)) #--- 4차 차분 (difference), ARIMA(p, 4, q) 모델 plot(diff(data01, differences = 5)) #--- 5차 차분 (difference), ARIMA(p, 5, q) 모델 plot(diff(data01, differences = 6)) #--- 6차 차분 (difference), ARIMA(p, 6, q) 모델 plot(diff(data01, differences = 7)) #--- 7차 차분 (difference), ARIMA(p, 7, q) 모델 plot(diff(data01, differences = 8)) #--- 8차 차분 (difference), ARIMA(p, 8, q) 모델 plot(diff(data01, differences = 9)) #--- 9차 차분 (difference), ARIMA(p, 9, q) 모델 (data01 <- diff(data01, differences = 2)) #--- differences의 값은 위 그래프를 보고 판단 #--- 부분자기함수(PACF) (pacf(data01, lag.max=10)) #--- 부분자기함수(PACF) #--- lag = 0인 지점은 판단에서 제외 #--- lag = 만약 4에서 절단점을 가질 경우 AR(3) 모형 #--- 자기상관함수(ACF) (acf(data01, lag.max=10, Plot=TRUE)) #--- 자기상관함수(ACF) #--- lag = 0인 지점은 판단에서 제외 #--- lag = 만약 2에서 절단점을 가질 경우 MA(1) 모형 ###----------------------------------------------------------------------------- #--- 모델 보정 (fitting) 및 예측 (data02 <- arima(data, order=c(2, 0, 0))) library(forecast) (data03 <- forecast.Arima(data02, h=20))#--- 20개 데이터 예측 plot(data03) #--- 신뢰구간 80%와 95%에서 예측값 표시 ###----------------------------------------------------------------------------- #--- 분해 시계열 모형 plot(data) #--- 각 요인(추세, 순환, 계절, 불규칙)을 시각적으로 확인 m <- decompose(data) #--- 시계열에 영향을 주는 일반적인 요인을 시계열에서 분리 m$x #--- 원본 데이터 m$trend #--- 추세요인 (Trend factor, 경향요인) m$seasonal #--- 계절요인 (Seasonal factor) m$random #--- 불규칙요인 (Irregular factor) plot(m) #--- 추세요인, 계절요인, 불규칙요인이 포함된 그래프 plot(data - m$trend) #--- 추세요인을 제거한 그래프 plot(data - m$trend - m$seasonal) #--- 추세요인과 계절요인을 제거한 그래프
- 참고 문헌
Clustering
군집 분석
- 군집 분석 개요
#--- stats : m <- kmeans(data, centers = 3); m$cluster #--- stats : m <- hclust(dist(data, method = "euclidean")^2, method = "ward") #--- pred <- cutree(m, k = 3) #--- cluster : m <- pam(data, 3), m$cluster #--- cluster : m <- fanny(data, 2), m$cluster #--- fpc : m <- dbscan(data, eps = 0.5, MinPts = 5); m$cluster #--- pred <- predict(m, data) #--- class : m <- SOM(data, somgrid(topo = "hexagonal")) #--- m <- SOM(data, somgrid(topo = "hexagonal"), #--- alpha = list(seq(0.05, 0, len = 1e4), seq(0.02, 0, len = 1e5)), #--- radii = list(seq(8, 1, len = 1e4), seq(4, 1, len = 1e5)))
- 군집 분석
#--- 데이터 준비 data <- iris[, 1:4] #--- 원본 데이터 cls <- iris[, 5] #--- 원본 데이터의 분류 group <- 3 #--- 군집수, Clustering - 군집수 결정 참조 #--- 군집 분석 (아래에서 한가지 선택) library(stats) m <- kmeans(data, group) #--- K-평균군집 library(cluster) m <- pam(data, group) #--- PAM (Partitioning Around Medoids) library(cluster) m <- fanny(data, group) #--- Fuzzy Clustering library(fpc) m <- dbscan(data, eps = 0.5), MinPts = 5) #--- Density-based Clustering #--- eps : Maximum distance #--- MinPts : 최소 데이터 개수 #--- eps 범위내에 MinPts 개수의 데이터가 있으면 군집으로 분류 #--- data로부터 군집 산정 pred <- m$cluster
- 시각화를 위해서는 아래 방식을 사용해 보세요.
plot(m) #--- pam, fanny plot(data, col = pred) #--- kmeans, pam, fanny plot(m, data) #--- dbscan plotcluster(data, pred) #--- dbscan
- 군집 분석의 제대로 되고 있는지 확인 하려면 아래와 같이 수작업을 하세요.
table(pred, cls) #--- predStr : 숫자로 표시된 pred를 문자로 변경하기 위해 사용 #--- data 별로 다르므로 매번 수작업이 필요 합니다. predStr <- c("setosa", "versicolor", "virginica") print(paste(round(mean(predStr[pred] == cls) * 100, 2), "% of predicted clusters correct", sep=""))
군집의 개수 산정
###----------------------------------------------------------------------------- ### 군집의 개수 산정 ### data : 원본 데이터 ### groups : 확인할 군집의 개수 범위 ### 그래프의 경사가 완만해 지는 지점이 군집의 개수 입니다 ###----------------------------------------------------------------------------- findCluster = function(data = iris[, 1:4], groups = 1:10) { models <- 0 for (i in groups) { models[i] <- sum(kmeans(data, centers = i)$withinss) } plot(groups, models, type = "b", main = "군집의 개수 산정", xlab = "군집의 수", ylab = "군집간 거리 제곱합") } findCluster()
Association
연관 분석
###----------------------------------------------------------------------------- ### 연관 분석 ### 트랜잭션 데이터 : items, transactionID, TimeStamp ### items : 트랜잭션(rows)에 속한 항목(columns)의 이름과 값 ### transactionID : 트랜잭션 아이디 (rows 이름) ### TimeStamp : 트랜잭션이 발생한 시간 ###----------------------------------------------------------------------------- ###--- 데이터 준비 data(Epub, package = "arules") (data <- Epub) length(data) #--- transactions 데이터 개수 size(data[1]) #--- 첫번째 트랜잭션의 항목수 data[1] #--- 첫번째 트랜잭션 데이터 조회 inspect(data[1]) #--- 첫번째 트랜잭션 데이터 상세 조회 transactionInfo(data[1]) #--- transactions 데이터 조회 itemsetInfo(data[1]) #--- 첫번째 트랜잭션 아이디 itemInfo(data[1]) #--- 모든 항목의 목록 summary(data[1]) #--- 첫번째 트랜잭션 데이터 요약 summary(data) #--- 트랜잭션 데이터 요약 as(data, "list")[1] #--- list로 변환한 후 첫번째 데이터 조회 format(as.POSIXlt(transactionInfo(data[1])"TimeStamp"), "%Y-%m-%d %H:%M:%S") #--- TimeStamp를 문자열로 변환 #--- support = 0.1 : 최소지지도 10% 이상 #--- cex.names = 0.8 : 글씨 크기 itemFrequencyPlot(data, support = 0.1, cex.names = 0.8) #--- 항목별 빈도수 #--- support = 0.01 : 최소지지도 1% 이상, 최소신뢰도 60% 이상인 연관 규칙 탐색 (m <- apriori(data, parameter = list (support = 0.01, confidence = 0.6))) summary(m) length(m) #--- 연관규칙의 개수 inspect(m[1:10]) #--- 10개의 연관규칙 조회 #--- 연관규칙 : lhs 발생 후에 rhs 발생 #--- support : 지지도, confidence : 신뢰도, lift. 향상도 inspect(sort(m[1:10])) #--- 지지도 내림 차순으로 정렬후 조회 inspect(sort(m[1:10], by = "confidence")) #--- 신뢰도 내림 차순으로 정렬후 조회 inspect(sort(m[1:10], by = "lift")) #--- 향상도 내림 차순으로 정렬후 조회 #--- rhs가 "income=small"이고 향상도(lift)가 1.2 이상이 연관규칙 추출 (small <- subset(m, subset = rhs %in% "income=small" & lift > 1.2)) inspect(small[1:10]) #--- 10개의 연관규칙 조회 #--- rhs가 "income=large"이고 향상도(lift)가 1.2 이상이 연관규칙 추출 (large <- subset(m, subset = rhs %in% "income=large" & lift > 1.2)) inspect(large[1:10]) #--- 10개의 연관규칙 조회 write(m[1:10], file="m.txt", sep = "\t", col.names = NA) #--- 연관규칙을 파일로 저장 library("pmml") saveXML(pmml(m[1:10]), file = "m.xml") #--- 연관규칙을 XML로 변환한 후, XML 파일로 저장
Optimization
loSolve
#--- "판매 수익 최대화" #--- 제품 : A, B, C, D #--- 목적 함수 : 4 * A + 6 * B + 7 * C + 8 * D (최대 수익) #--- 제약식 #--- 혼합 공정 시간 : 1 * A + 1.5 * B + 2 * C + 3 * D <= 800시간 #--- 주형 공정 시간 : 1.5 * A + 2 * B + 2 * C + 3 * D <= 1000시간 #--- 검사 공정 시간 : 0.5 * A + 0.6 * B + 1 * C + 1 * D <= 340시간 #--- B <= A : 1 * A - 1 * B + 0 * C + 0 * D >= 0 library(lpSolve) f.obj <- c(4, 6, 7, 8) #--- 목적함수 계수 (f.con <- matrix(c( 1, 1.5, 2, 3, 1.5, 2, 2, 3, 0.5, 0.6, 1, 1, 1, -1, 0, 0), nrow = 4, byrow = TRUE))#--- 제약식 행렬 (f.dir <- c("<=", "<=", "<=", ">=")) #--- 제약식 부등호 (f.rhs <- c(800, 1000, 340, 0)) #--- 제약식 우변값 lp("max", f.obj, f.con, f.dir, f.rhs) #--- 목적함수 값 lp("max", f.obj, f.con, f.dir, f.rhs)$solution #--- 최적의 해 lp("max", f.obj, f.con, f.dir, f.rhs, compute.sens = TRUE)$duals lp("max", f.obj, f.con, f.dir, f.rhs, compute.sens = TRUE)$duals.from lp("max", f.obj, f.con, f.dir, f.rhs, compute.sens = TRUE)$duals.to lp("max", f.obj, f.con, f.dir, f.rhs, compute.sens = TRUE)$sens.coef.from #--- 목적식 계수의 민감도 분석 - 하한 lp("max", f.obj, f.con, f.dir, f.rhs, compute.sens = TRUE)$sens.coef.to #--- 목적식 계수의 민감도 분석 - 상한
lpSolveAPI
#--- "판매 수익 최대화" #--- 제품 : A, B, C, D #--- 목적 함수 : 4 * A + 6 * B + 7 * C + 8 * D (최대 수익) #--- 제약식 #--- 혼합 공정 시간 : 1 * A + 1.5 * B + 2 * C + 3 * D <= 800시간 #--- 주형 공정 시간 : 1.5 * A + 2 * B + 2 * C + 3 * D <= 1000시간 #--- 검사 공정 시간 : 0.5 * A + 0.6 * B + 1 * C + 1 * D <= 340시간 #--- B <= A : 1 * A - 1 * B + 0 * C + 0 * D >= 0 library("lpSolveAPI") m <- make.lp(0, 4) #--- 4는 변수의 개수 lp.control(m, sense="max") #--- 최대값 구하기 set.objfn(m, c(4, 6, 7, 8)) #--- 목적 함수 add.constraint(m, c(1, 1.5, 2, 3), "<=", 800) #--- 혼합 공정 시간의 제약식 add.constraint(m, c(1.5, 2, 2, 3), "<=", 1000) #--- 주형 공정 시간의 제약식 add.constraint(m, c(0.5, 0.6, 1, 1), "<=", 340) #--- 검사 공정 시간의 제약식 add.constraint(m, c(1, -1, 0, 0), ">=", 0) #--- B <= A 인 제약식 m #--- 등록된 목적 함수와 제약식 보기 solve(m) #--- 최적해 구하기 get.objective(m) #--- 최적해 get.variables(m) #--- 최적해일 때, 변수들의 값
Text Mining
- 텍스트 마이닝
library(tm) getReaders() #--- Reader의 종류 확인 getTransformations() #--- tm_map용 함수 목록 ###----------------------------------------------------------------------------- ### Corpus 생성 (lines <- c("You're awe some and I love you", "I hate and hate and hate. So angry. Die!", "Impressed and amazed: you are peer less in your achievement of unparalleled mediocrity.", "I love you")) (doc <- Corpus(VectorSource(lines))) #--- XML 파일 읽기 #--- C:/Program Files/R/R-3.0.3/library/tm/texts/crude/ 폴더 지정 (folder <- system.file("texts", "crude", package = "tm")) (doc <- Corpus(DirSource(folder), readerControl = list(reader = readReut21578XML))) rm(folder) ###----------------------------------------------------------------------------- ### Corpus 조회 summary(doc) doc1 #--- 첫번째 문서 조회 inspect(doc[1]) #--- 첫번째 문서 조회 #writeCorpus(doc) #--- Corpus 저장 #writeCorpus(doc[1], filenames="01.txt") #--- 첫번째 Corpus 저장 ###----------------------------------------------------------------------------- ### Corpus 변환 (doc <- tm_map(doc, as.PlainTextDocument))1 #--- XML 문서를 Text로 변환 (doc <- tm_map(doc, stripWhitespace))1 #--- 두개 이상의 공백을 하나의 공백으로 치환 (doc <- tm_map(doc, tolower))1 #--- 소문자로 변환 (doc <- tm_map(doc, removePunctuation))1 #--- 구두점 삭제 (doc <- tm_map(doc, removeWords, stopwords("english")))1 #--- Stopword (조사, 띄어쓰기, 시제 등)를 제거하고 표준화 (doc <- tm_map(doc, stripWhitespace))1 #--- 두개 이상의 공백을 하나의 공백으로 치환 (doc <- tm_map(doc, stemDocument))1 #--- 어근만 추출 #(doc <- tm_map(doc, removeNumbers))1 #--- 숫자 삭제 #removeURL <- function(x) gsub("httpalnum:*", "", x) #(doc <- tm_map(doc, removeURL))1 #--- URL 삭제 #rm(removeURL) #(doc <- tm_map(doc, gsub, pattern = "diamond", replacement = "aaa"))1 #--- 문자열 치환 #(doc <- tm_map(doc, grep, pattern = "diamond"))1 #--- diamond가 포함된 라인 번호 반환 #(doc <- tm_map(doc, stemCompletion, dictionary = doc))1 #--- 어근으로 원래 단어 유추 # (a <- c("mining", "miners", "mining")) # (b <- stemDocument(a)) # (d <- stemCompletion(b, dictionary=a)) ###----------------------------------------------------------------------------- ### DocumentTermMatrix / TermDocumentMatrix (m <- DocumentTermMatrix(doc)) #--- DocumentTermMatrix 생성 #--- Non-/sparse entries : 단어가 있는 entry / 단어가 없는 entry #--- Sparsity : 문서별 단어 중 한번도 사용하지 않은 비율 (m <- removeSparseTerms(m, 0.70)) #--- Sparsity가 70% 이상인 경우 삭제 dic <- c("prices", "crude", "oil") #--- 여기 기술된 단어를 포함하는 모델 생성 (m <- DocumentTermMatrix(doc, list(dictionary = dic))) (m <- TermDocumentMatrix(doc)) #--- TermDocumentMatrix 생성 (m <- t(m)) #--- DocumentTermMatrix로 변환 (data <- as.matrix(m)) #--- DocumentTermMatrix를 matrix로 변환 m$nrow #--- 문서 (document) 개수 / 단어 (term) 개수 m$ncol #--- 단어 (term) 개수 / 문서 (document) 개수 m$dimnames #--- 문서 (document)와 단어 (term) 목록 m$dimnames$Docs m$dimnames$Terms m$i #--- 문서 (document) 인덱스 / 단어 (term) 인덱스 m$j #--- 단어 (term) 인덱스 / 문서 (document) 인덱스 m$v #--- m$i[0] 문서에서 m$j[0] 단어의 발생 빈도 #--- m$j[0] 문서에서 m$i[0] 단어의 발생 빈도 inspect(m) #--- 단어의 분포를 확인 inspect(m[1:2, 3:5]) #--- 처음 2개 문서의 3번째에서 5번째 단어의 분포를 확인 findFreqTerms(m, 10) #--- 10회 이상 사용된 단어 표시 findFreqTerms(m, 10, 15) #--- 10회 이상, 15회 이하 사용된 단어 표시 findAssocs(m, "oil", 0.65) #--- "oil" 단어와 연관성(같이 사용될 확률)이 65% 이상이 단어를 표시 rm(dic)
- 단어의 빈도 분석
###----------------------------------------------------------------------------- ### 단어의 빈도 분석 (frequency <- colSums(data)) #--- 단어별 발생 건수 계산 (frequency <- subset(frequency, frequency >= 20)) #--- 10건 이상 발생한 단어 추출 #library(gdata) (frequency <- as.data.frame(available.packages())) #--- 패키지 목록 추출 (frequency <- gdata::trim(unlist(strsplit(as.character(frequency$Depends), ',')))) #--- 패키지 의존 정보 추출 (frequency <- gsub('[ \\(].*|\\n', , frequency)) #--- 다양한 문자 부호 제거 (frequency <- table(frequency)) #--- 단어의 빈도수 테이블 library(ggplot2) barplot(frequency, las = 2) library(wordcloud) #--- 워드 클라우드 wordcloud(names(frequency), as.numeric(frequency), colors = c("green", "red")) wordcloud(names(frequency), log(as.numeric(frequency)), colors = c("green", "red")) (colors <- gray((frequency + 10) / (max(frequency) + 10))) wordcloud(words = names(frequency), freq = frequency, min.freq = 2, random.order = F, colors = colors) rm(frequency, colors) rm(list=ls(all=TRUE)) #--- 작업 영역에 저장된 데이터 모두 삭제
- 문서의 군집 분석
###----------------------------------------------------------------------------- ### 문서의 군집 분석 (fit <- hclust(dist(scale(data)), method = "ward")) plot(fit) rect.hclust(fit, k = 3) #--- 5개의 그룹으로 구분 (groups <- cutree(fit, k = 3)) #--- 문서별로 그룹 지정 rm(fit, groups) k <- 3 (kmeansResult <- kmeans(m, k)) #--- k-평균 군집 모형 for (i in 1:k) { cat(paste("cluster", i, ": ", sep = "")) s <- sort(kmeansResult$centers[i,], decreasing = T) cat(names(s), "\n") } library(fpc) (pamResult <- pamk(m, metric = "manhatttan")) (k <- pamResult$nc) (pamResult <- pamResult$pamobject) for (i in 1:k) { cat(paste("cluster", i, ": ")) cat(colnames(pamResult$medoids)[which(pamResult$medoids[i, ] == 1)], "\n") } plot(pamResult, color = F, labels = 4, lines = 0, #--- 오류가 발생함 cex = .8, col.clus = 1, col.p = pamResult$clustering) rm(list=ls(all=TRUE)) #--- 작업 영역에 저장된 데이터 모두 삭제
- 감성 분석
###----------------------------------------------------------------------------- ### 감성 분석 ###----------------------------------------------------------------------------- #--- 문장을 입력받아 문장과 점수를 반환 #--- 점수 = 긍정 점수 - 부정 점수 #--- 긍정 점수 : 긍정 단어 (pos.words)가 포함된 개수 #--- 부정 점수 : 부정 단어 (neg.words)가 포함된 개수 (pos.word <- scan("data/ADV_4_5_positiveWords.txt", what = "character", comment.char = ";")) #--- 긍정 단어 (pos.words <- c(pos.word, "upgade")) (neg.word <- scan("data/ADV_4_5_negativeWords.txt", what = "character", comment.char = ";")) #--- 부정 단어 (neg.words <- c(neg.word, "wait", "waiting")) scores <- function(sentences, pos.words, neg.words, .progress='none') { #--- 점수와 문장을 반환 require(plyr) require(stringr) scores = laply( sentences, function(sentence, pos.words, neg.words) { sentence = gsub('punct:', , sentence) #--- 구두점 삭제 sentence = gsub('cntrl:', , sentence) #--- 특수기호 삭제 sentence = gsub('\\d+', , sentence) #--- 숫자 삭제 sentence = tolower(sentence) #--- 소문자로 변환 word.list = str_split(sentence, '\\s+') #--- 하나 이상의 공백으로 단어 추출 words = unlist(word.list) #--- list를 벡터로 변환 pos.matches = match(words, pos.words) #--- 긍정의 점수 계산 (긍정 단어와 매핑되는 개수 산정) pos.matches = !is.na(pos.matches) neg.matches = match(words, neg.words) #--- 부정의 점수 계산 (부정 단어와 매핑되는 개수 산정) neg.matches = !is.na(neg.matches) score = sum(pos.matches) - sum(neg.matches) return (score) }, pos.words, neg.words, .progress=.progress ) scores.df = data.frame(score=scores, text=sentences) return(scores.df) } (result <- scores(lines, pos.words, neg.words)) library(ggplot2) qplot(result$score) hist(result$score)
- 연관 분석
###----------------------------------------------------------------------------- ### 연관 분석 ###----------------------------------------------------------------------------- library(KoNLP) extractNoun("연습을 해보고자 한다. 명사가 잘 추출되는지 보자. 빨간색으로 글씨를 쓴다.") sapply("연습을 해보고자 한다. 명사가 잘 추출되는지 보자. 빨간색으로 글씨를 쓴다.", extractNoun) system.time(nouns <- sapply(head(lines, 1000), extractNoun, USE.NAMES = FALSE)) rm(nouns) (data <- Map(extractNoun, lines)) #--- 각 문장에서 명사 추출 (문장 -> 문자열 목록) (data <- unique(data))1 #--- 라인별 데이터를 unique하게 (data <- sapply(data, unique))1 #--- 각 라인내 데이터를 unique하게 (data <- sapply(data, function(x) { #--- 2자 이상 4자 이하의 한글 단어 추출 Filter(function(y) { nchar(y) <= 4 && nchar(y) > 1 && is.hangul(y) }, x) })) (data <- Filter(function(x) { length(x) >= 2 }, data)) #--- 단어가 2개 이상 포함된 문장만 추출 (names(data) <- paste("Tr", 1:length(data), sep = "")) #--- 데이터에 행 이름 지정 data #--- 문장별 단어 목록 library(arules) (data <- as(data, "transactions")) (dataTab <- crossTable(data)) #--- 빈도수 5%, 같이 있을 확률이 10%인 단어 목록 추출 #--- 최소지지도 5% 이상, 최소신뢰도 10% 이상인 연관 규칙 탐색 (m <- apriori(data, parameter = list(supp = 0.05, conf = 0.1))) inspect(m) rm(list=ls(all=TRUE)) #--- 작업 영역에 저장된 데이터 모두 삭제
Social Network Analytics
###----------------------------------------------------------------------------- ### 데이터 준비 #data <- read.table("http://sna.stanford.edu/sna_R_labs/data/Krack-High-Tec-edgelist-Advice.txt") #write.table(data, file="data/ADV_4_5_001.csv", append=FALSE, quote=FALSE, sep=",", row.names=FALSE) (data01 <- read.table("data/ADV_4_5_001.csv", header=TRUE, sep=",", stringsAsFactors=FALSE, na.strings=c('NIL'), comment.char="#", fileEncoding="UTF-8", encoding="CP949")) colnames(data01) <- c("ego", "alter", "advice_tie") #data <- read.table("http://sna.stanford.edu/sna_R_labs/data/Krack-High-Tec-edgelist-Friendship.txt") #write.table(data, file="data/ADV_4_5_002.csv", append=FALSE, quote=FALSE, sep=",", row.names=FALSE) (data02 <- read.table("data/ADV_4_5_002.csv", header=TRUE, sep=",", stringsAsFactors=FALSE, na.strings=c('NIL'), comment.char="#", fileEncoding="UTF-8", encoding="CP949")) colnames(data02) <- c("ego", "alter", "friendship_tie") #data <- read.table("http://sna.stanford.edu/sna_R_labs/data/Krack-High-Tec-edgelist-ReportsTo.txt") #write.table(data, file="data/ADV_4_5_003.csv", append=FALSE, quote=FALSE, sep=",", row.names=FALSE) (data03 <- read.table("data/ADV_4_5_003.csv", header=TRUE, sep=",", stringsAsFactors=FALSE, na.strings=c('NIL'), comment.char="#", fileEncoding="UTF-8", encoding="CP949")) colnames(data03) <- c("ego", "alter", "reports_to_tie") #data <- read.csv("http://sna.stanford.edu/sna_R_labs/data/Krack-High-Tec-Attributes.csv", header = T) #write.table(data, file="data/ADV_4_5_004.csv", append=FALSE, quote=FALSE, sep=",", row.names=FALSE) (data04 <- read.table("data/ADV_4_5_004.csv", header=TRUE, sep=",", stringsAsFactors=FALSE, na.strings=c('NIL'), comment.char="#", fileEncoding="UTF-8", encoding="CP949")) which(data01$ego != data02$ego) #--- 두 데이터의 ego가 동일한지 검사 which(data01$ego != data03$ego) #--- 두 데이터의 ego가 동일한지 검사 which(data01$alter != data02$alter) #--- 두 데이터의 alter가 동일한지 검사 which(data01$alter != data03$alter) #--- 두 데이터의 alter가 동일한지 검사 #(data <- cbind(data01, data02$friendship_tie, data03$reports_to_tie)) #names(data)[4:5] <- c("friendship_tie", "reports_to_tie") (data <- data.frame(ego = data01[, 1], alter = data01[, 2], advice_tie = data01[, 3], friendship_tie = data02[, 3], reports_to_tie = data03[, 3])) (data <- subset(data, (advice_tie > 0 | friendship_tie > 0 | reports_to_tie > 0))) (attrs <- cbind(1:length(data04[, 1]), data04)) rm(list = c("data01", "data02", "data03", "data04")) ###----------------------------------------------------------------------------- ### 그래프 생성 library(igraph) #(m <- graph.data.frame(data)) #--- 방향 그래프 생성 (m <- graph.data.frame(d = data, directed = TRUE, vertices = attrs)) #--- 그래프 #--- Node : vertex, link : edge #--- 첫번째 컬럼이 두번째 컬럼을 가르키는 방향성 그래프 생성 #--- 세번째 이상의 컬럼은 edge의 attribute로 추가됨 #--- directed : TRUE. 방향 그래프, FALSE. 무방향 그래프 #--- vertices : vertex의 속성, 첫번째 열이 vertices의 아이디 #(m <- as.undirected(m, mode = "collapse")) #--- 무방향 그래프로 변환 #(m <- as.directed(m)) #--- 방향 그래프로 변환 #--- 방향성을 삭제한 인접(adjacency) 매트릭스 생성 #(m <- graph.adjacency(data, weight = T, mode = "undirected")) #(m <- simplify(m)) #--- 그래프 단순화 m$layout <- layout.fruchterman.reingold(m) #--- Fruchterman-Reingold Layout summary(m) vcount(m) #--- Vertex 개수 V(m) #--- Vertex get.vertex.attribute(m, "name") #--- Vertex 이름 get.vertex.attribute(m, "AGE") #--- Vertex attribute get.vertex.attribute(m, "TENURE") #--- Vertex attribute get.vertex.attribute(m, "LEVEL") #--- Vertex attribute get.vertex.attribute(m, "DEPT") #--- Vertex attribute #--- vertex 크기 : V(m)$size : vertex.size #--- vertex 색상 : V(m)$color : vertex.color #--- vertex 프레임 : V(m)$frame : vertex.frame #--- vertex 프레임 색상 : V(m)$frame.color : vertex.frame.color #--- vertex 모양 : V(m)$shape : vertex.shape #--- vertex 라벨 : V(m)$label : vertex.label #--- vertex 라벨 폰트 : V(m)$label.font : vertex.label.font #--- vertex 폰트 family : V(m)$label.family : vertex.label.family #--- vertex 라벨 크기 : V(m)$label.cex : vertex.label.cex #--- vertex 라벨 distance : V(m)$dist : vertex.label.dist #--- vertex 라벨 색상 : V(m)$label.color : vertex.label.color ecount(m) #--- Edge 개수 E(m) #--- Edge get.edge.attribute(m, "advice_tie") #--- Edge attribute get.edge.attribute(m, "friendship_tie") #--- Edge attribute get.edge.attribute(m, "reports_to_tie") #--- Edge attribute get.edge.ids(m, c(20, 18, 21, 18)) #--- 20 -> 18, 21 -> 18인 edge ID 반환 #--- edge 색상 : E(m)$color : edge.color #--- edge 길이 : E(m)$width : edge.arrow.width #--- edge 화살표 크기 : E(m)$arrow.size : edge.arrow.size #--- edge 화살표 길이 : E(m)$arrow.width : edge.arrow.width #--- edge 타입 : E(m)$lty : edge.lty #--- edge 라벨 : E(m)$label : edge.label #--- edge 라벨 폰트 : E(m)$label.font : edge.label.font #--- edge 폰트 family : E(m)$label.family : edge.label.family #--- edge 라벨 크기 : E(m)$label.cex : edge.label.cex #--- edge 라벨 색상 : E(m)$label.color : edge.label.color #write.graph(m, file = "sns.txt", format = "pajek") #--- 그래프를 파일로 저장 ###----------------------------------------------------------------------------- ### 그래프 시각화 (layouts <- layout.fruchterman.reingold(m)) #--- Fruchterman-Reingold Layout plot(m, main = "Krackhardt High-Tech Managers", edge.arrow.size = .05) #--- 매번 그래프가 변경 plot(m, layout = layouts, main = "Krackhardt High-Tech Managers", edge.arrow.size = .05) #--- DEPT별로 vertex 색상 지정 (vcolors <- get.vertex.attribute(m, "DEPT")) vcolors[vcolors == 0] <- "Black" vcolors[vcolors == 1] <- "Red" vcolors[vcolors == 2] <- "Blue" vcolors[vcolors == 3] <- "Yellow" vcolors[vcolors == 4] <- "Green" vcolors plot(m, layout = layouts, main = "Krackhardt High-Tech Managers", vertex.color = vcolors, vertex.label = NA, edge.arrow.size = .05) plot(m, layout = layouts, main = "Krackhardt High-Tech Managers", vertex.color = vcolors, edge.arrow.size = .05) #--- TENURE로 vertex 크기 지정 (vsizes <- get.vertex.attribute(m, "TENURE")) plot(m, layout = layouts, main = "Krackhardt High-Tech Managers", vertex.color = vcolors, vertex.size = vsizes, edge.arrow.size = .05) #--- edge 색상 지정 (colorStr <- c(rgb(1, 0, 0, .5), rgb(0, 0, 1, .5), rgb(0, 0, 0, .5))) #--- rgb : red, green, blue, alpha (투명도) (ecolors <- 1:length(E(m))) ecolors[E(m)$advice_tie == 1] <- colorStr[1] ecolors[E(m)$friendship_tie == 1] <- colorStr[2] ecolors[E(m)$reports_to_tie == 1] <- colorStr[3] ecolors plot(m, layout = layouts, main = "Krackhardt High-Tech Managers", vertex.color = vcolors, vertex.size = vsizes, edge.color = ecolors, edge.arrow.size = .05) legend(1, 1.25, legend = c("Advice", "Friendship", "Reports To"), #--- 범례 표시 col = colorStr, lty = 1, cex = .7) rm(colorStr) #--- V(m)과 E(m)의 속성 지정 방식으로 그래프 표시 plot(m, layout = layouts, main = "Krackhardt High-Tech Managers") (V(m)$size <- vsizes) (E(m)$color <- ecolors) (E(m)$arrow.size <- .05) plot(m, layout = layouts, main = "Krackhardt High-Tech Managers", vertex.color = vcolors) rm(list = c("vsizes", "ecolors")) ###----------------------------------------------------------------------------- ### 그래프 가공 #--- advice_tie에 값이 있는 것만 추출 (mAdvice <- delete.edges(m, E(m)[get.edge.attribute(m, name = "advice_tie") == 0])) plot(mAdvice, layout = layouts, main = "Krackhardt High-Tech Managers", vertex.color = vcolors) #--- 다른 vertex와 연결되지 않은 vertex 삭제 (mAdviceNo <- delete.vertices(mAdvice, V(mAdvice)[degree(mAdvice) == 0])) plot(mAdviceNo, layout = layouts, main = "Krackhardt High-Tech Managers", vertex.color = vcolors) (mFriendship <- delete.edges(m, E(m)[get.edge.attribute(m, name = "friendship_tie") == 0])) plot(mFriendship, layout = layouts, main = "Krackhardt High-Tech Managers", vertex.color = vcolors) (mReport <- delete.edges(m, E(m)[get.edge.attribute(m, name = "reports_to_tie") == 0])) plot(mReport, layout = layouts, main = "Krackhardt High-Tech Managers", vertex.color = vcolors) ###----------------------------------------------------------------------------- #--- 매개 중심성 (Betweenness centrality) : 한 노드가 연결망 내의 #--- 다른 노드들 사이의 최다 경로 위에 위치할수록 그 노드의 중심성이 높다. (m1 <- edge.betweenness.community(m)) #--- 매개 중심성 계산 plot(as.dendrogram(m1)) #--- 계층적 군집 rm(m1) ###----------------------------------------------------------------------------- #--- community detection : walktrap과 edge-betweenness 방법 #--- steps : random walks의 길이 #--- modularity = TRUE : modularity scores를 결과에 포함 (m1 <- walktrap.community(m, steps = 200, modularity = TRUE)) plot(as.dendrogram(m1, use.modularity = TRUE)) #--- 계층적 군집 m1$modularity rm(m1) ###----------------------------------------------------------------------------- #--- 연결정도 중심성 (Degree centrality) : 한 점에 직접적으로 연결된 점들의 합 (deg_full_in <- degree(m, mode = "in")) #--- indegree 계산 (deg_full_out <- degree(m, mode = "out")) #--- outdegree 계산 (deg_advice_in <- degree(mAdvice, mode = "in")) (deg_advice_out <- degree(mAdvice, mode = "out")) (deg_friendship_in <- degree(mFriendship, mode = "in")) (deg_friendship_out <- degree(mFriendship, mode = "out")) (deg_reports_to_in <- degree(mReport, mode = "in")) (deg_reports_to_out <- degree(mReport, mode = "out")) ###----------------------------------------------------------------------------- #--- 근접 중심성 (Closeness centrality) : 친밀감, shortest.paths의 역 #--- 노드 수 / 최단거리합 (m1 <- closeness(m)) (m1.score <- round((m1 - min(m1)) * length(m1) / max(m1)) + 1) (m1.colors <- rev(heat.colors(max(m1.score)))) plot(m1, col = m1.colors[m1.score]) rm(m1, m1.score, m1.colors) ###----------------------------------------------------------------------------- #--- 근접 중심성 (Closeness centrality) : 한 노드로부터 다른 노드에 도달하기까지 필요한 최소 단계의 합 #--- 최단거리합 / 노드 수 (sp_full_in <- shortest.paths(m, mode = "in")) #--- 노드간 짧은 거리 표시 (sp_full_out <- shortest.paths(m, mode = "out")) #--- 노드간 짧은 거리 표시 (sp_advice_in <- shortest.paths(mAdvice, mode = "in")) (sp_advice_out <- shortest.paths(mAdvice, mode = "out")) (sp_friendship_in <- shortest.paths(mFriendship, mode = "in")) (sp_friendship_out <- shortest.paths(mFriendship, mode = "out")) (sp_reports_to_in <- shortest.paths(mReport, mode = "in")) (sp_reports_to_out <- shortest.paths(mReport, mode = "out")) ###----------------------------------------------------------------------------- #--- matrix에서 행 vertex에서 열 vertex로 연결이 있으면 1을 설정 reachability <- function(m, mode) { reach_mat <- matrix(nrow = vcount(m), ncol = vcount(m)) for (idx in 1:vcount(m)) { reach_mat[idx, ] <- 0 # reaches <- subcomponent(m, idx, mode = mode) #--- 특정 vertex와 연결된 버텍스 집합을 반환 reaches <- subcomponent(m, idx, mode = mode)[2:(degree(m, mode = mode)[idx] + 1)] for (pos in 1:(length(reaches))) { reach_mat[idx, reaches[pos]] <- 1 } } return(reach_mat) } (reach_full_in <- reachability(m, "in")) (reach_full_out <- reachability(m, "out")) (reach_advice_in <- reachability(mAdvice, "in")) (reach_advice_out <- reachability(mAdvice, "out")) (reach_friendship_in <- reachability(mFriendship, "in")) (reach_friendship_out <- reachability(mFriendship, "out")) (reach_reports_to_in <- reachability(mReport, "in")) (reach_reports_to_out <- reachability(mReport, "out"))
Visualization
graphics
#--- 그래프의 공통 Parameter #--- main : 제목 #--- xlab, ylab : X축, Y축 이름 #--- xlim, ylim : X축, Y축 값의 범위 #--- type : p. 점, l. 라인, s. 라인, o. 점과 선, b. 점과 선, n. 빈 화면 표시 #--- col : 색상 (색상명 또는 "#FF0000" (RGB 코드)) #--- col.lab, col.axis : 레이블 색상, 축 색상 #--- pch : 점의 모양 #--- axes : FALSE - 축을 표시하지 않음 (data <- data.frame(y = iris$Species, y1 = iris$Sepal.Length, y2 = iris$Sepal.Width, y3 = iris$Petal.Length, x = iris$Petal.Width)) (idx <- sample(2, nrow(data), replace = TRUE, prob = c(0.7, 0.3))) (data <- data[idx == 1, ]) #--- 랜덤하게 샘플 추출 rm(idx) hist(data$x, freq = T, breaks = 10) #--- 히스토그램 hist(data$x, freq = F, breaks = 10) #--- 밀도 히스토그램 lines(density(data$x)) #--- 밀도 그래프 추가 plot(density(data$x)) #--- 밀도 그래프 plot(data$x, type = "l") #--- 선 그래프 plot(data$x, type = "s") #--- 선 그래프 plot(data$x, data$y1) #--- 산점도 plot(y1 ~ x, data = data) #--- 산점도 plot(x ~ y1 + y2 + y3, data = data) #--- 산점도 plot(~ y1 + y2 + y3, data = data) #--- 산점도 행렬 pairs(~ y1 + y2 + y3, data = data) #--- 산점도 행렬 library(caret) featurePlot(data[, 2:4], data$y, "ellipse") #--- 산점도 행렬 plot(data$y) #--- 막대 그래프 barplot(tapply(data$x, data$y, mean)) #--- 막대 그래프 plot(data$y, data$x) #--- 박스 그래프 boxplot(x ~ y, data = data, notch = F) #--- 박스 그래프 boxplot(x ~ y, data = data, notch = T) #--- 박스 그래프 boxplot(data[, 2:4]) #--- 박스 그래프 plot(y ~ y1 + y2 + y3, data = data) #--- 모자이크 플롯 (data <- data[sort(data$y1, index.return = TRUE)$ix, ]) #--- y1을 기준으로 데이터 정렬 plot(data$y1, data$y2, #--- 산점도 (빈화면 표시) main="붓꽃의 3가지 종", xlab="꽃받침 길이", ylab="꽃받침 넓이", pch=20, cex=1, col="yellowgreen", col.axis="green", col.lab="blue", xlim=c(4, 8), ylim=c(1, 5), type="n") points(data$y1, data$y2, #--- 점 추가 pch="+", cex=1, col="green") lines(data$y1, data$y2, col="blue") #--- 선 추가 lines(lowess(data$y1, data$y2)) #--- 회귀 분석선 추가 abline(h=mean(data$y2), lty=2, col="blue") #--- Y축 평균 (가로선) abline(v=mean(data$y1), lty=2, col="green") #--- X축 평균 (세로선) curve(sin(5 * x) + 3, 4, 8, n = 100, add=T) #--- 곡선을 추가 polygon(data$y1, data$y2) #--- 다각형을 추가 text(data$y1, data$y2, data$x, pos=4) #--- 문자열 추가 legend("topleft", legend=c("꽃받침 넓이"), #--- 범례 표시 pch=c(43), col=c("green"), bg="gray")
다중축
par(mar = c(5, 12, 4, 4) + 0.1) #--- 그래프에 여백 지정 plot(data$x, data$y1, pch=20, col="green", xlim=c(0, 3), ylim=c(4, 8), main = "", xlab = "", ylab = "", axes = FALSE) axis(1, pretty(range(data$x), 10)) #--- x축 추가 mtext(text = "x", side = 1, line = 2) #--- X축에 라벨 추가 axis(2, ylim = c(0, max(data$y1)), line = 0) #--- y축 추가 mtext(2, text = "y1", line = 2) #--- y축에 라벨 추가 par(new = T) #--- 원래 그래프에 새 그래프 추가 plot(data$x, data$y2, pch=21, col="blue", xlim=c(0, 3), ylim=c(2, 5), main = "", xlab = "", ylab = "", axes = FALSE) axis(2, ylim = c(0, max(data$y2)), line = 3.5) #--- y축 추가 mtext(2, text = "y2", line = 5.5) #--- y축에 라벨 추가 par(new = T) #--- 원래 그래프에 새 그래프 추가 plot(data$x, data$y3, pch=20, col="red", xlim=c(0, 3), ylim=c(1, 7), main = "", xlab = "", ylab = "", axes = FALSE) axis(2, ylim = c(0, max(data$y3)), line = 7) #--- y축 추가 mtext(2, text = "y3", line = 9) #--- y축에 라벨 추가 legend("topleft", legend = c("y1", "y2", "y3"), pch = c(20, 21, 22), col = c("green", "blue", "red"), bg = "grey") title(main = "산점도", sub = "x별 y1, y2, y3의 분포") par(mar = c(0, 0, 0, 0) + 4) #--- 그래프에 여백 지정
qplot
- ggplot2에서 시각화 단계
- qplot 주요 arguments
- x, y : x, y 좌표의 값
- data : 데이터
- geom : 챠트의 형태
- auto : 자동으로 선택
- point : 산점도, 점 그래프
- smooth : 회귀선 표시
- line : 선 그래프 (방향 : 왼쪽 -> 오른쪽)
- path : 선 그래프 (무방향)
- boxplot : 박스 챠트
- jitter :
- histogram : 히스토그램
- density : 밀도 그래프
- bar : 막대 그래프, 도수분포표
- facets : 챠트 분할
- main : 제목
- xlab, ylab : X축, Y축 이름
- xlim, ylim : X축, Y축 값의 범위
- binwidth : 구간의 넓이
- colour, color : 색상 분류 기준 (선/점 색)
- shape : 점의 모양
- alpah : 투명도, 작을수록 투명함
- fill : 채우는 색
- 예약어
- ..count.. : 관측 개수
- ..ncount.. : (0, 1)인 관측 개수
- ..density.. : 밀도
- ..ndensity.. : (0, 1)인 밀도
- qplot 기타 arguments
- weight : 가중치 적용
- method
- loess : smooth용 회귀분석
- gam : 데이터로 자유도 계산한 lm
- lm : 회귀분석
- formula : 수식
- se = FALSE : smooth에서 편차 제거
- span : smooth와 같이 사용, 0~1
- log : 로그 적용 (x, y, xy)
- asp : y/x 비율
- margins : 마진
- stat : 통계
- position :
ggplot2
- GEOM : geometric object, 기하 객체
- ggplot() : 데이터와 미적속성을 매핑하는 메타데이터 생성
- ggplot(~, aes(x=~, y=~, colour=~, group=~))
- 추가적으로 하나 이상의 레이어가 생성이 되어야 챠트가 생성됨
- + 로 레이어를 추가할 경우, 미적 속성은 +뒤의 레이어로 상속됨
ggplot(data = diamonds, aes(x=carat, y=price)) + geom_point(aes(colour=clarity)) + geom_smooth() ggplot(data = diamonds, aes(x=carat, y=price, colour=clarity) + geom_point() + geom_smooth()
- data : 데이터
- graph %+% dataFrame : 그래프의 데이터 교체
- aes(~) : Aesthetic attributes, 미적 속성 (데이터와 매핑됨)
- x, y : x, y 좌표의 값
- colour : 색상 분류 기준 (선/점 색)
- shape : 점의 모양 분류 기준, NA. 표시하지 않음
- size : 점의 크기, 선의 굵기 (1. default)
- alpha : 투명도, 작을수록 투명함
- fill : 색상 분류 기준 (채워넣는 색)
- group : 그룹 지정
- order : 누적 데이터 표시시 누적되는 순서 변경, order = desc(~)
- geom_point() : 산점도, 점 그래프
- geom_smooth() : 회귀선 표시
- stat_smooth() : smooth 추가
- binwidth() : 한칸당 간격
- geom_line() : 선 그래프 (방향 : 왼쪽 오른쪽)
- geom_histogram() : 히스토그램
- geom_density() : 밀도 그래프
- geom_bar() : 막대 그래프, 도수분포표
- aes(~) : Aesthetic attributes, 미적 속성
- binwidth : 구간의 넓이, X축 간격
- colour : 색상 분류 기준 (선/점 색)
- shape : 점의 모양 분류 기준, NA. 표시하지 않음
- size : 점의 크기, 선의 굵기 (1. default)
- alpha : 투명도, 작을수록 투명함
- fill : 채우는 색
- linetype : 선의 모양 (2, "dotdash")
- method : lm
- position : 그룹항목을 누적 표시, dodge (그룹 항목을 개별 표시), fill
- geom_pointrange() : 값과 범위 표시
- ymin, ymax : pointrange()에서 사용할 최소값과 최대값
- stat_bin2d() : 격자 형태의 그래프
- bins : stat_bin2d()에서 격자의 크기
- stat_bin2d(bins=25, colour="grey50")
- stat_bin() : 그래프 지정
- geom : bar, area, point, tile
- facet_grid() : 챠트 분할
- facet_wrap() : 챠트 분할
- nrow : 한 행에 표시할 챠트의 수
- xlab(), ylab() : X축, Y축 이름
- coord_cartesian()
- xlim, ylim : X축, Y축 값의 범위
- scale_x_continuous() : X축의 범위를 지정
- limits
- scale_y_continuous() : Y축의 범위를 지정
- limits
- sacle_x_date(breaks="2 years", labels=date_format("%Y-%m")) : 날자축 지정
- guides()
- colour = "colourbar" : 색상 범례 사용
- colour = guide_legend() : 이산형 범례, 작은값 큰값
- colour = guide_legend(reverse = TRUE) : 이산형 범례, 큰값 작은값
- scale_color_hue() : 색상 범례 제목 지정
- scale_colour_continuous() : 색상 범례
- breaks : break point 지정
- scale_shape_identity() : shape에 주어진 연속값을 불연속 값으로 매핑
- last_plot() : 마지막으로 그린 그래프
- coord_flip() : 가로, 세로 변경
- scale_x_reverse() : X축 값의 순서를 반대로 설정
- scale_y_reverse() : Y축 값의 순서를 반대로 설정
- opts() : 테마(theme) 상세 설정
- opts(axis.text.x=theme_text(angle=90, hjust=1)) : X축 라벨 90 회전
- geom_hline() : 가로선
- annotate() : 사각형 상자
- annotate("rect", xmin = 2, xmax = 3.5, ymin = 2, ymax = 25, fill = "dark grey", alpha = 0.5)
- 예약어
- ..count.. : 관측 개수
- ..ncount.. : (0, 1)인 관측 개수
- ..density.. : 밀도
- ..ndensity.. : (0, 1)인 밀도
- ggsave("~.png") : 챠트 저장
Java 연동
- rJava 설치
### Sys.setenv(JAVA_HOME="C:/appl/jre170") install.packages("rJava") install.packages("JavaGD")
- 환경변수 설정
- R_HOME
- Path에 URL 추가 : %R_HOME%\bin\x64;%R_HOME%\library\rJava\jri\x64
- Java 프로그램
- $R_HOME/library/rJava/jri/*.jar 파일을 Java의 classpath에 추가
package MiD.R import org.rosuda.JRI.*; public class RMain { public static void main(String arg[]) { String[] Rargs = { "--vanilla " }; Rengine ren = new Rengine(Rargs, false, null); if (!ren.waitForR()) { System.out.println("Cannot Load R"); return; } REXP rn = ren.eval("rnorm(10)"); double[] rnd = rn.asDoubleArray(); for (int i = 0 ; i < rnd.length ; i++) { System.out.println(rnd[i]); } ren.end(); } }
- JavaGD_~.zip 파일에 포함된 javaGD.jar를 classpath에 추가
- 애플릿 상에서 그래프 표시
package MiD.R; import javax.swing.JFrame; import org.rosuda.javaGD.GDCanvas; import org.rosuda.javaGD.GDInterface; public class MiDJavaGD extends GDInterface { public JFrame f; public void gdOpen(double w, double h) { f = new JFrame("JavaGD"); c = new GDCanvas(w, h); f.add((GDCanvas) c); f.pack(); f.setVisible(true); f.setTitle("Naked R plot"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } public class RMain { public static void main(String[] args) { Rengine engine = new Rengine(new String[] {"--vanilla"}, false, null); engine.eval("library(JavaGD)"); engine.eval("Sys.putenv('JAVAGD_CLASS_NAME'='MiDJavaGD')"); engine.eval("JavaGD()"); engine.eval("plot(rnorm(100))"); } }
- 그래프를 저장
public class RMain { public static void main(String[] args) { Rengine engine = new Rengine(new String[] {"--vanilla"}, false, null); if (!engine.waitForR()) { System.out.println("Cannot Load R"); return; } engine.eval("png(filename=\"c:/aaa/test3.png\")"); engine.eval("plot(rnorm(100))"); engine.eval("dev.off()"); engine.end(); } }
관리자 매뉴얼
- rJava 로딩시 오류 발생
Error : .onLoad가 loadNamespace()에서 'rJava'때문에 실패했습니다: 호출: inDL(x, as.logical(local), as.logical(now), ...) 에러: unable to load shared object 'C:/Users/ghkim/Documents/R/win-library/3.1/rJava/libs/x64/rJava.dll': LoadLibrary failure: 지정된 모듈을 찾을 수 없습니다.
- 원인 : JDK 1.8 설치시 오류 발생
- 조치 : 작업 폴더에 있는 .Rprofile 파일에 아래 코드 추가 합니다.
Sys.setenv(JAVA_HOME="C:/appl/jre170")
데이터셋
공공 데이터셋
온라인교육
- 데이터 사이언티스트의 현실과 미래
- 빅데이터 분석 과정 (R) : 공개 강좌
- 빅데이터 기술 과정 (Hadoop) : 공개 강좌
- 데이터 분석 전문가로 가는 길
참고 문헌
- RHive
- Rhipe : http://ml.stat.purdue.edu/rhafen/rhipe/
- RStudio
- Protovis : http://mbostock.github.io/protovis/
- GNUplot
- R 추천 도서
- An Introduction to R
- R Cookbook - Paul Teetor
- Beginning R
- R in a Nutshell
- R Graphics Cookbook
- The Art of R Programming
- 통계 추천 도서
- Head First Statistics - Dawn Griffiths
- Statistics for the Behavioural Sciences - Frederick J Gravetter 외