작성자: admin 작성일시: 2016-10-01 10:56:06 조회수: 275 다운로드: 35
카테고리: R 태그목록:

R로 데이터의 분포 살펴보기

분포

데이터의 수가 적으면 데이터의 값을 하나 하나 살펴볼 수 있지만 데이터의 수가 많다면 데이터가 주로 어떤 값 근처에 어떤 모양으로 모여 있는지 전반적인 형태를 살펴보는 수밖에 없다. 데이터 값의 전반적인 형태를 데이터의 분포(distribution)라고 한다.

주로 다음과 같은 방법으로 일차원 데이터의 분포를 살펴본다.

  • 기술 통계 (descriptive statistics)
  • 히스토그램 (histogram)
  • 커널 밀도 (kernel density)

기술 통계

기술 통계(descriptive statistics)는 데이터 분포의 특징을 대표할 수 있는 몇가지 숫자를 계산하여 이 숫자들로부터 데이터의 분포를 추측하는 방법이다. 흔히 일반인들이 통계라고 부르는 것이 바로 기술 통계를 말한다.

데이터의 분포의 특징을 대표하는 값들로는

  • 데이터의 숫자 (count)
  • 평균 (mean, average)
  • 분산 (variance)
  • 표준 편차 (standard deviation)
  • 최댓값 (maximum)
  • 최솟값 (minimum)
  • 중앙값 (median)
  • 사분위수 (quartile)

등이 많이 사용된다.

데이터가 $x_1, x_2, \cdots, x_N$ 일때, 평균은 보통 $\bar{x}$라고 표시하며 다음과 같이 계산된다. $$ \bar{x} = \dfrac{1}{N}\sum_{i=1}^N x_i $$

분산은 보통 $s^2$이라고 표시하며 계산된 평균 $\bar{x}$를 이용하여 다음과 같이 계산된다. $$ s^2 = \dfrac{1}{N}\sum_{i=1}^N (x_i - \bar{x})^2 $$

표준 편차는 보통 $s$이라고 표시하며 분산의 제곱근 값이다. $$ s = \sqrt{s^2} $$

최댓값은 데이터 중에서 가장 큰 값을, 최솟값을 가장 작은 값을 의미한다.

중앙값은 데이터를 크기대로 정렬하였을 때 가장 가운데에 있는 수를 말한다. 만약 데이터의 수가 짝수이면 보통 중앙의 두 수의 평균을 사용한다.

사분위수(quartile)는 데이터를 크기대로 정렬하였을 때 1/4, 2/4, 3/4 위치에 있는 수를 말한다. 1/4의 위치란 전체 데이터의 수가 만약 100개이면 25번째 순서를 말한다. 따라서 2사분위수는 중앙값과 같다.

때로는 위치를 1/100 단위로 나눈 백분위수(percentile)을 사용하기도 한다. 1사분위수는 25% 백분위수와 같다.

예를 들어 다음과 같은 데이터가 있다.

In [43]:
x <- c( 18,   5,  10,  23,  19,  -8,  10,   0,   0,   5,   2,  15,   8,
         2,   5,   4,  15,  -1,   4,  -7, -24,   7,   9,  -6,  23, -13,
         1,   0,  16,  15,   2,   4,  -7, -18,  -2,   2,  13,  13,  -2,
        -2,  -9, -13, -16,  20,  -4,  -3, -11,   8, -15,  -1,  -7,   4,
        -4, -10,   0,   5,   1,   4,  -5,  -2,  -5,  -2,  -7, -16,   2,
        -3, -15,   5,  -8,   1,   8,   2,  12, -11,   5,  -5,  -7,  -4)

이 데이터의 기술 통계값을 구하는 명령어는 다음과 같다.

In [44]:
length(x)
78
In [45]:
mean(x)
0.692307692307692
In [46]:
var(x)
97.3066933066933
In [47]:
sd(x)
9.86441550760578
In [48]:
max(x)
23
In [49]:
min(x)
-24
In [50]:
median(x)
0.5
In [51]:
quantile(x, 0.25)
25%: -5.75
In [52]:
quantile(x, 0.50)
50%: 0.5
In [53]:
quantile(x, 0.75)
75%: 5

R은 기술 통계값을 한번에 계산하는summary 명령도 제공한다.

In [54]:
summary(x)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
-24.0000  -5.7500   0.5000   0.6923   5.0000  23.0000 

히스토그램

히스토그램은 자료 값이 가질 수 있는 범위를 몇 개의 구간으로 나누고 각 구간에 해당하는 값의 숫자 혹은 상대적 빈도를 계산하는 방법이다.

R에서 히스토그램을 구하거나 그리기 위해서는 hist 명령을 사용한다. breaks 인수로 구간의 수를 조정할 수도 있다.

