#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
'''
#이상 과제 끝!