【问题标题】:Partition into classes: jenks vs kmeans分类:jenks vs kmeans
【发布时间】:2019-05-10 15:40:08
【问题描述】:

我想将一个向量(长度约为 10^5)划分为五个类。使用 classInt 包中的 classIntervals 函数,我想使用 style = "jenks" 自然间断点,但是即使对于只有 500 的小得多的向量,这也会花费大量时间。设置 style = "kmeans" 几乎是瞬间执行的。

library(classInt)

my_n <- 100
set.seed(1)
x <- mapply(rnorm, n = my_n, mean = (1:5) * 5)

system.time(classIntervals(x, n = 5, style = "jenks"))
R> system.time(classIntervals(x, n = 5, style = "jenks"))
   user  system elapsed 
  13.46    0.00   13.45 

system.time(classIntervals(x, n = 5, style = "kmeans"))
R> system.time(classIntervals(x, n = 5, style = "kmeans"))
   user  system elapsed 
   0.02    0.00    0.02

是什么让 Jenks 算法如此缓慢,有没有更快的方法来运行它?

如果需要,我会将问题的最后两部分移至 stats.stackexchange.com:

  • 在什么情况下,kmeans 是 Jenks 的合理替代品?
  • 通过在数据点的随机 1% 子集上运行 classInt 来定义类是否合理?

【问题讨论】:

  • 请阅读函数帮助。 kmeans 使用一组随机样本作为初始聚类中心。要获得可重现的结果,请通过set.seed() 设置种子并阅读有关 k-means 和局部与全局最小值的信息。 ?classIntervals 中提到了这一点。
  • 谢谢加文。我在发布并编辑问题后不久就找到了该部分。
  • @hadley:这很难相信。想象一下,您的数据代表 10 名成人和 90 名儿童的身高。应该清楚的是,一个好的聚类算法不仅仅是将它们塞进相同大小的分位数中。
  • 好的,但是你得到的数据具有非常清晰的集群是很不寻常的。你真的认为你的 100,000 个点很好地聚集成 5 个簇吗?!如果是这样,我希望我可以使用像您这样的数据。
  • 我不知道有 5 个集群,但在某些情况下您肯定会期望两个集群。将部分页面的灰度图像转换为仅用于光学字符识别的黑白图像是一个很好的示例,其中分位数会非常错误,但需要两个明确的簇。

标签: r intervals


【解决方案1】:

回答你原来的问题:

是什么让 Jenks 算法如此缓慢,有没有更快的方法 运行它?

确实,同时还有一种更快的方法来应用 Jenks 算法,即 BAMMtools 包中的 setjenksBreaks 函数。

但是,请注意,您必须以不同的方式设置中断数,即,如果您在 classInt 包的 classIntervals 函数中将中断数设置为 5,则您必须将 @987654325 的中断数设置为 6 BAMMtools 包中的@函数得到相同的结果。

# Install and load library
install.packages("BAMMtools")
library(BAMMtools)

# Set up example data
my_n <- 100
set.seed(1)
x <- mapply(rnorm, n = my_n, mean = (1:5) * 5)

# Apply function
getJenksBreaks(x, 6)

速度提升很大,即

> microbenchmark( getJenksBreaks(x, 6, subset = NULL),  classIntervals(x, n = 5, style = "jenks"), unit="s", times=10)
Unit: seconds
                                      expr         min          lq        mean      median          uq         max neval cld
       getJenksBreaks(x, 6, subset = NULL) 0.002824861 0.003038748 0.003270575 0.003145692 0.003464058 0.004263771    10  a 
 classIntervals(x, n = 5, style = "jenks") 2.008109622 2.033353970 2.094278189 2.103680325 2.111840853 2.231148846    10   

【讨论】:

    【解决方案2】:

    来自?BAMMtools::getJenksBreaks

    Jenks 自然中断方法已从 classInt R 包中的代码移植到 C。

    这两个程序是一样的;一个比另一个更快,因为它们的实现(C vs R)。

    【讨论】:

    • 在classInt中哪里可以了解jenks、fisher等的区别?
    猜你喜欢
    • 2011-10-10
    • 2015-12-03
    • 2019-10-03
    • 1970-01-01
    • 2020-04-06
    • 2018-01-21
    • 2013-04-23
    • 2018-08-13
    • 2016-11-11
    相关资源
    最近更新 更多