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    *      https://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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.clustering;
23  
24  import org.hamcrest.CoreMatchers;
25  import org.hipparchus.clustering.distance.CanberraDistance;
26  import org.hipparchus.clustering.distance.DistanceMeasure;
27  import org.hipparchus.exception.MathIllegalArgumentException;
28  import org.hipparchus.exception.NullArgumentException;
29  import org.hipparchus.random.JDKRandomGenerator;
30  import org.hipparchus.random.RandomGenerator;
31  import org.junit.jupiter.api.Test;
32  
33  import java.util.ArrayList;
34  import java.util.Arrays;
35  import java.util.List;
36  
37  import static org.hamcrest.MatcherAssert.assertThat;
38  import static org.junit.jupiter.api.Assertions.assertEquals;
39  import static org.junit.jupiter.api.Assertions.assertThrows;
40  import static org.junit.jupiter.api.Assertions.assertTrue;
41  
42  /**
43   * Test cases for FuzzyKMeansClusterer.
44   *
45   */
46  class FuzzyKMeansClustererTest {
47  
48      @Test
49      void testCluster() {
50          final List<DoublePoint> points = new ArrayList<DoublePoint>();
51  
52          // create 10 data points: [1], ... [10]
53          for (int i = 1; i <= 10; i++) {
54              final DoublePoint p = new DoublePoint(new double[] { i } );
55              points.add(p);
56          }
57  
58          final FuzzyKMeansClusterer<DoublePoint> transformer =
59                  new FuzzyKMeansClusterer<DoublePoint>(3, 2.0);
60          final List<CentroidCluster<DoublePoint>> clusters = transformer.cluster(points);
61  
62          // we expect 3 clusters:
63          //   [1], [2], [3]
64          //   [4], [5], [6], [7]
65          //   [8], [9], [10]
66          final List<DoublePoint> clusterOne = Arrays.asList(points.get(0), points.get(1), points.get(2));
67          final List<DoublePoint> clusterTwo = Arrays.asList(points.get(3), points.get(4), points.get(5), points.get(6));
68          final List<DoublePoint> clusterThree = Arrays.asList(points.get(7), points.get(8), points.get(9));
69  
70          boolean cluster1Found = false;
71          boolean cluster2Found = false;
72          boolean cluster3Found = false;
73          assertEquals(3, clusters.size());
74          for (final Cluster<DoublePoint> cluster : clusters) {
75              if (cluster.getPoints().containsAll(clusterOne)) {
76                  cluster1Found = true;
77              }
78              if (cluster.getPoints().containsAll(clusterTwo)) {
79                  cluster2Found = true;
80              }
81              if (cluster.getPoints().containsAll(clusterThree)) {
82                  cluster3Found = true;
83              }
84          }
85          assertTrue(cluster1Found);
86          assertTrue(cluster2Found);
87          assertTrue(cluster3Found);
88      }
89  
90      @Test
91      void testTooSmallFuzzynessFactor() {
92          assertThrows(MathIllegalArgumentException.class, () -> {
93              new FuzzyKMeansClusterer<DoublePoint>(3, 1.0);
94          });
95      }
96  
97      @Test
98      void testNullDataset() {
99          assertThrows(NullArgumentException.class, () -> {
100             final FuzzyKMeansClusterer<DoublePoint> clusterer = new FuzzyKMeansClusterer<DoublePoint>(3, 2.0);
101             clusterer.cluster(null);
102         });
103     }
104 
105     @Test
106     void testGetters() {
107         final DistanceMeasure measure = new CanberraDistance();
108         final RandomGenerator random = new JDKRandomGenerator();
109         final FuzzyKMeansClusterer<DoublePoint> clusterer =
110                 new FuzzyKMeansClusterer<DoublePoint>(3, 2.0, 100, measure, 1e-6, random);
111 
112         assertEquals(3, clusterer.getK());
113         assertEquals(2.0, clusterer.getFuzziness(), 1e-6);
114         assertEquals(100, clusterer.getMaxIterations());
115         assertEquals(1e-6, clusterer.getEpsilon(), 1e-12);
116         assertThat(clusterer.getDistanceMeasure(), CoreMatchers.is(measure));
117         assertThat(clusterer.getRandomGenerator(), CoreMatchers.is(random));
118     }
119 
120     @Test
121     void testSingleCluster() {
122         final List<DoublePoint> points = new ArrayList<DoublePoint>();
123         points.add(new DoublePoint(new double[] { 1, 1 }));
124 
125         final FuzzyKMeansClusterer<DoublePoint> transformer =
126                 new FuzzyKMeansClusterer<DoublePoint>(1, 2.0);
127         final List<CentroidCluster<DoublePoint>> clusters = transformer.cluster(points);
128 
129         assertEquals(1, clusters.size());
130     }
131 
132     @Test
133     void testClusterCenterEqualsPoints() {
134         final List<DoublePoint> points = new ArrayList<DoublePoint>();
135         points.add(new DoublePoint(new double[] { 1, 1 }));
136         points.add(new DoublePoint(new double[] { 1.00001, 1.00001 }));
137         points.add(new DoublePoint(new double[] { 2, 2 }));
138         points.add(new DoublePoint(new double[] { 3, 3 }));
139 
140         final FuzzyKMeansClusterer<DoublePoint> transformer =
141                 new FuzzyKMeansClusterer<DoublePoint>(3, 2.0);
142         final List<CentroidCluster<DoublePoint>> clusters = transformer.cluster(points);
143 
144         assertEquals(3, clusters.size());
145     }
146 
147 }