hist 함수의 반환값은 다음과 같은 속성들을 가진다.

  • breaks : 구간
  • counts : 구간내의 데이터 숫자

위의 자료에 대해 히스토그램을 그리면 아래와 같다.

In [55]:
h <- hist(x, breaks=10)
In [56]:
h$breaks
  1. -25
  2. -20
  3. -15
  4. -10
  5. -5
  6. 0
  7. 5
  8. 10
  9. 15
  10. 20
  11. 25
In [57]:
h$counts
  1. 1
  2. 5
  3. 5
  4. 12
  5. 16
  6. 20
  7. 7
  8. 6
  9. 4
  10. 2

커널 밀도

앞의 그림에서 곡선으로 나타난 것이 커널 밀도이다. 커널 밀도는 커널이라고 하는 특정 구간의 분포를 묘사하는 함수의 합으로 이루어진다고 가정하여 전체 분포를 묘사하는 방법이다. 커널 밀도를 사용하면 분포의 전체 모양을 파악하기가 더 쉽다.

In [58]:
rec <- function(x) (abs(x) < 1) * 0.5
tri <- function(x) (abs(x) < 1) * (1 - abs(x))
gauss <- function(x) 1/sqrt(2*pi) * exp(-(x^2)/2)
xx <- seq(from = -3, to = 3, by = 0.001)
plot(xx, rec(xx), type = "l", ylim = c(0,1), ylab = expression(K(x)), col="red")
lines(xx, tri(xx), col="blue")
lines(xx, gauss(xx), col="darkgreen")
legend(-3, 0.8, legend = c("Rectangular", "Triangular", "Gaussian"), lty = 1, title = "kernel functions", bty = "n")

R 에서 커널 밀도를 그리려면 density 명령을 사용한다.

In [59]:
plot(density(x))
In [66]:
n <- length(x)
xgrid <- seq(from = min(x) - 1, to = max(x) + 1, by = 0.01)
h <- 3.021
bumps <- sapply(x, function(a) 1e3 * gauss((xgrid - a)/h)/(n * h))
plot(xgrid, rowSums(bumps), ylab = expression(hat(f)(x)), type = "l", xlab = "x", lwd = 2)
axis(4)
par(new=T)
hist(x, xaxt='n', yaxt='n', main="", xlab="", ylab="")
rug(x, lwd = 2)
out <- apply(bumps, 2, function(b) lines(xgrid, b))

다차원 데이터 분포를 묘사하는 경우

다차원 데이터 분포는 순서가 정해진 여러개의 일차원 데이터가 있는 것과 같다.

만약 2차원 데이터이고 각 데이터가 모두 연속적인 실수값이라면 스캐터 플롯(scatter plot)을 사용하면 된다. 스캐터 플롯을 그리기 위해서는 plot(type="p") 명령을 사용한다.

다음 데이터는 붓꽃의 꽃잎의 길이, 꽃잎의 폭, 꽃받침의 길이, 꽃받침의 폭, 그리고 종(species)을 나타낸 데이터이다.

In [71]:
head(iris)
Sepal.LengthSepal.WidthPetal.LengthPetal.WidthSpecies
5.1 3.5 1.4 0.2 setosa
4.9 3.0 1.4 0.2 setosa
4.7 3.2 1.3 0.2 setosa
4.6 3.1 1.5 0.2 setosa
5.0 3.6 1.4 0.2 setosa
5.4 3.9 1.7 0.4 setosa
In [80]:
plot(iris$Sepal.Length, iris$Sepal.Width, type="p", xlab="Sepal.Length", ylab="Sepal.Width", col=iris$Species)

ggplot2 패키지를 사용하면 좀더 보기좋은 형태로 만들 수 있다.

In [70]:
library(ggplot2)
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point(aes(color=Species))

만약 3차원 이상의 데이터라면 pairs 명령을 사용한다. pairplot은 그리도(grid) 형태로 각 집합의 조합에 대해 히스토그램과 스캐터 플롯을 그린다.

In [79]:
pairs(iris[,1:4], col=iris$Species)

GGally 패키지에서는 ggpairs 명령을 사용한다.

In [87]:
library(GGally)
ggpairs(iris, mapping = aes(color = Species))
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

만약 모든 값이 카테고리(category) 값이면 heatmap 차트를 사용한다.

In [88]:
library(reshape2)
library(ggplot2)
dat <- matrix(rnorm(100, 3, 1), ncol=10)
names(dat) <- paste("X", 1:10)
dat2 <- melt(dat, id.var = "X1")
ggplot(dat2, aes(as.factor(Var1), Var2, group=Var2)) +
    geom_tile(aes(fill = value)) + 
    geom_text(aes(fill = dat2$value, label = round(dat2$value, 1))) +
    scale_fill_gradient(low = "white", high = "red")

질문/덧글

아직 질문이나 덧글이 없습니다. 첫번째 글을 남겨주세요!