it.univpm.deit.semedia.musicuri.utils.experimental.LambdaCalculator.java Source code

Java tutorial

Introduction

Here is the source code for it.univpm.deit.semedia.musicuri.utils.experimental.LambdaCalculator.java

Source

/*
 Copyright (c) 2005, Dimitrios Kourtesis
     
 This file is part of MusicURI.
     
 MusicURI is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
     
 MusicURI is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
     
 You should have received a copy of the GNU General Public License
 along with MPEG7AudioEnc; see the file COPYING. If not, write to
 the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 MA  02111-1307 USA
 */

package it.univpm.deit.semedia.musicuri.utils.experimental;

import it.univpm.deit.database.datatypes.AudioLLDmeta;
import it.univpm.deit.database.datatypes.Mp7ACT;
import it.univpm.deit.semedia.musicuri.core.MusicURIDatabase;
import it.univpm.deit.semedia.musicuri.core.MusicURIQuery;
import it.univpm.deit.semedia.musicuri.core.MusicURIReference;
import it.univpm.deit.semedia.musicuri.core.Toolset;
import it.univpm.deit.semedia.musicuri.statistics.PerformanceStatistic;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.math.stat.descriptive.SummaryStatistics;

import com.wcohen.secondstring.JaroWinkler;
import com.wcohen.secondstring.StringWrapper;

/**
 * Utility class used for calculating the optimal lambda for a linear combination of heterogeneous distance metrics
 */
public class LambdaCalculator {
    static String databasePath = "D:/1000ReferenceDB/";
    static String databaseFileName = "MusicURIReferences.db";
    static MusicURIDatabase db = new MusicURIDatabase(databasePath, databaseFileName);

