※ 해당 내용은 ADP를 준비하며 학습한 내용을 정리한 것 입니다.

 

1. 데이터 탐색

데이터를 분석하기 전에 대략의 데이터의 특성을 파악하고, 데이터에 대한 통찰을 얻기 위해 다각도로 접근한다.

 

  . 기초 데이터 탐색 ( 예시 )

data(iris)
head(iris, 10) # 데이터 앞 10줄만 출력
str(iris) # 데이터 구조 파악
summary(iris) # 데이터의 기초 통계량 출력
cov(iris[,1:4]) # 공분산
cor(iris[,1:4]) # 상관계수

2. 결측값 처리

결측값을 어떻게 처리하느냐에 따라 작업속도가 달라진다.

 

 . 간단한 결측값 제거

  → 해당 방법은 결측값이 포함된 관측치를 모두 제거한다. 결측값이 넓게 분포된 경우 주의가 필요.

y <- c(1,2,3,NA)
is.na(y)

y[complete.cases(y)] # 결측값 제거

y

 

R에서 주로 결측값처리에는 Amelia II, Mice, mistools 등 여러가지 패키지가 활용.

 

이 중 Amelia 패키지를 실습해 보자

 

library(Amelia)

data(freetrade)
head(freetrade)
str(freetrade)

# m = 몇개의 imputation 데이터셋을 만들지 결정하는 값
# ts = 시계열 정보, cs = cross-sectional 정보
# 즉, 아래 모델에서는 연도와 국가를 고려해
# 모든 freetrade 정보를 활용한 결측값에 대한 imputation(대체)가 이루어 짐
a.out <- amelia(freetrade, m=5, ts = "year", cs = "country")
hist(a.out$imputations[[5]]$tariff, col="grey", border="white")
save(a.out, file = "imputation.RData")
write.amelia(obj=a.out, file.stem="outdata")

missmap(freetrade) # 결측값 처리 전

 

#결측값 처리, inputation
freetrade$tariff <- a.out$imputations[[5]]$tariff
missmap(freetrade) # 결측값 처리 후

3. 이상값 검색

 . 이상값 검색의 활용

  ① 전처리를 어떻게 할지를 결정

  ② 부정사용방지 시스템에서 규칙을 발견하는데 사용

 

 . 이상값의 분류

  ① 의도하지 않게 잘못 입력한 경우 ( a1 )

  ② 의도하지 않계 입력되었으나 분석 목적에 부합하지 않아 제거해야하는 경우 ( a2 )

  ③ 의도되지 않은 현상이지만 분석에 포함해야 하는 경우 ( a3 )

  ④ 의도된 이상값인 경우 ( b1 )

 

 . 관련 알고리즘

  → ESD(Extreme Studentized Deviation)

      : 평균으로부터 K*표준편차만큼 떨어져 있는 값을 이상값으로 판단, 일반적으로 K=3으로 한다.

 

  . 상자그림으로 이상값 식별

x <- rnorm(100)
x <- c(x, 19, 28,30) # 이상값 추가
boxplot(x)

 

  . outliers 패키지 사용

library(outliers)
set.seed(1234)
y=rnorm(100)
outlier(y) # 평균과 가장 많이 차이나는 값 출력
outlier(y, opposite=TRUE)
dim(y) = c(20,5) # 행 20 열 5의 행렬 생성
outlier(y) # 각 열의 평균과 가장 차이가 많은 값을 각 열별로 출력

 # 각 열별로 반대 방향으로 열 평균과 가장 차이가 많은 값 출력

outlier(y, opposite = TRUE)
boxplot(y)

※ 해당 내용은 ADP 준비를 위해 데이터 마트 부분을 학습하며 정리한 내용입니다.

 

. 데이터 마이닝에서의 모델링

  → 다양한 분석 기법을 적용해 모델을 개발하는 과정, 데이터 마트를 개발해 놓으면 효율적이고 신속한 모델링 가능.

 

