/* * Copyright 2004-2010 Information & Software Engineering Group (188/1) * Institute of Software Technology and Interactive Systems * Vienna University of Technology, Austria * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.ifs.tuwien.ac.at/dm/somtoolbox/license.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package at.tuwien.ifs.somtoolbox.layers.quality; import java.util.Arrays; import at.tuwien.ifs.somtoolbox.data.InputData; import at.tuwien.ifs.somtoolbox.layers.GrowingLayer; import at.tuwien.ifs.somtoolbox.layers.Layer; import at.tuwien.ifs.somtoolbox.layers.Unit; import at.tuwien.ifs.somtoolbox.layers.metrics.DistanceMetric; /** * Implematation of Trustworthiness and Neighborhood preservation Quality Measures * * @author Gerd Platzgummer * @version $Id: Trustworthiness_NeighborhoodPreservation.java 3883 2010-11-02 17:13:23Z frank $ */ public class Trustworthiness_NeighborhoodPreservation extends AbstractQualityMeasure { DistanceMetric metric = null; double _K = 0.0; DistanceTag[][] inputDistances = null; DistanceTag[][] outputDistances = null; double[][] twUnitValues = null; double twMapValue = 0.0; double twK = -1; double[][] npUnitValues = null; double npMapValue = 0.0; double npK = -1; public Trustworthiness_NeighborhoodPreservation(Layer layer, InputData data) { super(layer, data); metric = layer.getMetric(); int xSize = layer.getXSize(); int ySize = layer.getYSize(); twUnitValues = new double[xSize][ySize]; npUnitValues = new double[xSize][ySize]; } private void calculateTW() { int samplecount = data.numVectors(); int xSize = layer.getXSize(); int ySize = layer.getYSize(); double[] samplevalues = new double[samplecount]; // errror value per Sample for (int j = 0; j < samplecount; j++) { samplevalues[j] = 0.0; for (int n = 0; n < samplecount && outputDistances[j][n].getMinRank() <= _K; n++) { int tag = outputDistances[j][n].getTag(); for (int m = 0; m < samplecount; m++) { if (inputDistances[j][m].getTag() == tag) { if (inputDistances[j][m].getMinRank() > _K) { samplevalues[j] += inputDistances[j][m].getRank() - _K; } } } } } // compute Map-value twMapValue = 0.0; for (int i = 0; i < samplecount; i++) { twMapValue += samplevalues[i]; } twMapValue = 1 - 2 / (samplecount * _K * (2 * samplecount - 3 * _K - 1)) * twMapValue; // reset Unit- values for (int x = 0; x < xSize; x++) { for (int y = 0; y < ySize; y++) { twUnitValues[x][y] = 0.0; } } // compute Unit-values for (int i = 0; i < samplecount; i++) { Unit bmu = ((GrowingLayer) layer).getWinners(data.getInputDatum(i), 1)[0]; twUnitValues[bmu.getXPos()][bmu.getYPos()] += samplevalues[i]; } twK = _K; // cleanup inputDistances = null; outputDistances = null; } private void calculateNP() { int samplecount = data.numVectors(); int xSize = layer.getXSize(); int ySize = layer.getYSize(); double[] samplevalues = new double[samplecount]; // errror value per Sample for (int j = 0; j < samplecount; j++) { samplevalues[j] = 0.0; for (int n = 0; n < samplecount && inputDistances[j][n].getMinRank() <= _K; n++) { int tag = inputDistances[j][n].getTag(); for (int m = 0; m < samplecount; m++) { if (outputDistances[j][m].getTag() == tag) { if (outputDistances[j][m].getMinRank() > _K) { samplevalues[j] += outputDistances[j][m].getRank() - _K; } } } } } // compute Map-values npMapValue = 0.0; for (int i = 0; i < samplecount; i++) { npMapValue += samplevalues[i]; } npMapValue = 1 - 2 / (samplecount * _K * (2 * samplecount - 3 * _K - 1)) * npMapValue; // reset Unit-values for (int x = 0; x < xSize; x++) { for (int y = 0; y < ySize; y++) { npUnitValues[x][y] = 0.0; } } // compute Unit-values for (int i = 0; i < samplecount; i++) { Unit bmu = ((GrowingLayer) layer).getWinners(data.getInputDatum(i), 1)[0]; npUnitValues[bmu.getXPos()][bmu.getYPos()] += samplevalues[i]; } npK = _K; // cleanup inputDistances = null; outputDistances = null; } private void rankingInputSpace() { // This computes the ranking (order) in the Input Space for each value int samplecount = data.numVectors(); inputDistances = new DistanceTag[samplecount][samplecount]; try { DistanceTagComparator comparator = new DistanceTagComparator(); for (int s = 0; s < samplecount; s++) { double[] svec = data.getInputDatum(s).getVector().toArray(); for (int t = 0; t < samplecount; t++) { if (s == t) { inputDistances[s][t] = new DistanceTag(t, Double.MAX_VALUE); } else { inputDistances[s][t] = new DistanceTag(t, metric.distance(svec, data.getInputDatum(t).getVector().toArray())); } } Arrays.sort(inputDistances[s], comparator); // QuickSort.sort(inputDistances[s], comparator); Rank(inputDistances, s, samplecount); /* * System.out.print(s + ": "); for (int t = 0; t < samplecount; t++) System.out.print(_InputDistances[s][t].getDistance() + " "); * System.out.println(); */ } } catch (Exception ex) { System.out.println("EXCEPTION: " + ex.getMessage()); } } private void rankingOutputSpace() { // This computes the ranking (order) in the Output Space for each value int samplecount = data.numVectors(); outputDistances = new DistanceTag[samplecount][samplecount]; try { DistanceTagComparator comparator = new DistanceTagComparator(); for (int s = 0; s < samplecount; s++) { Unit s_bmu = ((GrowingLayer) layer).getWinners(data.getInputDatum(s), 1)[0]; int s_x = s_bmu.getXPos(); int s_y = s_bmu.getYPos(); for (int t = 0; t < samplecount; t++) { if (s == t) { outputDistances[s][t] = new DistanceTag(t, Double.MAX_VALUE); } else { Unit t_bmu = ((GrowingLayer) layer).getWinners(data.getInputDatum(t), 1)[0]; double distance = Math.sqrt((s_x - t_bmu.getXPos()) * (s_x - t_bmu.getXPos()) + (s_y - t_bmu.getYPos()) * (s_y - t_bmu.getYPos())); outputDistances[s][t] = new DistanceTag(t, distance); } } Arrays.sort(outputDistances[s], comparator); // QuickSort.sort(outputDistances[s], comparator); Rank(outputDistances, s, samplecount); // System.out.print(s + ": "); // for (int t = 0; t < samplecount; t++) // System.out.print(outputDistances[s][t].getRank() + " "); // System.out.println(); } } catch (Exception ex) { System.out.println("EXCEPTION: " + ex.getMessage()); } } private void Rank(DistanceTag[][] distances, int s, int samplecount) { int sittingbull = 0; double sbdistance = distances[s][0].getDistance(); // distances[s][0].setMinRank(1); int countequal = 0; int ranksum = 0; int currank = 0; int minrank = 1; for (int roadrunner = 1; roadrunner < samplecount; roadrunner++) { currank++; countequal++; ranksum += currank; distances[s][roadrunner].setRank(currank); if (distances[s][roadrunner].getDistance() != sbdistance) { while (sittingbull < roadrunner) { distances[s][sittingbull].setRank((double) ranksum / (double) countequal); distances[s][sittingbull].setMinRank(minrank); sittingbull++; } minrank = currank + 1; ranksum = 0; countequal = 0; sbdistance = distances[s][roadrunner].getDistance(); } if (roadrunner == samplecount - 1) // letzter Wert ist immer das aktuelle Sample s { distances[s][roadrunner].setRank(samplecount); distances[s][roadrunner].setMinRank(samplecount); } } } /** *********************************************************************************************************** */ /* * Ausgabe: TRUSTWORTHINESS */ @Override public double getMapQuality(String name) throws QualityMeasureNotFoundException { if (name.startsWith("TW_Map|")) { int k = Integer.valueOf(name.substring(7)).intValue(); // Berechnung wird hier gestartet; Caching: wenn gleiches k schon ein Ergebnis vorhanden, dann dieses // zur�ckgeben, sonst Neuberechnung if (twK != k) { _K = k; rankingInputSpace(); rankingOutputSpace(); calculateTW(); } return twMapValue; } else if (name.startsWith("NP_Map|")) { int k = Integer.valueOf(name.substring(7)).intValue(); // Berechnung wird hier gestartet; Caching: wenn gleiches k schon ein Ergebnis vorhanden, dann dieses // zur�ckgeben, sonst Neuberechnung if (npK != k) { _K = k; rankingInputSpace(); rankingOutputSpace(); calculateNP(); } return npMapValue; } else { throw new QualityMeasureNotFoundException("Quality measure with name " + name + " not found."); } } /* * (non-Javadoc) * * @see at.tuwien.ifs.somtoolbox.layers.quality.QualityMeasure#getUnitQuality(java.lang.String) */ @Override public double[][] getUnitQualities(String name) throws QualityMeasureNotFoundException { if (name.startsWith("TW_Unit|")) { int k = Integer.valueOf(name.substring(8)).intValue(); // Berechnung wird hier gestartet; Caching: wenn gleiches k schon ein Ergebnis vorhanden, dann dieses // zur�ckgeben, sonst Neuberechnung if (twK != k) { _K = k; rankingInputSpace(); rankingOutputSpace(); calculateTW(); } return twUnitValues; } else if (name.startsWith("NP_Unit|")) { int k = Integer.valueOf(name.substring(8)).intValue(); // Berechnung wird hier gestartet; Caching: wenn gleiches k schon ein Ergebnis vorhanden, dann dieses // zur�ckgeben, sonst Neuberechnung if (npK != k) { _K = k; rankingInputSpace(); rankingOutputSpace(); calculateNP(); } return npUnitValues; } else { throw new QualityMeasureNotFoundException("Quality measure with name " + name + " not found."); } } /** *********************************************************************************************************** */ /** *********************************************************************************************************** */ public class DistanceTag { int _Tag; double _Distance = 0.0; double _Rank = 0.0; int _MinRank = 0; public DistanceTag(int tag) { _Tag = tag; } public DistanceTag(int tag, double distance) { _Tag = tag; _Distance = distance; } public int getTag() { return _Tag; } public double getDistance() { return _Distance; } public void setDistance(double d) { _Distance = d; } public double getRank() { return _Rank; } public void setRank(double r) { _Rank = r; } public int getMinRank() { return _MinRank; } public void setMinRank(int m) { _MinRank = m; } } public class DistanceTagComparator implements java.util.Comparator<DistanceTag> { public DistanceTagComparator() { } @Override public int compare(DistanceTag t1, DistanceTag t2) { double diff = t1.getDistance() - t2.getDistance(); if (diff > 0.0) { return 1; } else if (diff < 0.0) { return -1; } else { return 0; } } } }