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 package org.openimaj.ml.clustering.spectral;
31
32 import static org.junit.Assert.assertTrue;
33
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.Collection;
37 import java.util.HashSet;
38 import java.util.Set;
39
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.openimaj.feature.DoubleFVComparison;
43 import org.openimaj.io.FileUtils;
44 import org.openimaj.knn.DoubleNearestNeighboursExact;
45 import org.openimaj.logger.LoggerUtils;
46 import org.openimaj.math.matrix.MatlibMatrixUtils;
47 import org.openimaj.ml.clustering.IndexClusters;
48 import org.openimaj.ml.clustering.SpatialClusterer;
49 import org.openimaj.ml.clustering.dbscan.ClusterTestDataLoader;
50 import org.openimaj.ml.clustering.dbscan.ClusterTestDataLoader.TestStats;
51 import org.openimaj.ml.clustering.dbscan.DoubleDBSCANClusters;
52 import org.openimaj.ml.clustering.dbscan.DoubleNNDBSCAN;
53
54 import ch.akuhn.matrix.SparseMatrix;
55
56 import com.jmatio.types.MLArray;
57
58
59
60
61
62
63
64
65 public class TestDoubleNormalisedSpecralClustering {
66 private TestStats testStats;
67 private double[][] testData;
68 private int[][] testClusters;
69
70
71
72 @Before
73 public void loadTest() throws IOException{
74 LoggerUtils.prepareConsoleLogger();
75 String[] data = FileUtils.readlines(TestDoubleNormalisedSpecralClustering.class.getResourceAsStream("/org/openimaj/ml/clustering/dbscan/dbscandata"));
76 ClusterTestDataLoader loader = new ClusterTestDataLoader();
77 this.testStats = loader.readTestStats(data);
78 this.testData = loader.readTestData(data);
79 this.testClusters = loader.readTestClusters(data);
80 }
81
82
83
84
85
86
87 @Test
88 public void testSimSpatialClusterInverse(){
89 SpatialClusterer<DoubleDBSCANClusters,double[]> inner = new DoubleNNDBSCAN(
90 0.5, 3, new DoubleNearestNeighboursExact.Factory(DoubleFVComparison.EUCLIDEAN)
91 );
92 SpectralClusteringConf<double[]> conf = new SpectralClusteringConf<double[]>(inner, new GraphLaplacian.Normalised());
93 conf.eigenChooser = new AbsoluteValueEigenChooser(0.2, 0.1);
94 DoubleSpectralClustering clust = new DoubleSpectralClustering(conf);
95 SparseMatrix mat_norm = normalisedSimilarity();
96 IndexClusters res = clust.cluster(mat_norm);
97 confirmClusters(res);
98 }
99
100
101
102
103
104 @Test
105 public void testSimSpatialClusterInverseHardcoded() throws IOException{
106 SpatialClusterer<DoubleDBSCANClusters,double[]> inner = new DoubleNNDBSCAN(
107 0.2, 2, new DoubleNearestNeighboursExact.Factory(DoubleFVComparison.EUCLIDEAN)
108 );
109 SpectralClusteringConf<double[]> conf = new SpectralClusteringConf<double[]>(inner, new GraphLaplacian.Normalised());
110 conf.eigenChooser = new AbsoluteValueEigenChooser(0.95, 0.1);
111 DoubleSpectralClustering clust = new DoubleSpectralClustering(conf);
112 SparseMatrix mat_norm = normalisedSimilarity(Double.MAX_VALUE);
113 Collection<MLArray> col = new ArrayList<MLArray>();
114 col.add(MatlibMatrixUtils.asMatlab(mat_norm));
115
116 IndexClusters res = clust.cluster(mat_norm);
117 confirmClusters(res);
118 }
119
120
121 private void confirmClusters(IndexClusters res) {
122 for (int i = 0; i < this.testClusters.length; i++) {
123 System.err.println(toSet(this.testClusters[i]));
124 System.err.println(toSet(res.clusters()[i]));
125 assertTrue(toSet(this.testClusters[i]).equals(toSet(res.clusters()[i])));
126 }
127 }
128
129
130
131 private SparseMatrix normalisedSimilarity() {
132 return normalisedSimilarity(this.testStats.eps);
133 }
134 private SparseMatrix normalisedSimilarity(double eps) {
135 final SparseMatrix mat = new SparseMatrix(testData.length,testData.length);
136 final DoubleFVComparison dist = DoubleFVComparison.EUCLIDEAN;
137 double maxD = 0;
138 for (int i = 0; i < testData.length; i++) {
139 for (int j = i; j < testData.length; j++) {
140 double d = dist.compare(testData[i], testData[j]);
141 if(d>eps) d = Double.NaN;
142 else{
143 maxD = Math.max(d, maxD);
144 }
145 mat.put(i, j, d);
146 mat.put(j, i, d);
147 }
148 }
149 SparseMatrix mat_norm = new SparseMatrix(testData.length,testData.length);
150 for (int i = 0; i < testData.length; i++) {
151 for (int j = i+1; j < testData.length; j++) {
152 double d = mat.get(i, j);
153 if(Double.isNaN(d)){
154 continue;
155 }
156 else{
157 d/=maxD;
158 }
159 mat_norm.put(i, j, 1-d);
160 mat_norm.put(j, i, 1-d);
161 }
162 }
163 return mat_norm;
164 }
165 private Set<Integer> toSet(int[] is) {
166 Set<Integer> set = new HashSet<Integer>();
167 for (int i = 0; i < is.length; i++) {
168 set.add(is[i]);
169 }
170 return set;
171 }
172
173 }