Changeset 2416


Ignore:
Timestamp:
10/07/09 12:15:10 (13 years ago)
Author:
gkronber
Message:

Fixed export and import of SVM data structures (using round-trip format for double values). #774

Location:
trunk/sources
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.SupportVectorMachines/3.2/Predictor.cs

    r2415 r2416  
    159159      StreamWriter writer = new StreamWriter(s);
    160160      writer.Write("Targetvariable: "); writer.WriteLine(p.targetVariable);
    161       writer.Write("LowerPredictionLimit: "); writer.WriteLine(p.LowerPredictionLimit.ToString());
    162       writer.Write("UpperPredictionLimit: "); writer.WriteLine(p.UpperPredictionLimit.ToString());
     161      writer.Write("LowerPredictionLimit: "); writer.WriteLine(p.LowerPredictionLimit.ToString("r"));
     162      writer.Write("UpperPredictionLimit: "); writer.WriteLine(p.UpperPredictionLimit.ToString("r"));
    163163      writer.Write("MaxTimeOffset: "); writer.WriteLine(p.MaxTimeOffset.ToString());
    164164      writer.Write("MinTimeOffset: "); writer.WriteLine(p.MinTimeOffset.ToString());
  • trunk/sources/LibSVM/Model.cs

    r2415 r2416  
    256256                    arg = "";
    257257                }
    258                 arg = arg.ToLower();
     258                // arg = arg.ToLower(); (transforms double NaN or Infinity values to incorrect format [gkronber])
    259259
    260260                int i,n;
     
    401401            Parameter param = model.Parameter;
    402402
    403             output.Write("svm_type " + param.SvmType + "\n");
    404             output.Write("kernel_type " + param.KernelType + "\n");
     403            output.Write("svm_type " + param.SvmType + Environment.NewLine);
     404            output.Write("kernel_type " + param.KernelType + Environment.NewLine);
    405405
    406406            if (param.KernelType == KernelType.POLY)
    407                 output.Write("degree " + param.Degree + "\n");
     407                output.Write("degree " + param.Degree.ToString("r") + Environment.NewLine);
    408408
    409409            if (param.KernelType == KernelType.POLY || param.KernelType == KernelType.RBF || param.KernelType == KernelType.SIGMOID)
    410                 output.Write("gamma " + param.Gamma + "\n");
     410              output.Write("gamma " + param.Gamma.ToString("r") + Environment.NewLine);
    411411
    412412            if (param.KernelType == KernelType.POLY || param.KernelType == KernelType.SIGMOID)
    413                 output.Write("coef0 " + param.Coefficient0 + "\n");
     413              output.Write("coef0 " + param.Coefficient0.ToString("r") + Environment.NewLine);
    414414
    415415            int nr_class = model.NumberOfClasses;
    416416            int l = model.SupportVectorCount;
    417             output.Write("nr_class " + nr_class + "\n");
    418             output.Write("total_sv " + l + "\n");
     417            output.Write("nr_class " + nr_class + Environment.NewLine);
     418            output.Write("total_sv " + l + Environment.NewLine);
    419419
    420420            {
    421421                output.Write("rho");
    422422                for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++)
    423                     output.Write(" " + model.Rho[i]);
    424                 output.Write("\n");
     423                  output.Write(" " + model.Rho[i].ToString("r"));
     424                output.Write(Environment.NewLine);
    425425            }
    426426
     
    430430                for (int i = 0; i < nr_class; i++)
    431431                    output.Write(" " + model.ClassLabels[i]);
    432                 output.Write("\n");
     432                output.Write(Environment.NewLine);
    433433            }
    434434
     
    438438                output.Write("probA");
    439439                for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++)
    440                     output.Write(" " + model.PairwiseProbabilityA[i]);
    441                 output.Write("\n");
     440                  output.Write(" " + model.PairwiseProbabilityA[i].ToString("r"));
     441                output.Write(Environment.NewLine);
    442442            }
    443443            if (model.PairwiseProbabilityB != null)
     
    445445                output.Write("probB");
    446446                for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++)
    447                     output.Write(" " + model.PairwiseProbabilityB[i]);
    448                 output.Write("\n");
     447                  output.Write(" " + model.PairwiseProbabilityB[i].ToString("r"));
     448                output.Write(Environment.NewLine);
    449449            }
    450450
     
    453453                output.Write("nr_sv");
    454454                for (int i = 0; i < nr_class; i++)
    455                     output.Write(" " + model.NumberOfSVPerClass[i]);
    456                 output.Write("\n");
     455                  output.Write(" " + model.NumberOfSVPerClass[i].ToString("r"));
     456                output.Write(Environment.NewLine);
    457457            }
    458458
     
    464464            {
    465465                for (int j = 0; j < nr_class - 1; j++)
    466                     output.Write(sv_coef[j][i] + " ");
     466                  output.Write(sv_coef[j][i].ToString("r") + " ");
    467467
    468468                Node[] p = SV[i];
     
    476476                else
    477477                {
    478                     output.Write("{0}:{1}", p[0].Index, p[0].Value);
     478                  output.Write("{0}:{1}", p[0].Index, p[0].Value.ToString("r"));
    479479                    for (int j = 1; j < p.Length; j++)
    480                         output.Write(" {0}:{1}", p[j].Index, p[j].Value);
     480                      output.Write(" {0}:{1}", p[j].Index, p[j].Value.ToString("r"));
    481481                }
    482482                output.WriteLine();
  • trunk/sources/LibSVM/RangeTransform.cs

    r2415 r2416  
    2323using System.Globalization;
    2424
    25 namespace SVM
    26 {
    27     /// <summary>
    28     /// Class which encapsulates a range transformation.
    29     /// </summary>
    30     public class RangeTransform : IRangeTransform
    31     {
    32         /// <summary>
    33         /// Default lower bound for scaling (-1).
    34         /// </summary>
    35         public const int DEFAULT_LOWER_BOUND = -1;
    36         /// <summary>
    37         /// Default upper bound for scaling (1).
    38         /// </summary>
    39         public const int DEFAULT_UPPER_BOUND = 1;
    40 
    41         /// <summary>
    42         /// Determines the Range transform for the provided problem.  Uses the default lower and upper bounds.
    43         /// </summary>
    44         /// <param name="prob">The Problem to analyze</param>
    45         /// <returns>The Range transform for the problem</returns>
    46         public static RangeTransform Compute(Problem prob)
    47         {
    48             return Compute(prob, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND);
     25namespace SVM {
     26  /// <summary>
     27  /// Class which encapsulates a range transformation.
     28  /// </summary>
     29  public class RangeTransform : IRangeTransform {
     30    /// <summary>
     31    /// Default lower bound for scaling (-1).
     32    /// </summary>
     33    public const int DEFAULT_LOWER_BOUND = -1;
     34    /// <summary>
     35    /// Default upper bound for scaling (1).
     36    /// </summary>
     37    public const int DEFAULT_UPPER_BOUND = 1;
     38
     39    /// <summary>
     40    /// Determines the Range transform for the provided problem.  Uses the default lower and upper bounds.
     41    /// </summary>
     42    /// <param name="prob">The Problem to analyze</param>
     43    /// <returns>The Range transform for the problem</returns>
     44    public static RangeTransform Compute(Problem prob) {
     45      return Compute(prob, DEFAULT_LOWER_BOUND, DEFAULT_UPPER_BOUND);
     46    }
     47    /// <summary>
     48    /// Determines the Range transform for the provided problem.
     49    /// </summary>
     50    /// <param name="prob">The Problem to analyze</param>
     51    /// <param name="lowerBound">The lower bound for scaling</param>
     52    /// <param name="upperBound">The upper bound for scaling</param>
     53    /// <returns>The Range transform for the problem</returns>
     54    public static RangeTransform Compute(Problem prob, double lowerBound, double upperBound) {
     55      double[] minVals = new double[prob.MaxIndex];
     56      double[] maxVals = new double[prob.MaxIndex];
     57      for (int i = 0; i < prob.MaxIndex; i++) {
     58        minVals[i] = double.MaxValue;
     59        maxVals[i] = double.MinValue;
     60      }
     61      for (int i = 0; i < prob.Count; i++) {
     62        for (int j = 0; j < prob.X[i].Length; j++) {
     63          int index = prob.X[i][j].Index - 1;
     64          double value = prob.X[i][j].Value;
     65          minVals[index] = Math.Min(minVals[index], value);
     66          maxVals[index] = Math.Max(maxVals[index], value);
    4967        }
    50         /// <summary>
    51         /// Determines the Range transform for the provided problem.
    52         /// </summary>
    53         /// <param name="prob">The Problem to analyze</param>
    54         /// <param name="lowerBound">The lower bound for scaling</param>
    55         /// <param name="upperBound">The upper bound for scaling</param>
    56         /// <returns>The Range transform for the problem</returns>
    57         public static RangeTransform Compute(Problem prob, double lowerBound, double upperBound)
    58         {
    59             double[] minVals = new double[prob.MaxIndex];
    60             double[] maxVals = new double[prob.MaxIndex];
    61             for (int i = 0; i < prob.MaxIndex; i++)
    62             {
    63                 minVals[i] = double.MaxValue;
    64                 maxVals[i] = double.MinValue;
    65             }
    66             for (int i = 0; i < prob.Count; i++)
    67             {
    68                 for (int j = 0; j < prob.X[i].Length; j++)
    69                 {
    70                     int index = prob.X[i][j].Index - 1;
    71                     double value = prob.X[i][j].Value;
    72                     minVals[index] = Math.Min(minVals[index], value);
    73                     maxVals[index] = Math.Max(maxVals[index], value);
    74                 }
    75             }
    76             for (int i = 0; i < prob.MaxIndex; i++)
    77             {
    78                 if (minVals[i] == double.MaxValue || maxVals[i] == double.MinValue)
    79                 {
    80                     minVals[i] = 0;
    81                     maxVals[i] = 0;
    82                 }
    83             }
    84             return new RangeTransform(minVals, maxVals, lowerBound, upperBound);
     68      }
     69      for (int i = 0; i < prob.MaxIndex; i++) {
     70        if (minVals[i] == double.MaxValue || maxVals[i] == double.MinValue) {
     71          minVals[i] = 0;
     72          maxVals[i] = 0;
    8573        }
    86 
    87         private double[] _inputStart;
    88         private double[] _inputScale;
    89         private double _outputStart;
    90         private double _outputScale;
    91         private int _length;
    92 
    93         /// <summary>
    94         /// Constructor.
    95         /// </summary>
    96         /// <param name="minValues">The minimum values in each dimension.</param>
    97         /// <param name="maxValues">The maximum values in each dimension.</param>
    98         /// <param name="lowerBound">The desired lower bound for all dimensions.</param>
    99         /// <param name="upperBound">The desired upper bound for all dimensions.</param>
    100         public RangeTransform(double[] minValues, double[] maxValues, double lowerBound, double upperBound)
    101         {
    102             _length = minValues.Length;
    103             if(maxValues.Length != _length)
    104                 throw new Exception("Number of max and min values must be equal.");
    105             _inputStart = new double[_length];
    106             _inputScale = new double[_length];
    107             for (int i = 0; i < _length; i++)
    108             {
    109                 _inputStart[i] = minValues[i];
    110                 _inputScale[i] = maxValues[i] - minValues[i];
    111             }
    112             _outputStart = lowerBound;
    113             _outputScale = upperBound - lowerBound;
    114         }
    115         private RangeTransform(double[] inputStart, double[] inputScale, double outputStart, double outputScale, int length)
    116         {
    117             _inputStart = inputStart;
    118             _inputScale = inputScale;
    119             _outputStart = outputStart;
    120             _outputScale = outputScale;
    121             _length = length;
    122         }
    123         /// <summary>
    124         /// Transforms the input array based upon the values provided.
    125         /// </summary>
    126         /// <param name="input">The input array</param>
    127         /// <returns>A scaled array</returns>
    128         public Node[] Transform(Node[] input)
    129         {
    130             Node[] output = new Node[input.Length];
    131             for (int i = 0; i < output.Length; i++)
    132             {
    133                 int index = input[i].Index;
    134                 double value = input[i].Value;
    135                 output[i] = new Node(index, Transform(value, index));
    136             }
    137             return output;
    138         }
    139 
    140         /// <summary>
    141         /// Transforms this an input value using the scaling transform for the provided dimension.
    142         /// </summary>
    143         /// <param name="input">The input value to transform</param>
    144         /// <param name="index">The dimension whose scaling transform should be used</param>
    145         /// <returns>The scaled value</returns>
    146         public double Transform(double input, int index)
    147         {
    148             index--;
    149             double tmp = input - _inputStart[index];
    150             if (_inputScale[index] == 0)
    151                 return 0;
    152             tmp /= _inputScale[index];
    153             tmp *= _outputScale;
    154             return tmp + _outputStart;
    155         }
    156         /// <summary>
    157         /// Writes this Range transform to a stream.
    158         /// </summary>
    159         /// <param name="stream">The stream to write to</param>
    160         /// <param name="r">The range to write</param>
    161         public static void Write(Stream stream, RangeTransform r)
    162         {
    163             TemporaryCulture.Start();
    164 
    165             StreamWriter output = new StreamWriter(stream);
    166             output.WriteLine(r._length);
    167             output.Write(r._inputStart[0]);
    168             for(int i=1; i<r._inputStart.Length; i++)
    169                 output.Write(" " + r._inputStart[i]);
    170             output.WriteLine();
    171             output.Write(r._inputScale[0]);
    172             for (int i = 1; i < r._inputScale.Length; i++)
    173                 output.Write(" " + r._inputScale[i]);
    174             output.WriteLine();
    175             output.WriteLine("{0} {1}", r._outputStart, r._outputScale);
    176             output.Flush();
    177 
    178             TemporaryCulture.Stop();
    179         }
    180 
    181         /// <summary>
    182         /// Writes this Range transform to a file.    This will overwrite any previous data in the file.
    183         /// </summary>
    184         /// <param name="outputFile">The file to write to</param>
    185         /// <param name="r">The Range to write</param>
    186         public static void Write(string outputFile, RangeTransform r)
    187         {
    188             FileStream s = File.Open(outputFile, FileMode.Create);
    189             try
    190             {
    191                 Write(s, r);
    192             }
    193             finally
    194             {
    195                 s.Close();
    196             }
    197         }
    198 
    199         /// <summary>
    200         /// Reads a Range transform from a file.
    201         /// </summary>
    202         /// <param name="inputFile">The file to read from</param>
    203         /// <returns>The Range transform</returns>
    204         public static RangeTransform Read(string inputFile)
    205         {
    206             FileStream s = File.OpenRead(inputFile);
    207             try
    208             {
    209                 return Read(s);
    210             }
    211             finally
    212             {
    213                 s.Close();
    214             }
    215         }
    216 
    217         /// <summary>
    218         /// Reads a Range transform from a stream.
    219         /// </summary>
    220         /// <param name="stream">The stream to read from</param>
    221         /// <returns>The Range transform</returns>
    222         public static RangeTransform Read(Stream stream)
    223         {
    224             TemporaryCulture.Start();
    225 
    226             StreamReader input = new StreamReader(stream);
    227             int length = int.Parse(input.ReadLine());
    228             double[] inputStart = new double[length];
    229             double[] inputScale = new double[length];
    230             string[] parts = input.ReadLine().Split();
    231             for (int i = 0; i < length; i++)
    232                 inputStart[i] = double.Parse(parts[i]);
    233             parts = input.ReadLine().Split();
    234             for (int i = 0; i < length; i++)
    235                 inputScale[i] = double.Parse(parts[i]);
    236             parts = input.ReadLine().Split();
    237             double outputStart = double.Parse(parts[0]);
    238             double outputScale = double.Parse(parts[1]);
    239 
    240             TemporaryCulture.Stop();
    241 
    242             return new RangeTransform(inputStart, inputScale, outputStart, outputScale, length);
    243         }
    244     }
     74      }
     75      return new RangeTransform(minVals, maxVals, lowerBound, upperBound);
     76    }
     77
     78    private double[] _inputStart;
     79    private double[] _inputScale;
     80    private double _outputStart;
     81    private double _outputScale;
     82    private int _length;
     83
     84    /// <summary>
     85    /// Constructor.
     86    /// </summary>
     87    /// <param name="minValues">The minimum values in each dimension.</param>
     88    /// <param name="maxValues">The maximum values in each dimension.</param>
     89    /// <param name="lowerBound">The desired lower bound for all dimensions.</param>
     90    /// <param name="upperBound">The desired upper bound for all dimensions.</param>
     91    public RangeTransform(double[] minValues, double[] maxValues, double lowerBound, double upperBound) {
     92      _length = minValues.Length;
     93      if (maxValues.Length != _length)
     94        throw new Exception("Number of max and min values must be equal.");
     95      _inputStart = new double[_length];
     96      _inputScale = new double[_length];
     97      for (int i = 0; i < _length; i++) {
     98        _inputStart[i] = minValues[i];
     99        _inputScale[i] = maxValues[i] - minValues[i];
     100      }
     101      _outputStart = lowerBound;
     102      _outputScale = upperBound - lowerBound;
     103    }
     104    private RangeTransform(double[] inputStart, double[] inputScale, double outputStart, double outputScale, int length) {
     105      _inputStart = inputStart;
     106      _inputScale = inputScale;
     107      _outputStart = outputStart;
     108      _outputScale = outputScale;
     109      _length = length;
     110    }
     111    /// <summary>
     112    /// Transforms the input array based upon the values provided.
     113    /// </summary>
     114    /// <param name="input">The input array</param>
     115    /// <returns>A scaled array</returns>
     116    public Node[] Transform(Node[] input) {
     117      Node[] output = new Node[input.Length];
     118      for (int i = 0; i < output.Length; i++) {
     119        int index = input[i].Index;
     120        double value = input[i].Value;
     121        output[i] = new Node(index, Transform(value, index));
     122      }
     123      return output;
     124    }
     125
     126    /// <summary>
     127    /// Transforms this an input value using the scaling transform for the provided dimension.
     128    /// </summary>
     129    /// <param name="input">The input value to transform</param>
     130    /// <param name="index">The dimension whose scaling transform should be used</param>
     131    /// <returns>The scaled value</returns>
     132    public double Transform(double input, int index) {
     133      index--;
     134      double tmp = input - _inputStart[index];
     135      if (_inputScale[index] == 0)
     136        return 0;
     137      tmp /= _inputScale[index];
     138      tmp *= _outputScale;
     139      return tmp + _outputStart;
     140    }
     141    /// <summary>
     142    /// Writes this Range transform to a stream.
     143    /// </summary>
     144    /// <param name="stream">The stream to write to</param>
     145    /// <param name="r">The range to write</param>
     146    public static void Write(Stream stream, RangeTransform r) {
     147      TemporaryCulture.Start();
     148
     149      StreamWriter output = new StreamWriter(stream);
     150      output.WriteLine(r._length);
     151      output.Write(r._inputStart[0].ToString("r"));
     152      for (int i = 1; i < r._inputStart.Length; i++)
     153        output.Write(" " + r._inputStart[i].ToString("r"));
     154      output.WriteLine();
     155      output.Write(r._inputScale[0].ToString("r"));
     156      for (int i = 1; i < r._inputScale.Length; i++)
     157        output.Write(" " + r._inputScale[i].ToString("r"));
     158      output.WriteLine();
     159      output.WriteLine("{0} {1}", r._outputStart.ToString("r"), r._outputScale.ToString("r"));
     160      output.Flush();
     161
     162      TemporaryCulture.Stop();
     163    }
     164
     165    /// <summary>
     166    /// Writes this Range transform to a file.    This will overwrite any previous data in the file.
     167    /// </summary>
     168    /// <param name="outputFile">The file to write to</param>
     169    /// <param name="r">The Range to write</param>
     170    public static void Write(string outputFile, RangeTransform r) {
     171      FileStream s = File.Open(outputFile, FileMode.Create);
     172      try {
     173        Write(s, r);
     174      }
     175      finally {
     176        s.Close();
     177      }
     178    }
     179
     180    /// <summary>
     181    /// Reads a Range transform from a file.
     182    /// </summary>
     183    /// <param name="inputFile">The file to read from</param>
     184    /// <returns>The Range transform</returns>
     185    public static RangeTransform Read(string inputFile) {
     186      FileStream s = File.OpenRead(inputFile);
     187      try {
     188        return Read(s);
     189      }
     190      finally {
     191        s.Close();
     192      }
     193    }
     194
     195    /// <summary>
     196    /// Reads a Range transform from a stream.
     197    /// </summary>
     198    /// <param name="stream">The stream to read from</param>
     199    /// <returns>The Range transform</returns>
     200    public static RangeTransform Read(Stream stream) {
     201      TemporaryCulture.Start();
     202
     203      StreamReader input = new StreamReader(stream);
     204      int length = int.Parse(input.ReadLine());
     205      double[] inputStart = new double[length];
     206      double[] inputScale = new double[length];
     207      string[] parts = input.ReadLine().Split();
     208      for (int i = 0; i < length; i++)
     209        inputStart[i] = double.Parse(parts[i]);
     210      parts = input.ReadLine().Split();
     211      for (int i = 0; i < length; i++)
     212        inputScale[i] = double.Parse(parts[i]);
     213      parts = input.ReadLine().Split();
     214      double outputStart = double.Parse(parts[0]);
     215      double outputScale = double.Parse(parts[1]);
     216
     217      TemporaryCulture.Stop();
     218
     219      return new RangeTransform(inputStart, inputScale, outputStart, outputScale, length);
     220    }
     221  }
    245222}
Note: See TracChangeset for help on using the changeset viewer.