. 데이터 마트

  → 데이터의 한 부분, 특정 사용자가 관심을 갖는 데이터들을 담은 비교적 작은 규모의 데이터 웨어하우스.

 

. [참고] 데이터 웨어하우스와 마트 비교

  → 사용자의 기능 및 제공 범위를 기준으로 구분함.

  → 웨어하우스=전체의 상세 Data / 마트=특정 사용자 대상, 웨어하우스에 있는 일부 Data

 

1. R reshape를 활용한 데이터 마트 개발

① reshape

 

 reshape는 데이터 재정렬을 위한 기법 중 하나, 비견될 수 있는 기법 중 밀집화가 있다.

 

 . [참고] 밀집화

  → 데이터를 축소하고, 재정렬 ( ex) Excel Pivot )

  → 밀집화는 데이터가 간단하게 표시되지만, 원본이 손실되고, reshape는 원본이 유지된다는 점에서 차이가 있다.

 

 . melt() & cast 함수

  → reshape 패키지로 melt(), cast()만을 사용하여 데이터를 재구성 or 밀집화된 Data를 유연하게 생성 가능

  → melt로 데이터를 녹여 유연하게 만든 후 피벗과 비슷한 cast로 모양을 잡아준다고 생각하면 됨.

library(reshape)

names(airquality)
names(airquality) <- tolower(names(airquality)) #소문자 변환

# id에 있는 변수를 기준으로
# 각변수 Variable이란 이름의 데이터로 만듬
# [참고] na.rm = 결측값 제거
aqm <- melt(airquality, id=c("month","day"), na.rm = TRUE)
aqm

# cast를 이용해 엑셀의 Pivoting을 하듯이 자료를 변환

# cast( data, y축~x축~값 )

a <- cast(aqm, day~month~variable)
a

mean을 적용해 평균값을 산출할 수도 있다.

b <- cast(aqm, month~variable, mean) # 월별 평균값 계산
b

|를 이용하여 산출물을 분리해 표시도 가능하다. ( 조회에 적합 )

c <- cast(aqm, month ~ .|variable, mean)
c

margin 함수로 행/열의 소계도 산출 가능

# 행과 열의 소계 산출
d <- cast(aqm, month~variable, mean, margins=c("grand_row", "grand_col"))
d

 

특정 변수만 처리하고자 할 때 subset 옵션을 추가

# 특정변수만 처리하고자 할 때
e <- cast(aqm, month~variable, mean, subset = variable=="ozone")
e

 

range 옵션을 추가하면 min, max를 동시에 표시해 준다

 

# min, max 표시 ( min=_X1 / max=_X2 )
f <- cast(aqm, month~variable, range)
f

 

2. sqldf를 이용한 데이터 분석

sql를 R에서도 사용할 수 있도록 하는 패키지, 단순히 sqldf 괄호 안에 SQL 언어를 입력하여 사용하면 됨.

 

data(iris)
sqldf("select * from iris limit 10") # head와 같은 기능 구현

 

3. plyr : 데이터 분리+처리 후 결합

 

ply 함수와 multi-core 사용 함수를 이용하면 for loop를 간단하고 매우 빠르게 처리 가능

 

ply() 함수는 앞에 두 개 문자를 접두사로 가진다.

 

첫 번째 문자=입력하는 데이터 형태, 두 번째 문자= 출력하는 데이터 형태

 

  [ 접두사(데이터형태) 종류 ]

  가. d = 데이터 프레임 ( data.frame )

  나. a = 배열 ( array )

  다. l = 리스트 ( list )

 

실습에 사용할 Data 생성

set.seed(1) # 난수 고정, 같은 난수를 생성하도록 해줌

# runif( 생성할 난수 개수, 최소값, 최대값)
d = data.frame(year = rep(2012:2014, each=6), count = round(runif(9,0,20)))
d

