-
Notifications
You must be signed in to change notification settings - Fork 0
/
Fuzzy-Silhouette.R
60 lines (39 loc) · 1.99 KB
/
Fuzzy-Silhouette.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# FUZZY SILHOUETTE
# FUZZY.SIL is a implementation of the Fuzzy Silhouette of CAMPELLO, R.; HRUSCHKA, E. A fuzzy extension of the silhouette width criterion
# for cluster analysis. Fuzzy Sets and Systems, v. 157, n. 21, p. 2858
# This function returns the silhouette of each object (obj.sil) and the fuzzy silhouette of the given fuzzy partition
FUZZY.SIL = function (X, U, distance = "euclidean", alpha = 1)
{
X = as.matrix(X)
U = as.matrix(U)
n = nrow(U)
k = ncol(U)
D = as.matrix(dist(X, method = distance))^2 #distance between objects
clusters.obj = apply(U, 1, which.max) # cth cluster where each object has its maximum membership degree (each object "belongs")
dif.degrees = rep(0, n)
a = dif.degrees
b = a
obj.sil = a
for (i in 1:n) {
dif.degrees[i] = (max(U[i, ]) - max(U[i, ][-which.max(U[i, ])]))^alpha
B = rep(0, k)
i2 = which(clusters.obj != clusters.obj[i]) # objects that do not have their maximum membership degree in the same cluster of i
# i.e, objects that do not belong in the same cluster of i
c2 = unique(clusters.obj[i2]) # all remaining clusters that object i does not belong
for (c in c2) {
i3 = which(clusters.obj == c) # objects in the cth cluster
B[c] = mean(D[i, i3]) # average distance between object i and all other objects in the remaining clusters (inter-cluster distance).
}
b[i] = min(B[-clusters.obj[i]])
m = which(clusters.obj == clusters.obj[i]) # objects in the same cluster of i
a[i] = mean(D[i, m][-which(m == i)]) # average distance between object i and all other objects in the same cluster (intra-cluster distance)
if (length(which(clusters.obj[i] == clusters.obj)) > 1){
obj.sil[i] = (b[i] - a[i])/max(a[i], b[i])
}
}
fuzzy.sil = sum(dif.degrees * obj.sil)/sum(dif.degrees)
out = list()
out$obj.sil = obj.sil
out$fuzzy.sil = fuzzy.sil
return(out)
}