투빅스 9기&10기 4주차 K-means - 10기 임진혁

by 진혁 posted Aug 25, 2018
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

+ - Up Down Comment Print

#1.기본적인 k_means 알고리즘 구현 
data(iris)
 
k_means<-function(data,k)  #data는 분류할 데이터 , k는 나누고 싶은 집단의 갯수 
{
  data0<-data #데이터 원본을 저장
  
  c<-sample(nrow(data),k,F#랜덤으로 정할 k 개의 중심점, cent의 index, c.
  cent<-data[c,] #랜덤으로 정해진 중심점 cent. 
  data2<-rbind(data,cent)
  
  dist<-as.matrix(dist(data2))[-c(1:nrow(data)),] #각 임의의 중심점에 대한 각 데이터의 거리표
  for (i in 1:nrow(data)) {
    data$label[i]<- as.numeric(which(dist[,i] ==  min(dist[,i])))
  } #군집나누기! #중심점과 가장 거리가 가까운 군집에 데이터를 넣어준다. 
  
  for (i in 1:k) {
    d<-data[data$label==i,][,1:ncol(data)]
    
    cent[i,]<-colMeans(d)
  } #분할된 군집의 진짜 중심점을 찍어준다. 
  
  s<-1
  while(TRUE) { #무한반복 ~ 언제까지?!!!
    #방금 진행하였던 중심점을 찍고 가까운 데이터를 군집에 할당하고 다시 군집의 중심점을 찾는 과정을 반복.언제까지??
    #과정을 무한 반복하게 한다.~ 언제까지?!!
    data2<-rbind(data0,cent)  
    
    dist<-as.matrix(dist(data2))[-c(1:nrow(data0)),]
    for (i in 1:nrow(data0)) {
      data$label[i]<- which(dist[,i] ==  min(dist[,i]))
    }
    cent0<-cent
    for (i in 1:k) {
      d<-data[data$label==i,][,1:ncol(data0)]
      cent[i,]<-colMeans(d) }
    s<-s+1
    
    f <-1
    t <-1             #그 전 시점의 중심점과 현 중심점이 동일할 떄까지!!
    while (f <= ncol(data0) ) {
      t[f+1]<-(as.vector(colMeans(cent0))[f]==as.vector(colMeans(cent))[f])
      t[f+1]<-t[f]*t[f+1]
      f<-f+1
    }                      #==모든 차원(열,변수)에 대해서 동일할떄 (즉 동일점일떄 ) 
                           #==예시) 점 (1,2,3,5,4) = (1,2,3,5,4)가 될떄까지 .
                           #각 차원의 동일함을 확인하고 모두 true일떄 종료 (break!)
    if( t[f]  ){
      break           #연산종료 !
    }
  }
  
  return(data$label)}   #반환
 
 
#검증_: auc 확인하기 (대략적인)
head(iris)
data <- iris[,1:4]
label<-iris[,5]
self<-k_means(data,3)
 
head(self)
table(self)
result_table <- table(self, label);result_table
''' label
self setosa versicolor virginica
1      0         48        14
2     50          0         0
3      0          2        36'''
sum(50,48,36)/sum(result_table) #대략적인 auc를 구할수 있다. (다만, 라벨이 있는 데이터의 경우에만 가능) 
#따라서, 라벨 상관없이 비모수적 분류를 객관적인 지표로 잘 수행하였는지 확인할 수 있고 
#잘 분류하는 모델을 추가적으로 구현해보자 하였다. 




2.K_MEANS 구현 과제: GRID 내에서 DI 지수

를 통해 최적 그리드 탐색하여 클러스터링 해

주는 모델!!

#위에 기본 구현도 있음.
###grid내에서 최적 군집 갯수 k를 구하고 그에 맞춰서 분류해주는
##k_means update ver 1
#data는 분류할 데이터 , k는 나누고 싶은 집단의 갯수 grid
k_means2<-function(inputdata,grid){                                      
  data0<-inputdata #데이터 원본을 저장
 
  ####################### grid 설정 
  di<-rep(0,length(grid))
 for ( q in grid) {
   data<-data0
   k<-q
  
  
  c<-sample(nrow(data),k,F
  cent<-data[c,] #랜덤으로 정해진 중심점 cent. 
  data2<-rbind(data,cent)
  
  dist<-as.matrix(dist(data2))[-c(1:nrow(data)),] 
  for (i in 1:nrow(data)) {
    data$label[i]<- as.numeric(which(dist[,i] ==  min(dist[,i])))
  } #군집나누기! #중심점과 가장 거리가 가까운 군집에 데이터를 넣어준다. 
  
  for (i in 1:k) {
    d<-data[data$label==i,][,1:ncol(data)]
    
    cent[i,]<-colMeans(d)
 
  } #분할된 군집의 진짜 중심점을 찍어준다. 
  
  s<-1
  while(TRUE) { #무한반복 ~ 언제까지?
    #방금 진행하였던 중심점을 찍고 가까운 데이터를 군집에 할당하고 다시 군집의 중심점을 찾는 
    #과정을 무한 반복하게 한다.~ 언제까지?
    data2<-rbind(data0,cent)  
    
    dist<-as.matrix(dist(data2))[-c(1:nrow(data0)),]
    for (i in 1:nrow(data0)) {
      data$label[i]<- which(dist[,i] ==  min(dist[,i]))
    }
    cent0<-cent
    for (i in 1:k) {
      d<-data[data$label==i,][,1:ncol(data0)]
      cent[i,]<-colMeans(d) }
    s<-s+1
    
    f <-1
    t <-1             #그 전 시점의 중심점과 현 중심점이 동일할 떄까지!!
    while (f <= ncol(data0) ) {
      t[f+1]<-(as.vector(colMeans(cent0))[f]==as.vector(colMeans(cent))[f])
      t[f+1]<-t[f]*t[f+1]
      f<-f+1
    }                      
    if( t[f]  ){
      break           #연산종료 !
    }
  }
  
   ###DI 지수를 구하는 과정.   (DI 지수는 군집과 군집 사이의 거리 중 최소값/ 군집 내 객체 간 거리 중 최대값
  ##군집과 군집간 의 거리 :a (최소값)
 min_dist<-c()
  for ( i in 1:k) {
    data3<-data[data$label==i,][,-5]
    
    
    for(i in 1:k) {
      data4<-data[data$label==i,][,-5]
      data5<-rbind(data3,data4)
      dist<-as.matrix(dist(data5))[c(1:nrow(data3)),][,(nrow(data3)+1):ncol(as.matrix(dist(data5)))]
      min_dist<-c(min_dist,min(dist))
      
    }
    
  }
  a<-min(min_dist[-which(min_dist==0)])
  
  ##군집 내부의 거리 :b( 최대값)
  ###각 군집에서 중심점과 가장 먼점의 거리 
  max_dist<-c()
  for ( i in 1:k) {
  
  data3<-data[data$label==i,][,-5]
  data4<-rbind(data3,cent[i,])
  dist<-as.matrix(dist(data4))[c(1:nrow(data3)),][,ncol(as.matrix(dist(data4)))]
  max_dist<-c(max_dist,max(dist)  )
  
  
  }
  b<-max(max_dist)
  
  
  
  di[q]<-a/b   #즉 DI지수는 a/b이다. 
  
 }
  
 k<-which(di==max(di))         ####DI 지수로 가장 큰 모델로 클러스터링을 진행한다! #DI지수가 제대로 구현되었는지느
#잘 모르겠다. 다만 재밌다!
 data<-data0
 cat("최적 군집 갯수 :",k,"개" )
 ########마지막 클러스터링
 c<-sample(nrow(data),k,F
 cent<-data[c,] 
 data2<-rbind(data,cent)
 dist<-as.matrix(dist(data2))[-c(1:nrow(data)),] 
 for (i in 1:nrow(data)) {
   data$label[i]<- as.numeric(which(dist[,i] ==  min(dist[,i])))
 } 
 
 for (i in 1:k) {
   d<-data[data$label==i,][,1:ncol(data)]
   
   cent[i,]<-colMeans(d)
 }  
 
 s<-1
 while(TRUE
   data2<-rbind(data0,cent)  
   
   dist<-as.matrix(dist(data2))[-c(1:nrow(data0)),]
   for (i in 1:nrow(data0)) {
     data$label[i]<- which(dist[,i] ==  min(dist[,i]))
   }
   cent0<-cent
   for (i in 1:k) {
     d<-data[data$label==i,][,1:ncol(data0)]
     cent[i,]<-colMeans(d) }
   s<-s+1
   
   f <-1
   t <-1            
   while (f <= ncol(data0) ) {
     t[f+1]<-(as.vector(colMeans(cent0))[f]==as.vector(colMeans(cent))[f])
     t[f+1]<-t[f]*t[f+1]
     f<-f+1
   }                      
   if( t[f]  ){
     break           #연산종료 !
   }
 }
 
  
  return(data$label) }        #반환
 
 
 
self<-k_means2(data,c(3,4,5,6))

head(self)

table(self) #결과 예시 
'''

>최적 군집 갯수 : 5 개
[1] 5 5 5 5 5 5
> table(self)

self
 1  2  3  4  5 
12 36 24 28 50 
'''

#이상 과제 끝!

Articles

5 6 7 8 9 10 11 12 13 14

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5