일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 핵개발
- 자기관리
- 비율
- 산입 범위
- t검정
- 찬물샤워
- 티모시페리스
- 핵 개발
- 아인슈타인
- R 기초
- 최저 시급
- 유닛테스트
- R 프로그래밍
- 비선형성
- 동전 던지기
- R4DS
- 조던피더슨
- t-test
- 큰수의 법칙
- 성악설
- 비행기 추락
- 선형성
- 멘탈관리
- 산입범위
- 통계 오류
- 최저시급 개정안
- 통계오류
- 수학적 사고
- 이기적 유전자
- 인터스텔라
- Today
- Total
public bigdata
[datacamp] 효율적인 R 코드 작성 본문
<benchmark>
1. R 버전 확인
> version
_
platform x86_64-w64-mingw32
arch x86_64
os mingw32
system x86_64, mingw32
status
major 3
minor 6.3
year 2020
month 02
day 29
svn rev 77875
language R
version.string R version 3.6.3 (2020-02-29)
nickname Holding the Windsock
> version$major
[1] "3"
> version$minor
[1] "6.3"
version이라고 실행만 하면 된다.
2. read.csv VS read.RDS
> system.time(read.csv('movies.csv'))
user system elapsed
0.430 0.000 0.431
>
> # How long does it take to read movies from RDS?
> system.time(readRDS('movies.rds'))
user system elapsed
0.045 0.000 0.045
3. system.time
- user : time is the cpu time charged for the execution of user instructions.
- system : time is the cpu time charged for execution by the system on behalf of the calling process
- elapsed time is approximately the sum of user and system, this is the number we typically care about.
system.time(apply(iris[, -5], 1, sum))
4. library(microbehchmark)
> microbenchmark(apply(iris[, -5], 1, sum), times = 10)
Unit: microseconds
expr min lq mean median uq max neval
apply(iris[, -5], 1, sum) 231.8 232.8 249.92 237.65 242.2 354.8 10
times 인자를 통해 여러번 반복한 데이터로 부터 통계치를 산출해준다.
5. RAM, CPU 스펙 확인
library(benchmarkme)
ram <- get_ram()
ram
16.3 GB
# Assign the variable cpu to the cpu specs
cpu <- get_cpu()
cpu
$vendor_id
[1] "GenuineIntel"
$model_name
[1] "Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz"
$no_of_cores
[1] 4
6. 파일 읽고 쓰는데 걸리는 시간
# Load the package
library("benchmarkme")
# Run the io benchmark
res <- benchmark_io(runs = 1, size = 5)
# Plot the results
plot(res)
- runs : n번씩 반복
- size : 테스트할 데이터 사이즈(MB)
<Efficient Base R>
7. slow code example
> n <- 30000
> # Slow code
> growing <- function(n) {
+ x <- NULL
+ for(i in 1:n)
+ x <- c(x, rnorm(1))
+ x
+ }
>
> res_grow <- system.time(growing(n = 30000))
> res_grow
사용자 시스템 elapsed
1.2 0.0 1.2
8. fast code example
> n <- 30000
> # Fast code
> pre_allocate <- function(n) {
+ x <- numeric(n) # Pre-allocate
+ for(i in 1:n)
+ x[i] <- rnorm(1)
+ x
+ }
> n <- 30000
> system.time(res_allocate <- pre_allocate(n))
사용자 시스템 elapsed
0.03 0.00 0.03
9. R은 loop를 여러번 실행하는 것보다. vector 연산이 훨씬 빠르다.
10. R에서는 데이터프레임에 대한 인덱싱보다 매트릭스에 대한 인덱싱이 훨씬 빠르다.
## 열선택
> data(iris)
> iris_df <- iris
> iris_mat <- as.matrix(iris)
> microbenchmark(iris_df[, 1], iris_mat[, 1])
Unit: microseconds
expr min lq mean median uq max neval
iris_df[, 1] 5.5 5.7 6.372 6.1 6.3 35.6 100
iris_mat[, 1] 1.1 1.3 1.598 1.6 1.7 7.6 100
## 행선택
> data(iris)
> iris_df <- iris
> iris_mat <- as.matrix(iris)
> microbenchmark(iris_df[1, ], iris_mat[1, ])
Unit: nanoseconds
expr min lq mean median uq max neval
iris_df[1, ] 41301 41951 45107.91 42401 42901 153402 100
iris_mat[1, ] 600 651 1028.00 1101 1201 7902 100
그 중에서도 행 선택의 경우 훨씬 많이 차이가 난다. 컴퓨터의 데이터프레임과 매트릭스의 저장방식이 다르기 때문에 차이가 난다.
<Code Profiling>
11. 코드에서 병목현상이 생기는 곳 알아내기
# Load the data set
data(movies, package = "ggplot2movies")
# Load the profvis pacprkage
library(profvis)
# Profile the following code with the profvis function
profvis({
# Load and select data
comedies <- movies[movies$Comedy == 1, ]
# Plot data of interest
plot(comedies$year, comedies$rating)
# Loess regression line
model <- loess(rating ~ year, data = comedies)
j <- order(comedies$year)
# Add fitted line to the plot
lines(comedies$year[j], model$fitted[j], col = "red")
}) # Remember the closing brackets!
profvis라는 패키지를 이용해 위와 같이 profvis 함수 안에 실행시킬 코드를 {} 중괄호로 감싸 실행하면 어디서 시간이 오래 걸리는지 알 수 있다.
12. && vs &
Python의 and or 처럼 R의 &&, | 은 (False && ~~)인 경우 뒤 코드를 볼 필요가 없기 때문에 바로 결과를 내는 트릭을 사용한다. 그래서 &, | 보다는 속도가 훨씬 빠르다. 그러나 길이가 1인 비교만 가능하다.
<Parallel Programming>
13. R에서 병렬 컴퓨팅을 하는 프로세스
-
Load the package
-
Make a cluster
-
Switch to parSapply
-
stop cluster
## 기본 형태
> # Determine the number of available cores
> detectCores()
[1] 4
>
> # Create a cluster via makeCluster
> cl <- makeCluster(spec = 2)
>
> # Parallelize this code
> parApply(cl, dd, 2, median)
[1] 6.312964e-02 5.311687e-02 1.681104e-02 1.433903e-02 7.064213e-05
[6] 4.117414e-02 7.735636e-02 -5.979659e-02 2.297182e-01 1.100425e-01
>
> # Stop the cluster
> stopCluster(cl)
## Full 형태
play <- function() {
total <- no_of_rolls <- 0
while(total < 10) {
total <- total + sample(1:6, 1)
# If even. Reset to 0
if(total %% 2 == 0) total <- 0
no_of_rolls <- no_of_rolls + 1
}
no_of_rolls
}
# Set the number of games to play
no_of_games <- 1e5
## Time serial version
system.time(serial <- sapply(1:no_of_games, function(i) play()))
## Set up cluster
cl <- makeCluster(spec = 4)
clusterExport(cl, "play")
## Time parallel version
system.time(par <- parSapply(cl, 1:no_of_games, function(i) play()))
## Stop cluster
stopCluster(cl)
위 코드에서 가장 중요한 부분 "## Set up cluster "에서 클러스터를 만들고 clusterExport 함수를 통해서 play를 지정해준다.
cl <- makeCluster(spec = 4)
clusterExport(cl, "play")
이렇게 하는 이유는 parSapply는 독립적인 worker(core)에서 작동이 된다. 각각의 worker는 library, object가 로딩되어 있지 않는 fresh한 R 세션이라고 한다. 그래서 병렬 처리를 하기 위해서는 필요한 library, object를 worker에 전달해줘야 한다. library는 clusterEvalQ함수를 사용해서 전달해주고, object, 함수는 clusterExport로 전달해준다.
기본적으로 clusterExport 설정 시 envir 인자의 default는 .Grobal 환경이다. 그래서 따로 envir 를 설정할 필요 없이 필요한 함수만 전달해주면 된다.
그런데 만약 "parSapply(cl, 1:no_of_games, function(i) play())" 이 코드가 function내에서 실행이 되는 상황이고 함수에 전달된 인자를 찾아서 실행해야 하는 상황인데, envir인자를 default 상태로 실행하면 에러가 난다. 글로벌 환경에서 필요한 값을 찾기 때문이다. 여기서는 function에 전달된 인자들을 전달해야 하므로, 함수 내부의 환경을 참조할 수 있도록 envir = enviroment()라고 작성해줘야 제대로 작동이 된다. 자세한 내용은 더 찾아봐야 한다. R의 환경 관련해서.
14. apply family
- apply -> parApply
- sapply -> parSapply
- lapply -> parLapply
'R programming' 카테고리의 다른 글
dplyr (버전업 + 몰랐던 내용 정리) (0) | 2020.03.27 |
---|---|
flexdashboard 참고자료 (0) | 2020.03.17 |
Machine Learning in the Tidyverse [datacamp 정리] (0) | 2020.02.24 |
R markdown 참고자료 (0) | 2020.01.23 |
R data import(DBI/http data download) - 데이터 캠프 정리 (0) | 2020.01.04 |