본문 바로가기
데이터분석/R

[실무 프로젝트로 배우는...] 군집 분석

by 버섯도리 2022. 2. 2.

> ### 4.1 중고차 데이터 분할을 위한 데이터 분석 기법

> #### 4.1.1 비슷한 유형의 중고차 탐색 - 유사도 분석

> # 데이터 및 패키지 불러오기   

> library(ggplot2)
> library(dplyr)
> library(reshape)

> DIR = "F:/1_Study/1_BigData/12_R/02_Practical-R/Data/"
> Audi = read.csv(paste0(DIR, "audi.csv"),stringsAsFactors = FALSE)

> # 유사도 기준   

> Normalization = function(x){
+   y = (x-min(x))/(max(x)-min(x))
+   return(y)
+ }

> Audi$mileage_Norm = Normalization(Audi$mileage)
> Audi$mpg_Norm = Normalization(Audi$mpg)

> # 유클리디안 거리

Dist_Fun = function(x1,x2){
+   y1 = (x1-x2)^2
+   y2 = sqrt(sum(y1))
+   return(y2)
+ }

Dist_Fun(x1 = Audi[1,c("mileage_Norm", "mpg_Norm")],
+          x2 = Audi[2,c("mileage_Norm", "mpg_Norm")])
[1] 0.08194011

> Audi$transmission_Manual = ifelse(Audi$transmission == "Manual", 1, 0)
> Audi$transmission_Automatic = ifelse(Audi$transmission == "Automatic", 1, 0)

> Audi$fuelType_Petrol = ifelse(Audi$fuelType == "Petrol", 1, 0)
> Audi$fuelType_Diesel = ifelse(Audi$fuelType == "Diesel", 1, 0)

> Audi2 = Audi %>%
+   select(year, price, mileage, tax, mpg, 
+          engineSize, transmission_Manual, transmission_Automatic,
+          fuelType_Petrol, fuelType_Diesel)

> Audi2 = apply(Audi2, MARGIN = 2, FUN = Normalization)

Dist_Fun2 = function(x) {
+   Matrix = matrix(data = 0,
+                   nrow = nrow(x),
+                   ncol = nrow(x)
+   )
+   
+   for(k in 1:nrow(x)){
+     for(i in k:nrow(x)){
+       y1 = (x[k,]-x[i,])^2
+       y2 = sum(y1)
+       y3 = sqrt(y2)
+       
+       Matrix[k,i] = y3 
+       Matrix[i,k] = y3
+     }
+   } 
+   
+   return(Matrix)
+ }
> Dist_Matrix = Dist_Fun2(x = Audi2[1:10,])
> Dist_Matrix
           [,1]      [,2]       [,3]      [,4]      [,5]     [,6]      [,7]     [,8]       [,9]      [,10]
 [1,] 0.0000000 2.0170993 0.21619790 2.0039905 0.1255657 1.431026 2.0225669 1.450225 0.26013588 0.21246415
 [2,] 2.0170993 0.0000000 2.00347454 0.2229003 2.0266548 1.418035 0.1298899 1.420242 2.00360045 2.00371208
 [3,] 0.2161979 2.0034745 0.00000000 2.0141984 0.2663533 1.414527 2.0078850 1.427257 0.07411785 0.02422808
 [4,] 2.0039905 0.2229003 2.01419836 0.0000000 2.0122590 1.433012 0.2603833 1.439857 2.01764631 2.01406180
 [5,] 0.1255657 2.0266548 0.26635328 2.0122590 0.0000000 1.439691 2.0348919 1.468625 0.32506517 0.25865746
 [6,] 1.4310262 1.4180351 1.41452697 1.4330117 1.4396913 0.000000 1.4241887 2.007990 1.41588901 1.41475242
 [7,] 2.0225669 0.1298899 2.00788497 0.2603833 2.0348919 1.424189 0.0000000 1.415408 2.00519033 2.00965192
 [8,] 1.4502254 1.4202424 1.42725704 1.4398573 1.4686255 2.007990 1.4154083 0.000000 1.42232942 1.42971214
 [9,] 0.2601359 2.0036004 0.07411785 2.0176463 0.3250652 1.415889 2.0051903 1.422329 0.00000000 0.09209175
