Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.LibSVM/1.6.3/LibSVM-1.6.3/Model.cs @ 4545

Last change on this file since 4545 was 4545, checked in by gkronber, 14 years ago

Fixed warnings. #915

File size: 12.9 KB
Line 
1/*
2 * SVM.NET Library
3 * Copyright (C) 2008 Matthew Johnson
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20
21using System;
22using System.IO;
23
24namespace SVM {
25  /// <summary>
26  /// Encapsulates an SVM Model.
27  /// </summary>
28  [Serializable]
29  public class Model {
30    private Parameter _parameter;
31    private int _numberOfClasses;
32    private int _supportVectorCount;
33    private int[] _supportVectorIndizes;
34    private Node[][] _supportVectors;
35    private double[][] _supportVectorCoefficients;
36    private double[] _rho;
37    private double[] _pairwiseProbabilityA;
38    private double[] _pairwiseProbabilityB;
39
40    private int[] _classLabels;
41    private int[] _numberOfSVPerClass;
42
43    internal Model() {
44    }
45
46    /// <summary>
47    /// Parameter object.
48    /// </summary>
49    public Parameter Parameter {
50      get {
51        return _parameter;
52      }
53      set {
54        _parameter = value;
55      }
56    }
57
58    /// <summary>
59    /// Number of classes in the model.
60    /// </summary>
61    public int NumberOfClasses {
62      get {
63        return _numberOfClasses;
64      }
65      set {
66        _numberOfClasses = value;
67      }
68    }
69
70    /// <summary>
71    /// Total number of support vectors.
72    /// </summary>
73    public int SupportVectorCount {
74      get {
75        return _supportVectorCount;
76      }
77      set {
78        _supportVectorCount = value;
79      }
80    }
81
82    /// <summary>
83    /// Indizes of support vectors identified in the training.
84    /// </summary>
85    public int[] SupportVectorIndizes {
86      get {
87        return _supportVectorIndizes;
88      }
89      set {
90        _supportVectorIndizes = value;
91      }
92    }
93
94    /// <summary>
95    /// The support vectors.
96    /// </summary>
97    public Node[][] SupportVectors {
98      get {
99        return _supportVectors;
100      }
101      set {
102        _supportVectors = value;
103      }
104    }
105
106    /// <summary>
107    /// The coefficients for the support vectors.
108    /// </summary>
109    public double[][] SupportVectorCoefficients {
110      get {
111        return _supportVectorCoefficients;
112      }
113      set {
114        _supportVectorCoefficients = value;
115      }
116    }
117
118    /// <summary>
119    /// Rho values.
120    /// </summary>
121    public double[] Rho {
122      get {
123        return _rho;
124      }
125      set {
126        _rho = value;
127      }
128    }
129
130    /// <summary>
131    /// First pairwise probability.
132    /// </summary>
133    public double[] PairwiseProbabilityA {
134      get {
135        return _pairwiseProbabilityA;
136      }
137      set {
138        _pairwiseProbabilityA = value;
139      }
140    }
141
142    /// <summary>
143    /// Second pairwise probability.
144    /// </summary>
145    public double[] PairwiseProbabilityB {
146      get {
147        return _pairwiseProbabilityB;
148      }
149      set {
150        _pairwiseProbabilityB = value;
151      }
152    }
153
154    // for classification only
155
156    /// <summary>
157    /// Class labels.
158    /// </summary>
159    public int[] ClassLabels {
160      get {
161        return _classLabels;
162      }
163      set {
164        _classLabels = value;
165      }
166    }
167
168    /// <summary>
169    /// Number of support vectors per class.
170    /// </summary>
171    public int[] NumberOfSVPerClass {
172      get {
173        return _numberOfSVPerClass;
174      }
175      set {
176        _numberOfSVPerClass = value;
177      }
178    }
179
180    /// <summary>
181    /// Reads a Model from the provided file.
182    /// </summary>
183    /// <param name="filename">The name of the file containing the Model</param>
184    /// <returns>the Model</returns>
185    public static Model Read(string filename) {
186      FileStream input = File.OpenRead(filename);
187      try {
188        return Read(input);
189      }
190      finally {
191        input.Close();
192      }
193    }
194
195    public static Model Read(Stream stream) {
196      return Read(new StreamReader(stream));
197    }
198
199    /// <summary>
200    /// Reads a Model from the provided stream.
201    /// </summary>
202    /// <param name="input">The stream from which to read the Model.</param>
203    /// <returns>the Model</returns>
204    public static Model Read(TextReader input) {
205      TemporaryCulture.Start();
206
207      // read parameters
208
209      Model model = new Model();
210      Parameter param = new Parameter();
211      model.Parameter = param;
212      model.Rho = null;
213      model.PairwiseProbabilityA = null;
214      model.PairwiseProbabilityB = null;
215      model.ClassLabels = null;
216      model.NumberOfSVPerClass = null;
217      model.SupportVectorIndizes = new int[0];
218
219      bool headerFinished = false;
220      while (!headerFinished) {
221        string line = input.ReadLine();
222        string cmd, arg;
223        int splitIndex = line.IndexOf(' ');
224        if (splitIndex >= 0) {
225          cmd = line.Substring(0, splitIndex);
226          arg = line.Substring(splitIndex + 1);
227        } else {
228          cmd = line;
229          arg = "";
230        }
231        // arg = arg.ToLower(); (transforms double NaN or Infinity values to incorrect format [gkronber])
232
233        int i, n;
234        switch (cmd) {
235          case "svm_type":
236            param.SvmType = (SvmType)Enum.Parse(typeof(SvmType), arg.ToUpper());
237            break;
238
239          case "kernel_type":
240            param.KernelType = (KernelType)Enum.Parse(typeof(KernelType), arg.ToUpper());
241            break;
242
243          case "degree":
244            param.Degree = int.Parse(arg);
245            break;
246
247          case "gamma":
248            param.Gamma = double.Parse(arg);
249            break;
250
251          case "coef0":
252            param.Coefficient0 = double.Parse(arg);
253            break;
254
255          case "nr_class":
256            model.NumberOfClasses = int.Parse(arg);
257            break;
258
259          case "total_sv":
260            model.SupportVectorCount = int.Parse(arg);
261            break;
262
263          case "rho":
264            n = model.NumberOfClasses * (model.NumberOfClasses - 1) / 2;
265            model.Rho = new double[n];
266            string[] rhoParts = arg.Split();
267            for (i = 0; i < n; i++)
268              model.Rho[i] = double.Parse(rhoParts[i]);
269            break;
270
271          case "label":
272            n = model.NumberOfClasses;
273            model.ClassLabels = new int[n];
274            string[] labelParts = arg.Split();
275            for (i = 0; i < n; i++)
276              model.ClassLabels[i] = int.Parse(labelParts[i]);
277            break;
278
279          case "probA":
280            n = model.NumberOfClasses * (model.NumberOfClasses - 1) / 2;
281            model.PairwiseProbabilityA = new double[n];
282            string[] probAParts = arg.Split();
283            for (i = 0; i < n; i++)
284              model.PairwiseProbabilityA[i] = double.Parse(probAParts[i]);
285            break;
286
287          case "probB":
288            n = model.NumberOfClasses * (model.NumberOfClasses - 1) / 2;
289            model.PairwiseProbabilityB = new double[n];
290            string[] probBParts = arg.Split();
291            for (i = 0; i < n; i++)
292              model.PairwiseProbabilityB[i] = double.Parse(probBParts[i]);
293            break;
294
295          case "nr_sv":
296            n = model.NumberOfClasses;
297            model.NumberOfSVPerClass = new int[n];
298            string[] nrsvParts = arg.Split();
299            for (i = 0; i < n; i++)
300              model.NumberOfSVPerClass[i] = int.Parse(nrsvParts[i]);
301            break;
302
303          case "SV":
304            headerFinished = true;
305            break;
306
307          default:
308            throw new Exception("Unknown text in model file");
309        }
310      }
311
312      // read sv_coef and SV
313
314      int m = model.NumberOfClasses - 1;
315      int l = model.SupportVectorCount;
316      model.SupportVectorCoefficients = new double[m][];
317      for (int i = 0; i < m; i++) {
318        model.SupportVectorCoefficients[i] = new double[l];
319      }
320      model.SupportVectors = new Node[l][];
321
322      for (int i = 0; i < l; i++) {
323        string[] parts = input.ReadLine().Trim().Split();
324
325        for (int k = 0; k < m; k++)
326          model.SupportVectorCoefficients[k][i] = double.Parse(parts[k]);
327        int n = parts.Length - m;
328        model.SupportVectors[i] = new Node[n];
329        for (int j = 0; j < n; j++) {
330          string[] nodeParts = parts[m + j].Split(':');
331          model.SupportVectors[i][j] = new Node();
332          model.SupportVectors[i][j].Index = int.Parse(nodeParts[0]);
333          model.SupportVectors[i][j].Value = double.Parse(nodeParts[1]);
334        }
335      }
336
337      TemporaryCulture.Stop();
338
339      return model;
340    }
341
342    /// <summary>
343    /// Writes a model to the provided filename.  This will overwrite any previous data in the file.
344    /// </summary>
345    /// <param name="filename">The desired file</param>
346    /// <param name="model">The Model to write</param>
347    public static void Write(string filename, Model model) {
348      FileStream stream = File.Open(filename, FileMode.Create);
349      try {
350        Write(stream, model);
351      }
352      finally {
353        stream.Close();
354      }
355    }
356
357    /// <summary>
358    /// Writes a model to the provided stream.
359    /// </summary>
360    /// <param name="stream">The output stream</param>
361    /// <param name="model">The model to write</param>
362    public static void Write(Stream stream, Model model) {
363      TemporaryCulture.Start();
364
365      StreamWriter output = new StreamWriter(stream);
366
367      Parameter param = model.Parameter;
368
369      output.Write("svm_type " + param.SvmType + Environment.NewLine);
370      output.Write("kernel_type " + param.KernelType + Environment.NewLine);
371
372      if (param.KernelType == KernelType.POLY)
373        output.Write("degree " + param.Degree.ToString("r") + Environment.NewLine);
374
375      if (param.KernelType == KernelType.POLY || param.KernelType == KernelType.RBF || param.KernelType == KernelType.SIGMOID)
376        output.Write("gamma " + param.Gamma.ToString("r") + Environment.NewLine);
377
378      if (param.KernelType == KernelType.POLY || param.KernelType == KernelType.SIGMOID)
379        output.Write("coef0 " + param.Coefficient0.ToString("r") + Environment.NewLine);
380
381      int nr_class = model.NumberOfClasses;
382      int l = model.SupportVectorCount;
383      output.Write("nr_class " + nr_class + Environment.NewLine);
384      output.Write("total_sv " + l + Environment.NewLine);
385
386      {
387        output.Write("rho");
388        for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++)
389          output.Write(" " + model.Rho[i].ToString("r"));
390        output.Write(Environment.NewLine);
391      }
392
393      if (model.ClassLabels != null) {
394        output.Write("label");
395        for (int i = 0; i < nr_class; i++)
396          output.Write(" " + model.ClassLabels[i]);
397        output.Write(Environment.NewLine);
398      }
399
400      if (model.PairwiseProbabilityA != null)
401      // regression has probA only
402            {
403        output.Write("probA");
404        for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++)
405          output.Write(" " + model.PairwiseProbabilityA[i].ToString("r"));
406        output.Write(Environment.NewLine);
407      }
408      if (model.PairwiseProbabilityB != null) {
409        output.Write("probB");
410        for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++)
411          output.Write(" " + model.PairwiseProbabilityB[i].ToString("r"));
412        output.Write(Environment.NewLine);
413      }
414
415      if (model.NumberOfSVPerClass != null) {
416        output.Write("nr_sv");
417        for (int i = 0; i < nr_class; i++)
418          output.Write(" " + model.NumberOfSVPerClass[i].ToString("r"));
419        output.Write(Environment.NewLine);
420      }
421
422      output.WriteLine("SV");
423      double[][] sv_coef = model.SupportVectorCoefficients;
424      Node[][] SV = model.SupportVectors;
425
426      for (int i = 0; i < l; i++) {
427        for (int j = 0; j < nr_class - 1; j++)
428          output.Write(sv_coef[j][i].ToString("r") + " ");
429
430        Node[] p = SV[i];
431        if (p.Length == 0) {
432          output.WriteLine();
433          continue;
434        }
435        if (param.KernelType == KernelType.PRECOMPUTED)
436          output.Write("0:{0}", (int)p[0].Value);
437        else {
438          output.Write("{0}:{1}", p[0].Index, p[0].Value.ToString("r"));
439          for (int j = 1; j < p.Length; j++)
440            output.Write(" {0}:{1}", p[j].Index, p[j].Value.ToString("r"));
441        }
442        output.WriteLine();
443      }
444
445      output.Flush();
446
447      TemporaryCulture.Stop();
448    }
449  }
450}
Note: See TracBrowser for help on using the repository browser.