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  
18  package org.apache.commons.math4.neuralnet.twod.util;
19  
20  import java.util.List;
21  import org.apache.commons.math4.neuralnet.internal.NeuralNetException;
22  import org.apache.commons.math4.neuralnet.DistanceMeasure;
23  import org.apache.commons.math4.neuralnet.MapRanking;
24  import org.apache.commons.math4.neuralnet.Neuron;
25  import org.apache.commons.math4.neuralnet.twod.NeuronSquareMesh2D;
26  
27  /**
28   * Visualization of high-dimensional data projection on a 2D-map.
29   * The method is described in
30   * <blockquote>
31   *  <em>Using Smoothed Data Histograms for Cluster Visualization in Self-Organizing Maps</em>
32   *  <br>
33   *  by Elias Pampalk, Andreas Rauber and Dieter Merkl.
34   * </blockquote>
35   * @since 3.6
36   */
37  public class SmoothedDataHistogram implements MapDataVisualization {
38      /** Smoothing parameter. */
39      private final int smoothingBins;
40      /** Distance. */
41      private final DistanceMeasure distance;
42      /** Normalization factor. */
43      private final double membershipNormalization;
44  
45      /**
46       * @param smoothingBins Number of bins.
47       * @param distance Distance.
48       */
49      public SmoothedDataHistogram(int smoothingBins,
50                                   DistanceMeasure distance) {
51          this.smoothingBins = smoothingBins;
52          this.distance = distance;
53  
54          double sum = 0;
55          for (int i = 0; i < smoothingBins; i++) {
56              sum += smoothingBins - i;
57          }
58  
59          this.membershipNormalization = 1d / sum;
60      }
61  
62      /**
63       * {@inheritDoc}
64       *
65       * @throws IllegalArgumentException if the size of the {@code map} is
66       * smaller than the number of {@link #SmoothedDataHistogram(int,DistanceMeasure)
67       * smoothing bins}.
68       */
69      @Override
70      public double[][] computeImage(NeuronSquareMesh2D map,
71                                     Iterable<double[]> data) {
72          final int nR = map.getNumberOfRows();
73          final int nC = map.getNumberOfColumns();
74  
75          final int mapSize = nR * nC;
76          if (mapSize < smoothingBins) {
77              throw new NeuralNetException(NeuralNetException.TOO_SMALL,
78                                           mapSize, smoothingBins);
79          }
80  
81          final LocationFinder finder = new LocationFinder(map);
82          final MapRanking rank = new MapRanking(map.getNetwork(), distance);
83  
84          // Histogram bins.
85          final double[][] histo = new double[nR][nC];
86  
87          for (final double[] sample : data) {
88              final List<Neuron> sorted = rank.rank(sample);
89              for (int i = 0; i < smoothingBins; i++) {
90                  final LocationFinder.Location loc = finder.getLocation(sorted.get(i));
91                  final int row = loc.getRow();
92                  final int col = loc.getColumn();
93                  histo[row][col] += (smoothingBins - i) * membershipNormalization;
94              }
95          }
96  
97          return histo;
98      }
99  }