[10,] 0.2124641 2.0037121 0.02422808 2.0140618 0.2586575 1.414752 2.0096519 1.429712 0.09209175 0.00000000
> # 거리행렬이 출력된다.

> # 시각화 표현
> Dist_Matrix %>%
+   as.data.frame() %>%
+   mutate(Row = 1:10) %>%
+   melt(id.vars = c("Row")) %>%
+   ggplot() +
+   geom_tile(aes(x = as.factor(Row), y = as.factor(variable), fill = value), alpha = 0.6) +
+   geom_vline(xintercept = seq(0.5,10,by = 1), linetype = "dashed") +
+   geom_hline(yintercept = seq(0.5,10,by = 1), linetype = "dashed") +
+   scale_y_discrete(expand = c(0,0)) +
+   scale_x_discrete(expand = c(0,0)) +
+   xlab("") + ylab("") + ggtitle("Euclidean") +
+   guides(fill = FALSE) +
+   theme_classic() 
경고메시지(들): 
`guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> = "none")` instead. 

> # 상자 색이 진할수록 거리가 가까운 것을 의미한다.

> # 코사인 유사도

CosSim2 = function(x){
+   xy = x %*% t(x) 
+   x2 = sqrt(rowSums(x^2))
+   y2 = t(sqrt(rowSums(x^2)))
+   
+   Sim = xy/(x2 %*% y2)
+   
+   return(Sim)
+ }

> Cosine_Matrix = CosSim2(x = Audi2[1:10,])

> # 시각화 표현
> Cosine_Matrix %>%
+   as.data.frame() %>%
+   mutate(Row = 1:10) %>%
+   melt(id.vars = c("Row")) %>%
+   ggplot() +
+   geom_tile(aes(x = as.factor(Row), y = as.factor(variable), fill = value), alpha = 0.6) +
+   geom_vline(xintercept = seq(0.5,10,by = 1), linetype = "dashed") +
+   geom_hline(yintercept = seq(0.5,10,by = 1), linetype = "dashed") +
+   scale_y_discrete(expand = c(0,0)) +
+   scale_x_discrete(expand = c(0,0)) +
+   xlab("") + ylab("") + ggtitle("Cosine Similarity") +
+   guides(fill = FALSE) +
+   theme_classic()
경고메시지(들): 
`guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> = "none")` instead. 

> # 밝을수록 유사도가 높다.

> #### 4.1.2 계층적 군집분석

> library(cluster)

> # 유클리디안 거리 기준

> Cluster1 = hclust(as.dist(Dist_Matrix), method = 'ward.D')

> # Ward 방법은 예측자들에 대해 생성되는 군집의 분산분석 제곱합을 활용하는 방법이다.

plot(Cluster1, main = "Euclidean Distance Clustering",
+      ylab = "", xlab = "", yaxt = "n")


> # 코사인 유사도 거리 기준


> Cluster2 = hclust(as.dist(Cosine_Matrix), method = "ward.D")

plot(Cluster2, main = "Cosine Similarity Clustering",
+      ylab = "", xlab = "", yaxt = "n")



> #### 4.1.3 비계층적 군집분석

> # k 평균 군집분석   

> KM = kmeans(Audi2[1:100,], 3, nstart = 25)
> # k=3, nstart는 K개의 중심점을 임의로 생성하는 횟수를 의미하며, 일반적으로 25를 설정한다.
> KM$cluster
  [1] 3 1 3 1 3 3 1 2 3 3 3 1 2 3 2 3 1 3 1 3 1 1 1 1 1 1 1 3 1 2 1 3 1 3 1 1 3 1 2 2 2 1 1 1 3 3 3 1 3 3 2 1 3 2 1 3 1 3 2
 [60] 2 2 2 2 2 3 3 2 3 3 3 2 2 2 2 3 3 1 3 2 3 2 2 3 1 3 3 3 3 2 3 3 1 1 1 3 1 2 3 3 3
> # 각 행에 대한 군집을 출력

> library(factoextra)
> fviz_cluster(KM, data = Audi2[1:100,]) +
+   theme_bw()

> # 2개의 축은 주성분석으로 계산된 새로운 축이다.

 

 

 

 

 

 

출처 : 실무 프로젝트로 배우는 데이터 분석 with R