    public static void main(String[] args) throws Exception {

        //*****************************************************************************
        //*************************   F I L E   I N P U T   ***************************
        //*****************************************************************************

        if ((args.length == 1) && (new File(args[0]).exists())) {
            // get the file's canonical path
            File givenHandle = new File(args[0]);
            String queryAudioCanonicalPath = givenHandle.getCanonicalPath();
            System.out.println("Input: " + queryAudioCanonicalPath);

            //PerformanceStatistic tempStat;
            SummaryStatistics lambdaSummary = SummaryStatistics.newInstance();

            if (givenHandle.isDirectory()) {

                File[] list = givenHandle.listFiles();
                if (list.length == 0) {
                    System.out.println("Directory is empty");
                    return;
                } else {
                    ArrayList allStats = new ArrayList();
                    File currentFile;
                    for (int i = 0; i < list.length; i++) {
                        currentFile = list[i];
                        try {
                            if (Toolset.isSupportedAudioFile(currentFile)) {
                                System.out.println("\nCalculating optimal lambda : " + currentFile.getName());
                                lambdaSummary.addValue(getBestLambda(new MusicURIQuery(currentFile)));
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    //               System.out.println("\n\nStatistics for Test Case: " + queryAudioCanonicalPath);
                    //               mergeStatistics(allStats);
                }
            }
            if (givenHandle.isFile()) {
                if (Toolset.isSupportedAudioFile(givenHandle)) {
                    //               tempStat = getBestLambda (new MusicURIQuery(givenHandle));
                    //               if (tempStat!=null)
                    //               {
                    //                  //tempStat.printStatistics();
                    //                  ArrayList allStats = new ArrayList();
                    //                  allStats.add(tempStat);
                    //                  mergeStatistics(allStats);
                    //               }
                    //               else 
                    //                  System.out.println("Error in identification ");
                }
            }

        } //end if
        else {
            System.err.println("LambdaCalculator");
            System.err.println("Usage: java tester.LambdaCalculator {directory}");
        }

    }//end main method

    public static double getBestLambda(MusicURIQuery query) {

        //*****************************************************************************
        //************   Q U E R Y   D A T A   P R E P A R A T I O N   ****************
        //*****************************************************************************

        // get the act object encapsulated in the MusicURIQuery object
        Mp7ACT queryMp7 = query.getAudioCompactType();
        // if its null then there is some problem
        if (queryMp7 == null)
            System.out.println("Problem: queryMp7 is null");
        // read the required data from the AudioCompactType
        AudioLLDmeta queryMean = queryMp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.MEAN);
        AudioLLDmeta queryVariance = queryMp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.VARIANCE);
        // are audioSignatureType data included in the act file?
        if (queryMean == null || queryVariance == null) {
            System.out.println(
                    "Problem: AudioSignatureType is not included in ACT or cannot be extracted from audio file. Aborting.");
        }
        int vectorSize = queryMean.vectorSize; // internal! stay out! read the matrix size instead
        float[][] queryMeanMatrix = queryMean.__rawVectors;
        float[][] queryVarianceMatrix = queryVariance.__rawVectors;
        int QueryVectorDim = vectorSize; // ==number of dimensions, subbands
        String queryLabelling = query.getLabel();
        int queryIdentifier = Toolset.getTestCaseIdentifier(queryLabelling);
        StringWrapper queryWrapper = null;
        JaroWinkler test = new JaroWinkler();
        queryLabelling = Toolset.removeTestCaseIdentifier(queryLabelling);
        queryWrapper = test.prepare(queryLabelling);

        //*****************************************************************************
        //*********   R E F E R E N C E   D A T A   P R E P A R A T I O N   ***********
        //*****************************************************************************

        int RefVectorDim = 0; // number of subbands, dimensions
        double combinedDistance;
        double currentLabelDistance = 0.0;
        double currentSignatureDistance = 0.0;
        double normalizedSignatureDistance = 0.0;
        double confidence = 0.0;
        Mp7ACT mp7;
        String currentMD5;
        MusicURIReference currentReference;
        AudioLLDmeta refMean;
        AudioLLDmeta refVariance;
        float[][] refMeanMatrix;
        float[][] refVarianceMatrix;

        StringWrapper refWrapper = null;
        float editDistance;
        int referenceIdentifier;
        String referenceLabelling;

        double lambdaYeldingSmallestCombinedDistance = 0.0;
        double smallestCombinedDistanceYet = 0.0;

        Set allMusicURIReferenceKeys = db.getSetOfMusicURIReferences();

        //System.out.println("queryId: " + queryIdentifier);

        for (Iterator iter = allMusicURIReferenceKeys.iterator(); iter.hasNext();) {
            currentMD5 = (String) iter.next();
            currentReference = db.getMusicURIReference(currentMD5);
            referenceLabelling = currentReference.getLabel();
            referenceIdentifier = Toolset.getTestCaseIdentifier(referenceLabelling);

            if (referenceIdentifier == queryIdentifier) {
                mp7 = currentReference.getAudioCompactType();
                if (mp7 == null) {
                    System.out.println("Problem: No mpeg7 exists for given uri");
                }
                refMean = mp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.MEAN);
                refVariance = mp7.featureByName(Mp7ACT.FLATNESS, Mp7ACT.VARIANCE);
                if ((refMean == null) || (refVariance == null)) {
                    System.out.println("Skipping: problematic mpeg7 description!!! - " + mp7.getLabel() + ")");
                }
                refMeanMatrix = refMean.__rawVectors;
                refVarianceMatrix = refVariance.__rawVectors;
                RefVectorDim = vectorSize; // number of subbands

                currentSignatureDistance = Toolset.getEuclidianDistance(refMeanMatrix, refVarianceMatrix,
                        queryMeanMatrix, queryVarianceMatrix, QueryVectorDim, false);
                double theoreticalMaximum = (RefVectorDim * Math.sqrt(1)) * queryMeanMatrix.length;
                normalizedSignatureDistance = currentSignatureDistance / theoreticalMaximum; //eg (16 * sqrootof(1) ) * 10 --to scale at 0-1

                String refname = currentReference.getLabel();
                refname = Toolset.removeTestCaseIdentifier(refname);
                refWrapper = test.prepare(refname);
                editDistance = 1 - (float) test.score(queryWrapper, refWrapper);
                currentLabelDistance = editDistance;

                System.out.println("currentLabelDistance: " + currentLabelDistance);
                System.out.println("normalizedSignatureDistance: " + normalizedSignatureDistance);

                //combinedDistance = (0.5 * currentLabelDistance) + (0.5 * normalizedSignatureDistance);
                //smallestCombinedDistanceYet   = (0.5 * currentLabelDistance) + (0.5 * normalizedSignatureDistance);
                for (double lambda = 0.0; lambda < 1.0; lambda += 0.01) {
                    combinedDistance = lambda * currentLabelDistance + (1 - lambda) * normalizedSignatureDistance;
                    if (combinedDistance < smallestCombinedDistanceYet) {
                        smallestCombinedDistanceYet = combinedDistance;
                        lambdaYeldingSmallestCombinedDistance = lambda;
                    }
                }
                System.out.println("smallestCombinedDistanceYet: " + smallestCombinedDistanceYet);
                System.out.println("Best lambda: " + lambdaYeldingSmallestCombinedDistance);
                confidence = 100 - (100 * smallestCombinedDistanceYet);
                System.out.println("Best confidence: " + confidence);
            }
        }
        return lambdaYeldingSmallestCombinedDistance;
    }

