>RE::VISION CRM

R 데이터 분석

0720 클러스터링 군집화 연습

YONG_X 2015. 7. 20. 17:48

#----------[클러스터링]---------


# 클러스터링 (군집화)에 사용할 항목만 뽑아서 df 생성

mtc1 <- mtcars[, c(1,4,6) ] 

# 스케일을 통일

mtc2 <- scale(mtc1) 

# 비계층적 군집화 방법인 k-means 를 적용. 4개 군집으로 실


fit <- kmeans(mtc2, 4) 


# 생성된 결과를 담고있는 fit (모델) 에서 각 군집의 중심점 정


보를

# 추출해서 DF로 저장 --- 왜? 마음대로 그래프 그려보고 싶어


tmp01<-as.data.frame(fit$centers)


#-------- 계층적 군집화도 가능

d <- dist(scale(mtc1), method = "euclidean") # distance 


matrix

fit1 <- hclust(d, method="ward.D") 

plot(fit1, labels=row.names(mtcars) ) # display dendogram


rect.hclust(fit1, 3)


#==============[clustering 복습]====


dia <- read.csv("diamonds.csv")


# x, y, z 세가지 변수를 기준으로

# 6만개 가량의 데이터를 

# 5개 집단으로 구분


dia1 <- dia[, 9:11] 


# 각 변수가 서로 다른 분포를 가지고 있기

# 때문에 스케일을 동일하게 조절

dia2 <- scale(dia1) 

fit <- kmeans(dia2, 5) 

fit$centers


Available components:


[1] "cluster"      "centers"     

[3] "totss"        "withinss"    

[5] "tot.withinss" "betweenss"   

[7] "size"         "iter"        

[9] "ifault"      



# plot(sort(dia2[,1]))

# median(dia2[,1])


tmp01<-as.data.frame(fit$centers)


cor(tmp01$x,tmp01$y); cor(tmp01$x,tmp01$z)


tmp01$size <-fit$size

plot(tmp01$size)


plot(tmp01$x, tmp01$y, col=ifelse(tmp01$size>10000, "red", 


"green"))



# [mtcars]의 세 변수를 기준으로 =======

# 클러스터링 실시


data(mtcars)

"mpg" ~ "cyl"  "hp"  "wt"




mtcars1 <- mtcars[, c(2:11)] 


plot(mtcars1$cyl, mtcars1$hp)

plot(mtcars1$cyl, mtcars1$wt)

plot(mtcars1$hp, mtcars1$wt)

cor(mtcars1$cyl,mtcars1$hp); cor(mtcars1$hp,mtcars1$wt) ;

cor(mtcars1$cyl,mtcars1$wt)


# 난수의 차이로 결과가 달라지는 것을 방지

set.seed(432)

# 스케일을 동일하게 조절

mtcars2 <- scale(mtcars1) 

fit <- kmeans(mtcars2, 5) 

fit$centers


tmp01<-as.data.frame(fit$centers)


tmp01$size <-fit$size

plot(tmp01$size)


plot(tmp01$hp, tmp01$wt, col=ifelse(tmp01$size>5, "red", 


"green"))


mtcars$cluster <- fit$cluster


cl01 <- aggregate(mtcars$mpg, by=list(mtcars


$cluster),FUN=mean)

cl02 <- mtcars[mtcars$cluster==3,]


require(party)

mtcars$cluster <- as.factor(mtcars$cluster)


ct1 <- ctree(cluster~cyl+disp+hp+drat+wt+qsec+vs+am


+gear+carb , control=ctree_control(minsplit = 4, maxdepth = 


5, minbucket = 2)

, data = mtcars)

plot(ct1)


#---[어느 클러스터에 어느 브랜드가 많은가?]

# 클러스터 프로파일링 연습


# 먼저 브랜드명을 뽑아 오고

library(stringr)

mtcars$brand<-word(rownames(mtcars),1)


# sql을 사용하여 집단별 브랜드별 차량수 계산

install.packages("sqldf")

require(sqldf)