. ddply을 사용해 데이터 프레임을 입력받아 sd와 mean의 비율인 변동계수 cv 구하기

 → test 결과 Rcpp 패키지도 추가해 주어야 함

library(plyr)
library(Rcpp)

ddply(d, "year", function(x){
  mean.count = mean(x$count)
  sd.count = sd(x$count)
  cv = sd.count/mean.count
  data.frame(cv.count=cv)
})

 

 . transform, summarise 옵션

  → summarise 옵션 = 변수에 명령된 평균이나 합 등을 계산해 줌

  → transform 옵션 = summarise 옵션과 달리 계산에 사용된 변수도 출력

 

ddply(d, "year", summarise, mean.count = mean(count))

ddply(d, "year", transform, total.count = sum(count))

4. 데이터 테이블 ( Data Table )

데이터 테이블은 데이터 프레임과 우사하지만 보다 빠른 그룹화, 순서화, 짧은 문장 지원 측면에서 매력적

 

data.frame과 같은 방법으로 생성되나, 행 번호가 콜론(:)으로 표시

# rnorm(n) 함수는 정규분포에서 n개의 난수 생성
DT <- data.table(x=c("b","b","b","a","a"),v=rnorm(5))
DT

 

기존 data.frame을 data.table 형식으로 변환 가능하다.

CARS <- data.table(cars)

. data.frame과 data.table 차이점

 → 데이터 테이블 = 인덱스(목차) 생성이 가능한 데이터 프레임

 → 따라서 검색과 같은 작업을 할 때 성능의 차이점을 보인다.

 → [참고] 검색 시 data.frame은 하나하나 비교해 찾는 벡터 검색 방식 / data.table은 목차를 이용, 바이너리 검색

※ 해당 내용은 위의 책을 통해 R을 학습하면서 개인적으로 정리한 내용임을 밝힙니다.

 

R을 활용한 그래프 표현을 학습해보면 알겠지만, 그래프를 나타낼 때 사용패턴이 비슷하며 안에있는 변수나 지정값이 달라질 뿐이다. 따라서 아래와 같이 ggplot2를 정리 가능하다.

 

ggplot(data= <데이터> )  +
 <지옴함수>(
    mapping = aes(<매핑모음>),
     stat = <스탯>,
     poistion = <위치>
  ) +
  <좌표계 함수> +
  <면분할 함수>

 

위와 같이 조합을 변경해보면서 다양한 그래프를 완성시킬 수 있다.

 

※ 해당 내용은 위의 책을 통해 R을 학습하면서 개인적으로 정리한 내용임을 밝힙니다.

 

[ 사용 Packages = tidyverse ] 

library(tidyverse)

[ 실습용 Data Set = mpg ]

# mpg : 미 환경보호당국이 수집한 38개의 차 모델들에 대한 관측값
mpg

[ 참고 사항 ]

ggplot2는 보통 ggplot(data=<데이터>)에 지옴 함수를 + 하여 작동

  → 즉 그래프 형식을 변경하거나 표현을 추가하고 싶다면 +되는 지옴함수를 바꾸면 됨 

 

기하 그래프 그리기 ( geom_smooth() )

 

지난번 산점도에 이어서 기하 그래프를 그리는 방법을 학습해보자. 산점도로 상관관계 파악이 가능하지만, 평활선을 그려 추세를 볼 수 있다면, 더 효과적인 Data 이해가 가능하다. 이 때는 geom_smooth() 함수를 사용하면 된다.

 

산점도 보다 배기량(displ)과 연비(hwy)의 상관 관계를 선으로 보다 명확히 볼 수 있다.

 

# geom_smooth(), 데이터에 적합한 평활선을 만들어 추세 보여줌
# geom_Point()와 사용 방법은 비슷하다. ( 지옴함수만 바뀜 )
ggplot(data=mpg) + geom_smooth(mapping = aes(x=displ, y=hwy))

 