    public static void mergeStatistics(ArrayList allStats) {
        PerformanceStatistic tempStat;

        int truePositives = 0;
        int falsePositives = 0;
        int trueNegatives = 0;
        int falseNegatives = 0;

        SummaryStatistics TPBestMatchSummary = SummaryStatistics.newInstance();
        SummaryStatistics TPSecondBestSummary = SummaryStatistics.newInstance();

        SummaryStatistics FPBestMatchSummary = SummaryStatistics.newInstance();

        SummaryStatistics BothTP_FPBestMatchSummary = SummaryStatistics.newInstance();

        SummaryStatistics TNSummary = SummaryStatistics.newInstance();
        SummaryStatistics FNSummary = SummaryStatistics.newInstance();

        SummaryStatistics pruningSpeedSummary = SummaryStatistics.newInstance();
        SummaryStatistics matchingSpeedSummary = SummaryStatistics.newInstance();
        SummaryStatistics totalSpeedSummary = SummaryStatistics.newInstance();

        for (int i = 0; i < allStats.size(); i++) {
            tempStat = (PerformanceStatistic) allStats.get(i);

            if (tempStat.isTruePositive())
                truePositives++;
            if (tempStat.isFalsePositive())
                falsePositives++;
            if (tempStat.isTrueNegative())
                trueNegatives++;
            if (tempStat.isFalseNegative())
                falseNegatives++;

            // accurate results only
            //if (tempStat.isTruePositive() || tempStat.isTrueNegative())

            pruningSpeedSummary.addValue(tempStat.getPruningTime());
            matchingSpeedSummary.addValue(tempStat.getMatchingTime());
            totalSpeedSummary.addValue(tempStat.getPruningTime() + tempStat.getMatchingTime());

            if (tempStat.isTruePositive()) {
                TPBestMatchSummary.addValue(tempStat.getBestMatchDistance());
                TPSecondBestSummary.addValue(tempStat.getSecondBestMatchDistance());
            }

            if (tempStat.isFalsePositive()) {
                FPBestMatchSummary.addValue(tempStat.getBestMatchDistance());
            }

            BothTP_FPBestMatchSummary.addValue(tempStat.getBestMatchDistance());

        }

        System.out.println("---------------------------------------------------------");

        System.out.println("\nTrue Positives      : " + truePositives + "/" + allStats.size());
        System.out.println("False Positives     : " + falsePositives + "/" + allStats.size());
        System.out.println("True Negatives      : " + trueNegatives + "/" + allStats.size());
        System.out.println("False Negatives     : " + falseNegatives + "/" + allStats.size());

        System.out.println("\nTrue Positive Best Match Statistics");
        System.out.println("Distance Min        : " + TPBestMatchSummary.getMin());
        System.out.println("Distance Max        : " + TPBestMatchSummary.getMax());
        System.out.println("Distance Mean       : " + TPBestMatchSummary.getMean());
        System.out.println("Distance Variance   : " + TPBestMatchSummary.getVariance());
        System.out.println("Distance StdDev     : " + TPBestMatchSummary.getStandardDeviation());
        System.out.println("Confidence Mean     : " + (100 - (100 * (TPBestMatchSummary.getMean()))) + " %");

        System.out.println("\nTrue Positive Second Best Statistics");
        System.out.println("Distance Min        : " + TPSecondBestSummary.getMin());
        System.out.println("Distance Max        : " + TPSecondBestSummary.getMax());
        System.out.println("Distance Mean       : " + TPSecondBestSummary.getMean());
        System.out.println("Confidence Mean     : " + (100 - (100 * (TPSecondBestSummary.getMean()))) + " %");

        System.out.println("\nFalse Positive Best Match Statistics");
        System.out.println("Distance Min        : " + FPBestMatchSummary.getMin());
        System.out.println("Distance Max        : " + FPBestMatchSummary.getMax());
        System.out.println("Distance Mean       : " + FPBestMatchSummary.getMean());
        System.out.println("Distance Variance   : " + FPBestMatchSummary.getVariance());
        System.out.println("Distance StdDev     : " + FPBestMatchSummary.getStandardDeviation());
        System.out.println("Confidence Mean     : " + (100 - (100 * (FPBestMatchSummary.getMean()))) + " %");

        System.out.println("\nBest Match Statistics (Regardless being False or True Positive) ");
        System.out.println("Distance Min        : " + BothTP_FPBestMatchSummary.getMin());
        System.out.println("Distance Max        : " + BothTP_FPBestMatchSummary.getMax());
        System.out.println("Distance Mean       : " + BothTP_FPBestMatchSummary.getMean());
        System.out.println("Distance Variance   : " + BothTP_FPBestMatchSummary.getVariance());
        System.out.println("Distance StdDev     : " + BothTP_FPBestMatchSummary.getStandardDeviation());
        System.out.println("Confidence Mean     : " + (100 - (100 * (BothTP_FPBestMatchSummary.getMean()))) + " %");

        System.out.println("\n\nPruning Speed Statistics");
        System.out.println("Speed Min           : " + (pruningSpeedSummary.getMin() / 1000) + " sec");
        System.out.println("Speed Max           : " + (pruningSpeedSummary.getMax() / 1000) + " sec");
        System.out.println("Speed Mean          : " + (pruningSpeedSummary.getMean() / 1000) + " sec");

        System.out.println("\nMatching Speed Statistics");
        System.out.println("Speed Min           : " + (matchingSpeedSummary.getMin() / 1000) + " sec");
        System.out.println("Speed Max           : " + (matchingSpeedSummary.getMax() / 1000) + " sec");
        System.out.println("Speed Mean          : " + (matchingSpeedSummary.getMean() / 1000) + " sec");

        System.out.println("\nOverall Speed Statistics");
        System.out.println("Speed Min           : " + (totalSpeedSummary.getMin() / 1000) + " sec");
        System.out.println("Speed Max           : " + (totalSpeedSummary.getMax() / 1000) + " sec");
        System.out.println("Speed Mean          : " + (totalSpeedSummary.getMean() / 1000) + " sec");

    }

}