cl03 <- sqldf('select cluster, brand,

count(*) as cnt

from mtcars

group by cluster, brand')


# 집단별 차량수 순으로 내림차 정렬

cl03 <- cl03[order(cl03$cluster, -cl03$cnt),]


 

#---------------------


d <- dist(scale(mtcars1), method ="euclidean") 

# distance matrix

fit1 <- hclust(d, method="ward.D") 


# display dendogram

plot(fit1, labels=row.names(mtcars)) 


#--------------------

#  ... 클러스터링 응용...[뉴스 클러스터링]

#-------------------------------

# 페이스북에 올려진 두 파일을 읽어들임

# cndf1_0717a.csv     [키워드 추출 결과]

# temp_news_rvc07_001.csv  [뉴스 자체]


# 같은 키워드가 들어있는 뉴스는 유사한 내용에

# 대한 뉴스 일 수 있음 --> 키워드로 군집화



news01 <- read.csv("cndf1_0717a.csv")

news02 <- read.csv("temp_news_rvc07_001.csv")


length(unique(news01$news_seq))

plot(news01$newskwd)


# SQL의 한글 인코딩 문제를 피하기 위해

# aggregate 함수 활용

# SQL의 count와 같은 기능을 제공하지 않아서

# 사용자정의함수를 활용


n04 <- aggregate(news01$news_seq,  by=list


(news01$newskwd),  function(x) length(unique(x)))


# select newskwd,

# count(distinct news_seq) as cntnews

# group by newskwd


n05 <- head(n04[order(-n04$x),],5)

names(n05) <- c("newskwd", "cntnews")

n05$newskwd <- as.character(n05$newskwd)


n07<- unique(news01$newskwd)

n08<- c(1:length(n07))

n09 <- data.frame(n08,n07)


n10 <- unique(news01$news_seq)



# 가장 빈도가 높은 <빅데이터>라는 키워드가

# (n05의 첫번째 키워드)

# 포함되었으면 1, 아니면 0으로 

# 각 기사에 값을 부여


n11 <- "빅데이터"

n11 <- n05[1,1]

n12 <- news01[news01$newskwd == n11, ]


# unique(n12)

# 불필요한 X 컬럼을 제거

n13 <- n12[,-1]

# nrow(unique(n13))

n1301 <- unique(n13 )

n1301$is_kwd01 <- 1

n1301 <- n1301[,c(-1,-2)]


n14 <-data.frame(n10)

names(n14) <- c("news_seq")



n15 <- merge(n14, n1301, by.x="news_seq", 


by.y="news_seq", all.x = TRUE, all.y = FALSE)


# n15 <- merge(n14, n1301, by=c("news_seq"), all.x = TRUE)


#--------------

n21 <- news01[news01$newskwd == n05[2,1] , ]


# 불필요한 X 컬럼을 제거

n22 <- n21[,-1]

n2201 <- unique(n22 )

n2201$is_kwd02 <- 1

n2201 <- n2201[,c(-1,-2)]


n23 <- merge(n15, n2201, by.x="news_seq", 


by.y="news_seq", all.x = TRUE, all.y = FALSE)


#--------------

n24 <- news01[news01$newskwd == n05[3,1] , ]


# 불필요한 X 컬럼을 제거

n24 <- n24[,-1]

n2401 <- unique(n24 )

n2401$is_kwd03 <- 1

n2401 <- n2401[,c(-1,-2)]


n25 <- merge(n23, n2401, by.x="news_seq", 


by.y="news_seq", all.x = TRUE, all.y = FALSE)


#--------------

n26 <- news01[news01$newskwd == n05[4,1] , ]


# 불필요한 X 컬럼을 제거

n26 <- n26[,-1]

n2601 <- unique(n26 )

n2601$is_kwd04 <- 1

n2601 <- n2601[,c(-1,-2)]


n27 <- merge(n25, n2601, by.x="news_seq", 


by.y="news_seq", all.x = TRUE, all.y = FALSE)


#--------------

n28 <- news01[news01$newskwd == n05[5,1] , ]


# 불필요한 X 컬럼을 제거

n28 <- n28[,-1]

n2801 <- unique(n28 )

n2801$is_kwd05 <- 1

n2801 <- n2801[,c(-1,-2)]


n29 <- merge(n27, n2801, by.x="news_seq", 


by.y="news_seq", all.x = TRUE, all.y = FALSE)


#--------------

# 한번에 모두 NA를 0으로 바꾸기

n29[2:6][is.na(n29[2:6])] <- 0


# 클러스터링 

n30 <- scale(n29[,c(2:6)]) 

fit <- kmeans(n30, 5) 

fit$centers


tmp01<-as.data.frame(fit$centers)


tmp01$size <-fit$size

plot(tmp01$size)


n29$cluster <- fit$cluster

head(n29[n29$cluster != 4,])


plot(n29$is_kwd01, n29$is_kwd02, col=ifelse


(n29$cluster==2,"red","grey"), pch=3)


plot(jitter(n29$is_kwd01,0.2), jitter(n29$is_kwd02,0.2), 


col=ifelse(n29$cluster==2,"red","grey"), pch=3)


# 점들이 같은 값을 가져서 플롯상에서

# 구별되지 않을때 이 값들을 무작위로 약간 조절해서

# 시각적으로 분포가 구별될 수 있도록 jitter 함수 사용

plot(jitter(n29$is_kwd03,0.5), jitter(n29$is_kwd04,0.5), 


col=ifelse(n29$cluster==2,"red","grey"), pch=3)


#=========================

# 경기도 교통 

#----------------------


ggtr <- read.csv('TransitBusPass_wd12071212.csv')

ggtr1 <- ggtr[ggtr$월==7 & ggtr$일시=="평일"& ggtr$시간


=="일합계", c(1,5,6,8,9)]


head(ggtr1[order(-ggtr1$단일통행승차),],10 )


ggtr2 <- ggtr1[ggtr1$단일통행승차<183130,]

head(ggtr2[order(-ggtr2$단일통행승차),] )


plot(ggtr2$단일통행승차,ggtr2$단일통행하차)

cor(ggtr2$단일통행승차,ggtr2$단일통행하차)


plot(ggtr2$단일통행승차,ggtr2$환승통행승차)

cor(ggtr2$단일통행승차,ggtr2$환승통행승차)


plot(ggtr2$환승통행승차,ggtr2$환승통행하차)

cor(ggtr2$환승통행승차,ggtr2$환승통행하차)


plot(ggtr2$단일통행승차-ggtr2$단일통행하차)

plot(sort(ggtr2$단일통행승차/ggtr2$단일통행하차))


plot(sort(ggtr2$환승통행승차/ggtr2$환승통행하차))


ggtr2$단일통행승하차비율<- ggtr2$단일통행승차/ggtr2$단일


통행하차


ggtr2$환승통행승하차비율<- ggtr2$환승통행승차/ggtr2$환승


통행하차


fit <- kmeans(ggtr2[,c(2,4,6,7)], 5) 

fit$centers


tmp01<-as.data.frame(fit$centers)


tmp01$size <-fit$size

plot(tmp01$size)


ggtr2$cluster <- as.factor(fit$cluster)

require(party)


ct1 <- ctree(cluster~단일통행승차+단일통행승하차비율+환승


통행승차+환승통행승하차비율 , control= ctree_control


(minsplit = 4, maxdepth = 5, minbucket = 2) , data = ggtr2 )

plot(ct1)


plot(ggtr2$단일통행승차, ggtr2$환승통행승차, col=ifelse


(ggtr2$cluster==5,"red","grey"), pch=3)


ggtr2[ ggtr2$cluster==5, c(1,2,4)]


areaname <- ggtr2$지역

areaseq <- c(1:46)

areanamedf <- data.frame(areaseq, areaname)


# 각 지역별로 오전중 (05~12 시) 중 

# 가장 통행이 많은 시간과

# 저녁 6시이후 (18~23 시) 가장 통행이 많은 시간을

# 지역에 대한 변수로 사용해서

# 군집을 만들어 본다면?


ggtr3 <- ggtr[ggtr$월==7 & ggtr$일시=="평일" & ggtr$시간


!="일합계" & ggtr$시간!="12시간", c(1,4,5,8)]


ggtr3$시간대 <- as.numeric(substr(as.character(ggtr3$시간), 


1,2))


n51a <- sqldf('select distinct 지역,  시간대 as max시간오전,

max(단일통행승차) as max단일통행승차오전

from ggtr3 

where  시간대 between 5 and 12

group by 지역

')


ggtr4 <- ggtr[ggtr$월==7 & ggtr$일시=="평일"& ggtr$시간


=="일합계", c(1,5,6,8,9)]


n52 <- sqldf('select a.*, b.단일통행승차 

from n51a as a left join ggtr4 as b

on a.지역=b.지역

')

plot(n52$max시간오전, n52$단일통행승차)


# 클러스터링에 투입되는 변수들이 분포가

# 크게 차이날 경우, scale은 필수로 체크 필요!!

fit <- kmeans(scale(n52[,c(2,4)]), 5) 

fit$centers


tmp01<-as.data.frame(fit$centers)

tmp01$size <-fit$size

plot(tmp01$size)


n52$cluster <- fit$cluster


plot(n52$max시간오전, n52$단일통행승차, col=ifelse


(n52$cluster==3,"red","grey"), pch=3)

plot(n52$max시간오전, n52$단일통행승차, col=ifelse


(n52$cluster==4,"red","grey"), pch=3)


plot(jitter(n52$max시간오전,0.1), jitter(n52$단일통행승차,0.1), 


col=ifelse(n52$cluster==1,"red","grey"), pch=3, main="J1")

plot(jitter(n52$max시간오전,0.1), jitter(n52$단일통행승차,0.1), 


col=ifelse(n52$cluster==2,"red","grey"), pch=3)

plot(jitter(n52$max시간오전,0.1), jitter(n52$단일통행승차,0.1), 


col=ifelse(n52$cluster==3,"red","grey"), pch=3)

plot(jitter(n52$max시간오전,0.1), jitter(n52$단일통행승차,0.1), 


col=ifelse(n52$cluster==4,"red","grey"), pch=3)

plot(jitter(n52$max시간오전,0.1), jitter(n52$단일통행승차,0.1), 


col=ifelse(n52$cluster==5,"red","grey"), pch=3)


cor(n52$max시간오전, n52$단일통행승차)