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 }