【问题标题】:Kmeans: Wrong size of clustersKmeans:集群大小错误
【发布时间】:2019-12-27 15:10:35
【问题描述】:

我在Heart Disease UCI 数据集上运行 R 中的 Kmeans 算法。我应该得到 2 个大小为 138 165 的集群,每个集群都像数据集中的那样。

步骤:

  1. 将数据集存储在数据框中:
df <- read.csv(".../heart.csv",fileEncoding = "UTF-8-BOM")
  1. 提取特征:
features = subset(df, select = -target)
  1. 规范化它:
normalize <- function(x) {
  return ((x - min(x)) / (max(x) - min(x)))
}

features = data.frame(sapply(features, normalize))
  1. 运行算法:
set.seed(0)
cluster = kmeans(features, 2)
cluster$size

输出:

[1]  99 204

为什么?

【问题讨论】:

  • 您没有获得相同的集群可能有多种原因。例如,您的set.seed 在您当前的迭代和之前的迭代之间可能不同。此外,以不同的方式对数据进行排序会影响如何“挑选”基于种子的起点(因为没有更好的术语)。
  • 除了更换种子,我还能做些什么来获得更好的结果?我应该为kmeans 函数指定nstart 吗?
  • 您应该考虑一些事项。尝试多个种子(我尝试了多达 20 个)。尝试多个nstarts。使用两者的组合。我知道这不是一个简单的解决方案。另外,数据有变化吗?你有原始结果吗?通过将新运行与原始结果进行比较,您可能能够接近原始结果。
  • 数据是不变的。我只是在导入和规范化它。它在“目标”列中有原始结果,那么我怎样才能接近?

标签: r k-means


【解决方案1】:

您似乎关注的是集群的大小,而不是预测的准确性。您可能会得到两个大小为 (138, 165) 的集群,但不一定与数据中的“目标”列相同。

判断表现的更好方法是预测的准确性。在您的情况下,您的模型准确率为 72%。您可以通过以下方式查看:

df$label <- cluster$cluster -1

confusionMatrix(table(df$target, df$label))

#Confusion Matrix and Statistics
#   
#      0   1
#  0  76  62
#  1  23 142
#                                          
#               Accuracy : 0.7195 
# ...

我能够通过标准化数据而不是标准化来获得更好的准确性。可能是因为标准化对异常值更稳健。

我还对分类外观变量进行了虚拟编码,这似乎提高了准确性。我们现在有 85% 的准确率,并且集群大小更接近我们的预期(143 160)。尽管如前所述,集群大小本身是没有意义的。

library(dplyr)
library(fastDummies)
library(caret)
standardize <- function(x){
  num <- x - mean(x, na.rm=T)
  denom <- sd(x, na.rm=T)

  num/denom
}

# dummy-code and standardize
features <-  select(df, -target) %>%
   dummy_cols(select_columns = c('cp','thal', 'ca'),
              remove_selected_columns = T,remove_first_dummy  = T) %>%
  mutate_all(standardize)

set.seed(0)
cluster <- kmeans(features, centers = 2, nstart = 50)

cluster$size
# 143 160

# check predictions vs actual labels
df$label <- cluster$cluster -1

confusionMatrix(table(df$target, df$label))
#Confusion Matrix and Statistics
#
#   
#      0   1
#  0 117  21
#  1  26 139
#                                          
#               Accuracy : 0.8449 

当然,还有其他准确度指标也值得考虑,例如样本外准确度(将您的数据拆分为训练集和测试集,并计算测试集上的预测准确度)和 f1-score。

【讨论】:

  • “虚拟编码”和不在features 中包含它们有什么区别?
  • 当我们使用虚拟代码thal 时,我们最终会得到一列 thal=6(1 或 0),以及 thal = 7(1 或 0)的列。我们不需要 thal=3 的列,因为当 thal_6 = 0 且 thal_7=0 时就是这种情况,因此我们删除了该列 (remove_first_dummy=T)。虚拟编码的好处是为我们的变量赋予了意义(Thal = 3 表示“正常”)。否则,我们的变量将被解释为不是数字的(值 4 没有意义)。如果我们根本不将它们包含在 features 中,我们将丢失有价值的信息。
【解决方案2】:

这是一个可以帮助您理顺事情的示例。

library(tidyverse)  # data manipulation
library(cluster)    # clustering algorithms
library(factoextra) # clustering algorithms & visualization

df <- USArrests
df <- na.omit(df)
df <- scale(df)


distance <- get_dist(df)
fviz_dist(distance, gradient = list(low = "#00AFBB", mid = "white", high = "#FC4E07"))



k2 <- kmeans(df, centers = 2, nstart = 25)
str(k2)

fviz_cluster(k2, data = df)

 [![enter image description here][1]][1]

k3 <- kmeans(df, centers = 3, nstart = 25)
k4 <- kmeans(df, centers = 4, nstart = 25)
k5 <- kmeans(df, centers = 5, nstart = 25)

# plots to compare
p1 <- fviz_cluster(k2, geom = "point", data = df) + ggtitle("k = 2")
p2 <- fviz_cluster(k3, geom = "point",  data = df) + ggtitle("k = 3")
p3 <- fviz_cluster(k4, geom = "point",  data = df) + ggtitle("k = 4")
p4 <- fviz_cluster(k5, geom = "point",  data = df) + ggtitle("k = 5")

library(gridExtra)
grid.arrange(p1, p2, p3, p4, nrow = 2)




set.seed(123)

# function to compute total within-cluster sum of square 
wss <- function(k) {
  kmeans(df, k, nstart = 10 )$tot.withinss
}

# Compute and plot wss for k = 1 to k = 15
k.values <- 1:15

# extract wss for 2-15 clusters
wss_values <- map_dbl(k.values, wss)

plot(k.values, wss_values,
       type="b", pch = 19, frame = FALSE, 
       xlab="Number of clusters K",
       ylab="Total within-clusters sum of squares")

[![enter image description here][1]][1]


set.seed(123)

fviz_nbclust(df, kmeans, method = "wss")




# Compute k-means clustering with k = 4
set.seed(123)
final <- kmeans(df, 4, nstart = 25)
print(final)

fviz_cluster(final, data = df)

https://uc-r.github.io/kmeans_clustering

【讨论】:

    猜你喜欢
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 2021-02-20
    • 2017-06-01
    • 2020-11-21
    • 2016-06-28
    • 2021-10-20
    相关资源
    最近更新 更多