geom_point()에서는 다양한 방식(색상, 모양, 투명도 등)으로 1개의 변수 안 항목을 그래프 상에서 구분 표현하였다. 이처럼 geom_Smooth()에서는 linetype을 추가하면, 1개의 변수의 Data의 항목을 구분하여 표현이 가능하다.

 

구동방식(drv) 변수를 지정해서 4륜, 전륜, 후륜을 구분해서 평활선을 볼 수 있다.

 

# geom_smooth() + linetype 추가, 지정 Data로 평활선을 구분
ggplot(data=mpg)+geom_smooth(mapping = aes(x=displ, y=hwy, linetype = drv))

 

평활선을 산점도와 같이 보고 싶다면, 지옴 함수를 더 + 해주면 된다.

# ggplot()에 추가 표현하고 싶은 지옴함수를 +로 추가
ggplot(data=mpg)+
  geom_smooth(mapping = aes(x=displ, y=hwy)) +
  geom_point(mapping = aes(x=displ, y=hwy))

위와 같이 지옴 함수마다 x,y에 어떤 변수를 매핑하는지 각각 지정해 줄 수도 있다. 그러나 X,Y 변수가 동일할 땐, 상위

ggplot에 매핑을 지정하여, 전역 처리하면 보다 코드를 간단히 할 수 있다. 

ggplot(data=mpg,mapping = aes(x=displ, y=hwy))+
  geom_smooth()+
  geom_point()

 

<참고> 중복되는 것은 전역처리하고, 지옴 함수 별 심미성을 표현하면 더 깔끔하게 작성 가능하다.

ggplot(data=mpg,mapping = aes(x=displ, y=hwy))+
  geom_smooth(
    data=filter(mpg, class == "subcompact"),
    se = FALSE
  )+
  geom_point(mapping = aes(color=class))

※ 해당 내용은 위의 책을 통해 R을 학습하면서 개인적으로 정리한 내용임을 밝힙니다.

 

[ 사용 Packages = tidyverse ] 

library(tidyverse)

[ 실습용 Data Set = mpg ]

# mpg : 미 환경보호당국이 수집한 38개의 차 모델들에 대한 관측값
mpg

[ 참고 사항 ]

ggplot2는 보통 ggplot(data=<데이터>)에 지옴 함수를 + 하여 작동

  → 즉 그래프 형식을 변경하거나 표현을 추가하고 싶다면 +되는 지옴함수를 바꾸면 됨 

 

ggplot2 다양한 방식의 산점도 작성 ( geom_point() )

 

산점도는 두 변수에 대한 상관관계를 알아보는데 유용.

 

[ 사용 형식 ] ggplot(data=<데이터>) + <geom_함수>(mapping = aes(<매핑모음>))

 

geom_point() 함수로 산점도를 작성해보면 배기량(displ)과 연비(hwy)가 음의 상관관계가 있음을 알 수 있다.

# geom_point() = Plot에 점 레이어 추가, 산점도 생성
# aes()의 x, y 인수는 x, y축으로 매핑될 변수를 지정
ggplot(data=mpg) + geom_point(mapping = aes(x=displ, y = hwy))

 

위 산점도를 보면, 점들이 이상하게 규칙적이다. 그 이유는 geom_point()는 값들을 반올림하여 나타냈기 때문이다. 반올림하는 이유는 점들이 겹치는 것을 방지하기 위함이라고 한다. 그러면 실제 값을 산점도에 표현하려면 어떻게 해야할까? 지옴 함수를 geom_jitter()로 바꾸어주면 간단히 해결된다.

 

 <참고> geom_jitter()를 통해선 실제 값으로 산점도 표현이 가능하다.

ggplot(data=mpg) + geom_jitter(mapping = aes(x=displ, y = hwy))

 

 

 

다시 geom_point()로 돌아와서, 산점도에 색상을 표시해 차형식(Class) 도 함께 구분해서 보고 싶다면, Color를 추가하고, 어떤 변수의 색상을 구분하고 싶은지 지정해 주면 된다.

