View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.ml.clustering;
18  
19  import java.util.ArrayList;
20  import java.util.Arrays;
21  import java.util.List;
22  
23  import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
24  import org.apache.commons.math4.legacy.exception.NullArgumentException;
25  import org.apache.commons.math4.legacy.ml.distance.CanberraDistance;
26  import org.apache.commons.math4.legacy.ml.distance.DistanceMeasure;
27  import org.apache.commons.rng.simple.RandomSource;
28  import org.apache.commons.rng.UniformRandomProvider;
29  import org.junit.Assert;
30  import org.junit.Test;
31  
32  /**
33   * Test cases for FuzzyKMeansClusterer.
34   *
35   * @since 3.3
36   */
37  public class FuzzyKMeansClustererTest {
38  
39      @Test
40      public void testCluster() {
41          final List<DoublePoint> points = new ArrayList<>();
42  
43          // create 10 data points: [1], ... [10]
44          for (int i = 1; i <= 10; i++) {
45              final DoublePoint p = new DoublePoint(new double[] { i } );
46              points.add(p);
47          }
48  
49          final FuzzyKMeansClusterer<DoublePoint> transformer =
50                  new FuzzyKMeansClusterer<>(3, 2.0);
51          final List<CentroidCluster<DoublePoint>> clusters = transformer.cluster(points);
52  
53          // we expect 3 clusters:
54          //   [1], [2], [3]
55          //   [4], [5], [6], [7]
56          //   [8], [9], [10]
57          final List<DoublePoint> clusterOne = Arrays.asList(points.get(0), points.get(1), points.get(2));
58          final List<DoublePoint> clusterTwo = Arrays.asList(points.get(3), points.get(4), points.get(5), points.get(6));
59          final List<DoublePoint> clusterThree = Arrays.asList(points.get(7), points.get(8), points.get(9));
60  
61          boolean cluster1Found = false;
62          boolean cluster2Found = false;
63          boolean cluster3Found = false;
64          Assert.assertEquals(3, clusters.size());
65          for (final Cluster<DoublePoint> cluster : clusters) {
66              if (cluster.getPoints().containsAll(clusterOne)) {
67                  cluster1Found = true;
68              }
69              if (cluster.getPoints().containsAll(clusterTwo)) {
70                  cluster2Found = true;
71              }
72              if (cluster.getPoints().containsAll(clusterThree)) {
73                  cluster3Found = true;
74              }
75          }
76          Assert.assertTrue(cluster1Found);
77          Assert.assertTrue(cluster2Found);
78          Assert.assertTrue(cluster3Found);
79      }
80  
81      @Test(expected = MathIllegalArgumentException.class)
82      public void testTooSmallFuzzynessFactor() {
83          new FuzzyKMeansClusterer<>(3, 1.0);
84      }
85  
86      @Test(expected = NullArgumentException.class)
87      public void testNullDataset() {
88          final FuzzyKMeansClusterer<DoublePoint> clusterer = new FuzzyKMeansClusterer<>(3, 2.0);
89          clusterer.cluster(null);
90      }
91  
92      @Test
93      public void testGetters() {
94          final DistanceMeasure measure = new CanberraDistance();
95          final UniformRandomProvider random = RandomSource.MT_64.create();
96          final FuzzyKMeansClusterer<DoublePoint> clusterer =
97                  new FuzzyKMeansClusterer<>(3, 2.0, 100, measure, 1e-6, random);
98  
99          Assert.assertEquals(3, clusterer.getK());
100         Assert.assertEquals(2.0, clusterer.getFuzziness(), 1e-6);
101         Assert.assertEquals(100, clusterer.getMaxIterations());
102         Assert.assertEquals(1e-6, clusterer.getEpsilon(), 1e-12);
103         Assert.assertEquals(measure, clusterer.getDistanceMeasure());
104         Assert.assertEquals(random, clusterer.getRandomGenerator());
105     }
106 
107     @Test
108     public void testSingleCluster() {
109         final List<DoublePoint> points = new ArrayList<>();
110         points.add(new DoublePoint(new double[] { 1, 1 }));
111 
112         final FuzzyKMeansClusterer<DoublePoint> transformer =
113                 new FuzzyKMeansClusterer<>(1, 2.0);
114         final List<CentroidCluster<DoublePoint>> clusters = transformer.cluster(points);
115 
116         Assert.assertEquals(1, clusters.size());
117     }
118 
119     @Test
120     public void testClusterCenterEqualsPoints() {
121         final List<DoublePoint> points = new ArrayList<>();
122         points.add(new DoublePoint(new double[] { 1, 1 }));
123         points.add(new DoublePoint(new double[] { 1.00001, 1.00001 }));
124         points.add(new DoublePoint(new double[] { 2, 2 }));
125         points.add(new DoublePoint(new double[] { 3, 3 }));
126 
127         final FuzzyKMeansClusterer<DoublePoint> transformer =
128                 new FuzzyKMeansClusterer<>(3, 2.0);
129         final List<CentroidCluster<DoublePoint>> clusters = transformer.cluster(points);
130 
131         Assert.assertEquals(3, clusters.size());
132     }
133 }