【发布时间】:2015-06-23 13:53:23
【问题描述】:
我是 r 的新手,如果我的要求是不可能的或疯狂的,请纠正我。
我想将一组地理坐标数据(纬度、经度)聚类成预定数量的大小大致相同的聚类。
我关心的是 k-means 和 FCM 算法,因为它是基于欧几里德距离计算的。我在想如果我可以用Haversine公式代替它,也许会起作用。我查看了 cmeans 函数的源代码,但不知道发生了什么......
我的想法是在下面的metric方法下添加一个Haversine选项,并相应地添加代码。
`dist <- pmatch(dist, c("euclidean", "manhattan","Haversine"))`
我也尝试过 DBSCAN,但由于我需要固定数量的类似大小的集群,我发现很难实现我的目标。
如果可能,请告诉我。也欢迎任何关于如何执行集群的其他想法,谢谢!
#Fuzzy C Means
fcmeans=function (x, centers, iter.max = 100, verbose = FALSE, dist = "euclidean",
method = "cmeans", m = 2, rate.par = NULL, weights = 1, control = list())
{
x <- as.matrix(x)
xrows <- nrow(x)
xcols <- ncol(x)
if (missing(centers))
stop("Argument 'centers' must be a number or a matrix.")
dist <- pmatch(dist, c("euclidean", "manhattan"))
if (is.na(dist))
stop("invalid distance")
if (dist == -1)
stop("ambiguous distance")
method <- pmatch(method, c("cmeans", "ufcl"))
if (is.na(method))
stop("invalid clustering method")
if (method == -1)
stop("ambiguous clustering method")
if (length(centers) == 1) {
ncenters <- centers
centers <- x[sample(1:xrows, ncenters), , drop = FALSE]
if (any(duplicated(centers))) {
cn <- unique(x)
mm <- nrow(cn)
if (mm < ncenters)
stop("More cluster centers than distinct data points.")
centers <- cn[sample(1:mm, ncenters), , drop = FALSE]
}
}
else {
centers <- as.matrix(centers)
if (any(duplicated(centers)))
stop("Initial centers are not distinct.")
cn <- NULL
ncenters <- nrow(centers)
if (xrows < ncenters)
stop("More cluster centers than data points.")
}
if (xcols != ncol(centers))
stop("Must have same number of columns in 'x' and 'centers'.")
if (iter.max < 1)
stop("Argument 'iter.max' must be positive.")
if (method == 2) {
if (missing(rate.par)) {
rate.par <- 0.3
}
}
reltol <- control$reltol
if (is.null(reltol))
reltol <- sqrt(.Machine$double.eps)
if (reltol <= 0)
stop("Control parameter 'reltol' must be positive.")
if (any(weights < 0))
stop("Argument 'weights' has negative elements.")
if (!any(weights > 0))
stop("Argument 'weights' has no positive elements.")
weights <- rep(weights, length = xrows)
weights <- weights/sum(weights)
perm <- sample(xrows)
x <- x[perm, ]
weights <- weights[perm]
initcenters <- centers
pos <- as.factor(1:ncenters)
rownames(centers) <- pos
if (method == 1) {
retval <- .C("cmeans", as.double(x), as.integer(xrows),
as.integer(xcols), centers = as.double(centers),
as.integer(ncenters), as.double(weights), as.double(m),
as.integer(dist - 1), as.integer(iter.max), as.double(reltol),
as.integer(verbose), u = double(xrows * ncenters),
ermin = double(1), iter = integer(1), PACKAGE = "e1071")
}
else if (method == 2) {
retval <- .C("ufcl", x = as.double(x), as.integer(xrows),
as.integer(xcols), centers = as.double(centers),
as.integer(ncenters), as.double(weights), as.double(m),
as.integer(dist - 1), as.integer(iter.max), as.double(reltol),
as.integer(verbose), as.double(rate.par), u = double(xrows *
ncenters), ermin = double(1), iter = integer(1),
PACKAGE = "e1071")
}
centers <- matrix(retval$centers, ncol = xcols, dimnames = list(1:ncenters,
colnames(initcenters)))
u <- matrix(retval$u, ncol = ncenters, dimnames = list(rownames(x),
1:ncenters))
u <- u[order(perm), ]
iter <- retval$iter - 1
withinerror <- retval$ermin
cluster <- apply(u, 1, which.max)
clustersize <- as.integer(table(cluster))
retval <- list(centers = centers, size = clustersize, cluster = cluster,
membership = u, iter = iter, withinerror = withinerror,
call = match.call())
class(retval) <- c("fclust")
return(retval)
}
【问题讨论】:
标签: r cluster-analysis