Free cookie consent management tool by TermsFeed Policy Generator

Changeset 8441 for branches/NCA


Ignore:
Timestamp:
08/08/12 18:20:33 (12 years ago)
Author:
abeham
Message:

#1913: added quality output

Location:
branches/NCA/HeuristicLab.Algorithms.NCA/3.3
Files:
1 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • branches/NCA/HeuristicLab.Algorithms.NCA/3.3/HeuristicLab.Algorithms.NCA-3.3.csproj

    r8437 r8441  
    4343    <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4">
    4444      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
     45      <Private>False</Private>
     46    </Reference>
     47    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
    4548      <Private>False</Private>
    4649    </Reference>
     
    109112    <Compile Include="NCAClassificationSolution.cs" />
    110113    <Compile Include="NCAModel.cs" />
    111     <Compile Include="Auxiliary.cs" />
    112114    <Compile Include="Plugin.cs" />
    113115    <Compile Include="Properties\AssemblyInfo.cs" />
  • branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NCAModel.cs

    r8437 r8441  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using HeuristicLab.Algorithms.DataAnalysis;
    2526using HeuristicLab.Common;
    2627using HeuristicLab.Core;
     
    6364      get { return (double[,])transformedTrainingset.Clone(); }
    6465    }
     66    [Storable]
     67    private Scaling scaling;
    6568
    6669    [StorableConstructor]
     
    7780      if (original.transformedTrainingset != null)
    7881        this.transformedTrainingset = (double[,])original.transformedTrainingset.Clone();
     82      this.scaling = cloner.Clone(original.scaling);
    7983    }
    80     public NCAModel(double[,] transformedTrainingset, double[,] transformationMatrix, int k, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues = null)
     84    public NCAModel(double[,] transformedTrainingset, Scaling scaling, double[,] transformationMatrix, int k, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues = null)
    8185      : base() {
    8286      this.name = ItemName;
    8387      this.description = ItemDescription;
    8488      this.transformedTrainingset = transformedTrainingset;
     89      this.scaling = scaling;
    8590      this.transformationMatrix = transformationMatrix;
    8691      this.k = k;
     
    96101
    97102    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
    98       int k = Math.Min(this.k, transformedTrainingset.GetLength(0));
    99       double[] transformedRow = new double[transformationMatrix.GetLength(1)];
     103      var k = Math.Min(this.k, transformedTrainingset.GetLength(0));
     104      var transformedRow = new double[transformationMatrix.GetLength(1)];
    100105      var kVotes = new SortedList<double, double>(k + 1);
    101106      foreach (var r in rows) {
     
    103108        int j = 0;
    104109        foreach (var v in allowedInputVariables) {
     110          var values = scaling.GetScaledValues(dataset, v, rows);
    105111          double val = dataset.GetDoubleValue(v, r);
    106112          for (int i = 0; i < transformedRow.Length; i++)
  • branches/NCA/HeuristicLab.Algorithms.NCA/3.3/NeighborhoodComponentsAnalysis.cs

    r8437 r8441  
    2020#endregion
    2121
     22using System;
     23using System.Collections.Generic;
    2224using System.Linq;
    2325using HeuristicLab.Algorithms.DataAnalysis;
     26using HeuristicLab.Analysis;
    2427using HeuristicLab.Common;
    2528using HeuristicLab.Core;
     
    3235
    3336namespace HeuristicLab.Algorithms.NCA {
     37  public delegate void Reporter(double quality, double[] coefficients);
    3438  /// <summary>
    3539  /// Neighborhood Components Analysis
     
    9397
    9498      var clonedProblem = (IClassificationProblemData)Problem.ProblemData.Clone();
    95       var classification = new NCAClassificationSolution(clonedProblem, Auxiliary.Train(clonedProblem, k, dimensions, initializer));
     99      var model = Train(clonedProblem, k, dimensions, initializer, ReportQuality);
     100      var classification = new NCAClassificationSolution(clonedProblem, model);
    96101      Results.Add(new Result("ClassificationSolution", "The classification solution.", classification));
    97       // TODO: result that shows the LOO performance
    98     }
     102    }
     103
     104    private void ReportQuality(double func, double[] coefficients) {
     105      var instances = Problem.ProblemData.TrainingIndices.Count();
     106      DataTable qualities;
     107      if (!Results.ContainsKey("Optimization")) {
     108        qualities = new DataTable("Optimization");
     109        qualities.Rows.Add(new DataRow("Quality", string.Empty));
     110        Results.Add(new Result("Optimization", qualities));
     111      } else qualities = (DataTable)Results["Optimization"].Value;
     112      qualities.Rows["Quality"].Values.Add(-func / instances);
     113
     114      if (!Results.ContainsKey("Quality")) {
     115        Results.Add(new Result("Quality", new DoubleValue(-func / instances)));
     116      } else ((DoubleValue)Results["Quality"].Value).Value = -func / instances;
     117    }
     118
     119    public static INCAModel Train(IClassificationProblemData data, int k, int dimensions, INCAInitializer initializer, Reporter reporter = null) {
     120      var instances = data.TrainingIndices.Count();
     121      var attributes = data.AllowedInputVariables.Count();
     122
     123      double[] matrix = initializer.Initialize(data, dimensions);
     124
     125      var info = new OptimizationInfo(data, dimensions, reporter);
     126      alglib.mincgstate state;
     127      alglib.mincgreport rep;
     128
     129      alglib.mincgcreate(matrix, out state);
     130      alglib.mincgsetcond(state, 0, 1e-05, 0, 20);
     131      alglib.mincgsetxrep(state, true);
     132      alglib.mincgoptimize(state, Gradient, Report, info);
     133      alglib.mincgresults(state, out matrix, out rep);
     134
     135      var transformationMatrix = new double[attributes, dimensions];
     136      var counter = 0;
     137      for (var i = 0; i < attributes; i++)
     138        for (var j = 0; j < dimensions; j++)
     139          transformationMatrix[i, j] = matrix[counter++];
     140
     141      var transformedTrainingset = new double[instances, dimensions];
     142      var rowCount = 0;
     143      foreach (var r in data.TrainingIndices) {
     144        var i = 0;
     145        foreach (var v in data.AllowedInputVariables) {
     146          var val = data.Dataset.GetDoubleValue(v, r);
     147          for (var j = 0; j < dimensions; j++)
     148            transformedTrainingset[rowCount, j] += val * transformationMatrix[i, j];
     149          i++;
     150        }
     151        rowCount++;
     152      }
     153
     154      var ds = data.Dataset;
     155      var targetVariable = data.TargetVariable;
     156      return new NCAModel(transformedTrainingset, info.Scaling, transformationMatrix, k, data.TargetVariable, data.AllowedInputVariables,
     157        data.TrainingIndices.Select(i => ds.GetDoubleValue(targetVariable, i)).ToArray());
     158    }
     159
     160    private static void Report(double[] A, double func, object obj) {
     161      var info = (OptimizationInfo)obj;
     162      if (info.Reporter != null) info.Reporter(func, A);
     163    }
     164
     165    private static void Gradient(double[] A, ref double func, double[] grad, object obj) {
     166      var info = (OptimizationInfo)obj;
     167      var data = info.Data;
     168      var classes = info.TargetValues;
     169      var instances = info.Instances;
     170      var attributes = info.Attributes;
     171
     172      var AMatrix = new Matrix(A, A.Length / info.ReduceDimensions, info.ReduceDimensions);
     173
     174      alglib.sparsematrix probabilities;
     175      alglib.sparsecreate(instances, instances, out probabilities);
     176      var transformedDistances = new double[instances];
     177      for (int i = 0; i < instances - 1; i++) {
     178        var iVector = new Matrix(GetRow(data, i), data.GetLength(1));
     179        var denom = 0.0;
     180        for (int k = 0; k < instances; k++) {
     181          if (k == i) continue;
     182          var kVector = new Matrix(GetRow(data, k));
     183          transformedDistances[k] = Math.Exp(-iVector.Multiply(AMatrix).Subtract(kVector.Multiply(AMatrix)).SquaredVectorLength());
     184          denom += transformedDistances[k];
     185        }
     186        if (denom > 1e-05) {
     187          for (int j = i + 1; j < instances; j++) {
     188            if (i == j) continue;
     189            var v = transformedDistances[j] / denom;
     190            alglib.sparseset(probabilities, i, j, v);
     191          }
     192        }
     193      }
     194      alglib.sparseconverttocrs(probabilities); // needed to enumerate in order (top-down and left-right)
     195
     196      int t0 = 0, t1 = 0, r, c;
     197      double val;
     198      var pi = new double[instances];
     199      while (alglib.sparseenumerate(probabilities, ref t0, ref t1, out r, out c, out val)) {
     200        if (classes[r].IsAlmost(classes[c])) {
     201          pi[r] += val;
     202        }
     203      }
     204
     205      var innerSum = new double[attributes, attributes];
     206      while (alglib.sparseenumerate(probabilities, ref t0, ref t1, out r, out c, out val)) {
     207        var vector = new Matrix(GetRow(data, r)).Subtract(new Matrix(GetRow(data, c)));
     208        vector.OuterProduct(vector).Multiply(2.0 * val * pi[r]).AddTo(innerSum);
     209
     210        if (classes[r].IsAlmost(classes[c])) {
     211          vector.OuterProduct(vector).Multiply(-2.0 * val).AddTo(innerSum);
     212        }
     213      }
     214
     215      func = -2.0 * pi.Sum();
     216
     217      r = 0;
     218      var newGrad = AMatrix.Multiply(-2.0).Transpose().Multiply(new Matrix(innerSum)).Transpose();
     219      foreach (var g in newGrad) {
     220        grad[r++] = g;
     221      }
     222    }
     223
     224    #region Helpers
     225    private static IEnumerable<double> GetRow(double[,] data, int row) {
     226      for (int i = 0; i < data.GetLength(1); i++)
     227        yield return data[row, i];
     228    }
     229
     230    private class OptimizationInfo {
     231      public Scaling Scaling { get; private set; }
     232      public double[,] Data { get; private set; }
     233      public double[] TargetValues { get; private set; }
     234      public int ReduceDimensions { get; private set; }
     235      public int Instances { get; private set; }
     236      public int Attributes { get; private set; }
     237      public Reporter Reporter { get; private set; }
     238
     239      public OptimizationInfo(IClassificationProblemData data, int reduceDimensions, Reporter reporter) {
     240        this.Scaling = new Scaling(data.Dataset, data.AllowedInputVariables, data.TrainingIndices);
     241        this.Data = AlglibUtil.PrepareAndScaleInputMatrix(data.Dataset, data.AllowedInputVariables, data.TrainingIndices, Scaling);
     242        this.TargetValues = data.Dataset.GetDoubleValues(data.TargetVariable, data.TrainingIndices).ToArray();
     243        this.ReduceDimensions = reduceDimensions;
     244        this.Instances = data.TrainingIndices.Count();
     245        this.Attributes = data.AllowedInputVariables.Count();
     246        this.Reporter = reporter;
     247      }
     248    }
     249    #endregion
    99250  }
    100251}
Note: See TracChangeset for help on using the changeset viewer.