# color에 차형식(class) 변수를 지정, 색상 랜덤배정하여 구분됨
ggplot(data = mpg) + geom_point(mapping = aes(x=displ, y=hwy, color=class))

색상이 잘 구분이 안된다 싶으면 ggplot2에서는 아래와 같이 여러 방법으로 표현도 가능하다. 즉, 이 중에 Data를 가장 잘 표현하는 것으로 Data분석자가 선택하면 된다. 책에서는 이를 심미성 매핑이라고 부른다. 

 

# 크기 심미성 매핑, 크기로 구분
ggplot(data = mpg) + geom_point(mapping = aes(x=displ, y=hwy, size=class))

# 투명도 심미성 매핑, 투명도로 구분
ggplot(data = mpg) + geom_point(mapping = aes(x=displ, y=hwy, alpha=class))

# 모양 심미성 매핑, 모양으로 구분 (최대 6개까지 가능)
ggplot(data = mpg) + geom_point(mapping = aes(x=displ, y=hwy, shape=class))

 

그래프를 표현하다 보면, 직접 조건을 넣어 구별하고 싶을 때도 있다. 이 때는 변수에 조건식을 넣어주면 ggplot2가 알아서 True/False로 구분해준다. 색상구분만 해보자면, ( 색상, 크기, 모양, 투명도 모두 적용 가능 )

# Color에 조건을 넣어주면, 조건에 대한 True/False로 색상을 구분
# cyl 변수는 차량의 기통 수 ( 즉, 8기통 보다 크냐, 작으냐로 True/False 색상 구분 )
ggplot(data = mpg) + geom_point(mapping = aes(x=displ, y=hwy, color=cy<8))

차형식(Class) 변수를 심미성 매핑( 색상, 모양 등 구분 )을 하면 차형식 안의 변수가 7개이기 때문에 복잡해 보이기도 한다. 어떨 때는 그냥 아예 그래프를 쪼개서 보는 것이 유리 할 수도 있다. 이때는 면 분할 함수 Facet_wrap를 추가하면 1개의 변수를 기준으로 쉽게 그래프를 분할 가능하다.

 

※ 아래 코드형식을 보면 Facet_wrap 함수를 +로 추가한 것을 볼 수 있다. 이처럼 ggplot는 +로 함수들을 추가하여, 기능이나 표현을 추가한다는 것을 볼 수 있다.

 

# 플롯을 하나의 변수에 대해 면 분할 Facet_wrap()
# (중요) Facet_wrap()에 전달하는 변수는 이산형(연속형 X)이어야 함.
# 이산형이란 것은 정수형, 문자형 Data가 뚝뚝 끊어져 있어야 한다는 것.
# nrow = 그래프 분할 시 몇개의 행으로 구분하는지 지정 ( 굳이 안써도 됨 )
ggplot(data=mpg) + geom_point(mapping = aes(x=displ, y=hwy)) + facet_wrap(~ class, nrow=2)

 

 

 

여기서 더 욕심을 내면, 2개의 변수로 그래프를 쪼개고 싶을 때가 있다. 이 때는 Facet_grid()를 추가하자.

 

# 플롯을 두 변수 조합으로 면분할 Facet_grid()
# 두개의 변수가 ~로 행, 열 구분됨 ( 변수를 생략하려면 .을 찍음 )
ggplot(data=mpg) + geom_point(mapping = aes(x=displ, y=hwy)) + facet_grid(drv ~ cyl)

 

<참고> Code 작성시 주의 사항

# 실행 안됨
ggplot(data=mpg)
+ geom_point(mapping = aes(x=displ, y = hwy))

# 실행됨
ggplot(data=mpg) +
 geom_point(mapping = aes(x=displ, y = hwy))

위와 같이 +는 라인의 시작이 아니라 끝에 와야 Code의 실행이 가능하다.

+ Recent posts